我有一个像这样的 SQL CLR 函数:
public partial class UserDefinedFunctions {
[Microsoft.SqlServer.Server.SqlFunction(TableDefinition = "number int", FillRowMethodName = "FillRow")]
public static IEnumerable MyClrFunction(object obj) {
// read obj array input and then
var result = new ArrayList();
result.Add((SqlInt32)1);
result.Add((SqlInt32)2);
result.Add((SqlInt32)3);
return result;
}
public static void FillRow(object obj, out SqlInt32 number) {
number = (SqlInt32)obj;
}
}
我想这样使用它:
DECLARE @x arrayOfInt
INSERT INTO @x VALUES (10)
INSERT INTO @x VALUES (20)
INSERT INTO @x VALUES (30)
SELECT * FROM dbo.MyClrFunction(@x)
整数数组 is:
CREATE TYPE [dbo].[arrayOfInt] AS TABLE(
[item] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[item] ASC
) WITH (IGNORE_DUP_KEY = OFF)
)
我的问题是整数数组与 sql_variant 不兼容。是否可以编写具有数组(表)参数的 CLR 表值函数?
SQLCLR 不支持表值参数 (TVP):
-
创建程序
[ 类型架构名称。 ] 数据类型
...
CLR 过程指南:
-
创建函数
[ 类型架构名称。 ] 参数数据类型
...对于 CLR 函数,允许所有数据类型,包括 CLR 用户定义类型,除了text, ntext, image,用户定义的表类型和时间戳数据类型。
但是,您确实有多种选择:
如果数组是数字和/或字符串的简单列表,您始终可以发送分隔值列表(通过 SqlString / NVARCHAR(MAX))并使用 String.Split() 对其进行解包。
如果数组更复杂(即多个字段),那么您可以将数据包装在 XML 中并将其作为 SqlXml 传递。
或者,如果您有一个复杂的数组,那么您可以创建一个 CLR UDT 作为您喜欢的任何结构,并将其传递到函数中。不过,这需要付出更多努力。
-
另外,请记住,表值参数只是表(表变量),而不是内存中的数据结构,例如数组和集合。 TVP 的主要优点和用例是在从应用程序向 SQL Server 发送数据时降低复杂性并提高性能。如果您已经在 SQL Server 中创建一个表变量,然后想要将其传递给 CLR 存储过程(或者可能是函数),那么您需要做的就是以稍微不同的方式查看问题,然后您就可以可以完成同样的基本事情:
- 使用临时表代替表变量
- 将临时表名称传递给 CLR 存储过程
- 使用进程内连接(即连接字符串=
"Context Connection = true;"
) 因为它可以访问本地临时对象
- 您可以通过使用传入的表名在执行的任何 SQL 中使用临时表
- 您可以通过执行简单的操作将该表中的数据获取到 .NET 上下文中
SELECT *
在传入的表名上,然后通过读取每一行SqlCommand.ExecuteReader()
and SqlDataReader.Read()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)