SQL CLR中的标识列拆分UDF

时间:2010-03-16 01:55:28

标签: sql-server clr split user-defined-functions

如何返回带有标准SQL CLR Split UDF的标识列,例如下面的代码将返回一个表,其中字符串值由分隔符拆分,我还需要以某种方式返回标识列。

<SqlFunction(FillRowMethodName:="FillRow", TableDefinition:="value nvarchar(4000)")> _
Public Shared Function GetStrings(ByVal str As SqlString, ByVal delimiter As SqlString) As IEnumerable
    If (str.IsNull OrElse delimiter.IsNull) Then
        Return Nothing
    Else
        Return str.Value.Split(CChar(delimiter))
    End If
End Function
Public Shared Sub FillRow(ByVal row As Object, ByRef str As String)
    str = CType(row, String).Trim()
End Sub

1 个答案:

答案 0 :(得分:3)

就CLR UDF而言,“identity”没有任何特定含义,因为您自己生成所有行。你想要的只是一个柜台。

简单的答案是在现场生成索引,然后发送IEnumerable复合值。所以像这样:

[SqlFunction(FillRowMethodName = "FillMyRow",
    TableDefinition = "ID int, Value nvarchar(4000)")]
public static IEnumerable GetStrings(SqlString str, SqlString delimiter)
{
    if (str.IsNull || delimiter.IsNull)
    {
        return null;
    }

    string[] values = str.Value.Split(delimiter.Value.ToCharArray());
    StringPair[] results = new StringPair[values.Length];
    for (int i = 0; i < values.Length; i++)
    {
        results[i] = new StringPair(i + 1, values[i]);
    }
    return results;
}

public static void FillMyRow(object row, ref int id, ref string value)
{
    StringPair pair = (StringPair)row;
    id = pair.ID;
    value = pair.Value;
}

public class StringPair
{
    public StringPair(int id, string value)
    {
        this.id = id;
        this.value = value;
    }

    public int ID { get; private set; }
    public string Value { get; private set; }
}

与身份栏完全相同;你只是递增一个ID的计数器,从数字1开始。

您可能还想考虑使用ROW_NUMBER在SQL本身中生成代理ID,因此可能根本不需要这样做。这本来是我的选择,但是如果你需要在CLR输出中做到这一点,上面的代码应该可以解决问题。