Sql server 2008 SQL Server 2008中CLR过程的表值参数-可能吗?

Sql server 2008 SQL Server 2008中CLR过程的表值参数-可能吗?,sql-server-2008,stored-procedures,clr,table-valued-parameters,Sql Server 2008,Stored Procedures,Clr,Table Valued Parameters,,讨论CLR存储过程,并有一个标题为“表值参数”的部分,其中讨论了它们的优势。那太好了-我很想在CLR程序中使用TVPs,但不幸的是,这似乎是宇宙中唯一提到这种可能性的地方,本节没有描述语法是什么(本段末尾链接的更多信息也没有) 当然,我可以很容易地找到关于如何从T-SQL过程中使用TVP的描述,或者通常如何执行CLR过程的描述。但是写一个需要TVP的CLR进程?没有什么。这是非常不寻常的,因为将多行数据传递到存储的进程是一个常见的问题 这让我想知道,该页面上出现的部分是否是一个错误。有人请告诉

,讨论CLR存储过程,并有一个标题为“表值参数”的部分,其中讨论了它们的优势。那太好了-我很想在CLR程序中使用TVPs,但不幸的是,这似乎是宇宙中唯一提到这种可能性的地方,本节没有描述语法是什么(本段末尾链接的更多信息也没有)

当然,我可以很容易地找到关于如何从T-SQL过程中使用TVP的描述,或者通常如何执行CLR过程的描述。但是写一个需要TVP的CLR进程?没有什么。这是非常不寻常的,因为将多行数据传递到存储的进程是一个常见的问题

这让我想知道,该页面上出现的部分是否是一个错误。有人请告诉我不是这样,并告诉我更多的信息/例子

[编辑]

我正要把这篇文章发到微软的一个论坛上,突然发现了。看来这件事办不到。

我能找到一个解决办法。然而,这些都是用于将表值参数传递给TSQL过程的,所以这没有什么用处

然而,我得出的结论是这是不可能的。首先,CLR和SQL类型之间存在差异。对于表类型,没有映射,因此以下操作不起作用,例如:

[SqlProcedure]
public static void StoredProcedure(DataTable tvp, out int sum)
{
    return 42;
}
然后

CREATE TYPE MyTableType AS TABLE 
(
    Id INT NOT NULL PRIMARY KEY,
    [Count] INT NOT NULL
)
GO
CREATE ASSEMBLY ClrTest FROM '<somePath>'
GO
CREATE PROCEDURE ClrTest
AS EXTERNAL NAME ClrTest.StoredProcedures.StoredProcedure
GO
将类型MyTableType创建为表
(
Id INT非空主键,
[Count]INT不为空
)
去
从“”创建程序集CLR测试
去
创建过程ClrTest
作为外部名称ClrTest.StoredProcedures.StoredProcedure
去
无论您尝试何种类型(
DataTable
DbDataReader
IEnumerable
),
CREATE PROCEDURE
调用都会不断生成错误6552:CREATE PROCEDURE for“ClrTest”失败,因为参数“@tvp”的T-SQL和CLR类型不匹配

其次,您链接到的页面上的文档说明:用户定义的表类型不能作为表值参数传递给SQL Server进程中执行的托管存储过程或函数,也不能从中返回

我似乎在任何地方都找不到如何在C#中创建用户定义的表类型,但这似乎也是一条死胡同


也许你可以在微软论坛的某个地方问你的问题。奇怪的是,他们在CLR存储过程页面上提到了表值参数,但从未解释如何实现这一点。如果您找到了任何解决方案,我想知道。

虽然目前似乎不可能将表直接传递给CLR过程,但我得到了一个结果,尽管通过以下方式得到了次优结果:

  • 定义TSQL表值UDT FooTable
  • 定义一个TSQL函数,该函数将FooTable作为参数,并使用FOR XML EXPLICIT返回XML
  • 将结果XML传递给CLR函数/过程,而不是表本身

不太理想,但它更接近了。

解决方案是将表格数据序列化为Json格式的字符串,然后将该字符串传递到CLR进程中。在clr过程或函数中,您可以将json解析为IEnumerable、list或Tablear对象。然后,您可以像处理任何其他类型的表格数据一样处理这些数据


我已经编写了一些实用程序,能够将任何sql表序列化为Json格式的字符串。我很乐意与提供其电子邮件地址的任何人分享。Phil Factor编写了一个很好的T-SQL Json解析器,他称之为parseJson。我已将他的解决方案改编为clr,该clr执行速度更快。两者都接受Json格式的字符串,并从该字符串生成一个表。我还为T-SQL和CLR使用了各种Json实用程序,能够序列化、解析、插入、删除和更新存储在SQL列中的Json格式字符串。

在调用过程和读取CLR过程中的表之前,可以使用创建和填充的临时表。

如果使用C#(与缺少自定义迭代器的VB不同)您可以编写ADO.NET代码来调用ExecuteOnQuery(),并使用SqlDbType.Structured参数(即TVP)运行存储过程

作为TVP值传递的集合必须实现
IEnumerable
。每次执行此IEnumerable的收益返回,一个SqlDataRecord“行”通过管道传输到“table”参数


详细信息请参见。

我刚刚详细阅读了您的整个问题。CLR存储过程,而不是TSQL存储过程。对于这种情况,很抱歉,我会尝试找到更好的解决方案……哈哈,np-谢谢。我将保留我的投票,直到您回来;-)谢谢rw。文档中的这一段(最近添加的)看起来确实不正确。我会在某个MS论坛上跟进。这会给目前接受的答案增加什么?这应该是评论,而不是回答。请检查这一点以及如何给出正确答案。这个答案非常好,因为它涉及到在存储过程之间传递数据的一种与其他答案中提到的完全不同的方法。请参阅Erland Sommerskog在上发表的关于每种特定方法的优缺点的经典、权威性博客文章,其中他讨论了每种方法的特定用例。临时表解决方案有其独特的用例;当我遇到这个线程时,它就是我想要解决的问题的解决方案。