SQl服务器TVF CLR函数返回行索引?

时间:2012-08-04 17:51:09

标签: c# .net sql-server sql-server-2008 sqlclr

我有这个简单的C#代码,Sql Server使用它来返回TVF

[SqlFunction(FillRowMethodName = "FillRow3")]
public static IEnumerable GetCsv(string csv)
{
    string[] arr = csv.Split(',');
    return arr;
}

public static void FillRow3(Object obj, out int val, out int index)
{
    val = int.Parse((string)obj) ;
    index =  ??? <----------?
}

但是 - 我想返回一个包含2列的表:( val,index)

如何根据arr

返回每一行及其索引(从0开始)

obj是来自arr。)

p.s - 我可以在MyItem方法中创建一个GetCsv数组,其中包含[value,index] 然后 - FillRow3方法可以看到obj row(val + index)。 但我不想这样做。

2 个答案:

答案 0 :(得分:0)

我解决了。

我想生产一个柜台:

public static void FillRow3(Object obj, out int val, out int index)
{

}

但它必须是静态的。

所以我尝试创建一个静态字段:

public static   int g = 0;
public static void FillRow2(Object obj, out int val, out int index)
{
    val = (int.Parse((string) obj)*2);
    int h = g;
   index = h++;
}

然后SQL喊道:

  

CREATE ASSEMBLY失败,因为在安全程序集“MyDll2”中键入“Class1”   有一个静态字段'g'。安全程序集中静态字段的属性   必须在Visual C#,Visual Basic中的ReadOnly或者   init用Visual C ++和中间语言。

但如果我有一个readonly int - 我将无法更改它。

所以我为int创建了一个包装器引用对象。

引用不会变色, Int 将......:)

所以我的最终解决方案是:

  public class MyCounter
    {
        public  int cnt;
    }  


    public static readonly MyCounter mc = new MyCounter();

    public static void FillRow2(Object obj, out int val, out int index)
    {
        val = (int.Parse((string) obj)*2);

        index = mc.cnt++;
    }

和..................

enter image description here

答案 1 :(得分:0)

它应该是这样的:

[SqlFunction(FillRowMethodName = "FillRow3")]
public static IEnumerable GetCsv(string csv)
{
    string[] arr = csv.Split(',');
    return arr.Select((x, i) => Tuple.Create(x, i));
}

public static void FillRow3(Object obj, out string val, out int index)
{
    var input = (Tuple<string, int>)obj;
    val = input.Item1;
    index = input.Item2;
}

请注意,不需要静态变量。如果您认为SQL Server内部的静态不是问题,请研究此问题。