• C# source code, for those that prefer to compile for themselves:

    using System;

    using System.Collections;

    using System.Collections.Generic;

    using System.Data.SqlTypes;

    using Microsoft.SqlServer.Server;

    public partial class UserDefinedFunctions

    {

    [SqlFunction

    (

    DataAccess = DataAccessKind.None,

    SystemDataAccess = SystemDataAccessKind.None,

    FillRowMethodName = "FillRow",

    IsDeterministic = true,

    IsPrecise = true

    )

    ]

    public static IEnumerable GetCombinations

    (

    [SqlFacet(MaxSize = 256, IsNullable = false, IsFixedLength = false)] SqlString input

    )

    {

    // Check for a NULL parameter

    if (input.IsNull)

    {

    return new string[0];

    }

    // Create a list of string arrays to hold each member of each group

    List<string[]> groupList = new List<string[]>();

    // Split the input into groups on the semicolon

    string[] groups = input.Value.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

    // For each group, add each item of the group to a string array in the list

    for (int i = 0; i < groups.Length; i++)

    {

    groupList.Add(groups.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));

    }

    // Do the recursive magic (returns a List of strings, each of which is a combination)

    return recursiveAppend(0, groupList);

    }

    // Called by SQL Server for each member of the List of strings

    public static void FillRow(object obj, out SqlString combination)

    {

    // Remove the final comma and return the combination string as a new row

    string output = (string)obj;

    output = output.Substring(0, output.Length - 1);

    combination = new SqlString(output);

    }

    // The magic

    static List<string> recursiveAppend(int level, List<string[]> inputList)

    {

    List<string> toReturn = new List<string>();

    if (level == inputList.Count)

    {

    toReturn.Add(String.Empty);

    return toReturn;

    }

    foreach (string item in inputList[level])

    {

    foreach (string partialList in recursiveAppend(level + 1, inputList))

    {

    if (!partialList.Contains(item + ','))

    {

    toReturn.Add(item + "," + partialList);

    }

    }

    }

    return toReturn;

    }

    }