从存储过程Transact-SQL SQL Server中访问结果集
我正在使用SQL Server 2005,我想知道如何从transact-sql中访问不同的结果集。 下面的存储过程返回两个结果集,如何从另一个存储过程访问它们?
CREATE PROCEDURE getOrder (@orderId as numeric) AS BEGIN select order_address, order_number from order_table where order_id = @orderId select item, number_of_items, cost from order_line where order_id = @orderId END
我需要能够遍历两个结果集单独。
编辑:只是为了澄清这个问题,我想testing存储过程。 我有一套从VB.NET客户端使用的存储过程,它返回多个结果集。 这些都不会变成表值函数,实际上我根本不能改变程序。 改变程序不是一个选项。
过程返回的结果集不是相同的数据types或列数。
简短的回答是:你做不到。
从T-SQL中无法访问嵌套存储过程调用的多个结果,而无需像其他人所build议的那样更改存储过程。
要完成,如果过程返回单个结果,则可以使用以下语法将其插入临时表或表variables中:
INSERT INTO #Table (...columns...) EXEC MySproc ...parameters...
对于返回多个结果的过程,可以使用相同的语法,但是只会处理第一个结果,其余部分将被丢弃。
我很容易通过创build包含内部数据集的SQL2005 CLR存储过程来完成此操作。
你会发现,一个新的SqlDataAdapter会默认将一个多结果集的sproc填充到一个多表数据集中。 这些表中的数据可以反过来插入到您希望写入的调用存储中的#Temp表中。 dataset.ReadXmlSchema将显示每个结果集的模式。
步骤1:开始写入将从多结果集sproc读取数据的sproc
一个。 根据模式为每个结果集创build一个单独的表。
CREATE PROCEDURE [dbo].[usp_SF_Read] AS SET NOCOUNT ON; CREATE TABLE #Table01 (Document_ID VARCHAR(100) , Document_status_definition_uid INT , Document_status_Code VARCHAR(100) , Attachment_count INT , PRIMARY KEY (Document_ID));
湾 此时您可能需要声明一个游标来重复调用您将在此处创build的CLR存储:
第2步:制作CLR Sproc
Partial Public Class StoredProcedures <Microsoft.SqlServer.Server.SqlProcedure()> _ Public Shared Sub usp_SF_ReadSFIntoTables() End Sub End Class
一个。 使用New SqlConnection("context connection=true")
。
湾 设置一个命令对象(cmd)来包含多重结果集sproc。
C。 获取所有数据使用以下内容:
Dim dataset As DataSet = New DataSet With New SqlDataAdapter(cmd) .Fill(dataset) ' get all the data. End With 'you can use dataset.ReadXmlSchema at this point...
d。 遍历每个表并将每一行插入到适当的临时表(您在上面的第一步中创build的)。
最后一点:根据我的经验,您可能希望强制执行表格之间的某些关系,以便知道每个logging来自哪个批次。
这就是它的全部!
〜西雅图附近的Shaun
有一个你可以做的一个kludge。 将一个可选参数N int添加到您的存储区。 默认N的值为-1。 如果N的值是-1,那么做你的每一个select。 否则,请执行第N次select,然后仅select第N次。
例如,
if (N = -1 or N = 0) select ... if (N = -1 or N = 1) select ...
没有指定N的sproc的调用者将得到一个包含多个表的结果集。 如果您需要从另一个sproc中提取这些表中的一个或多个,只需调用指定N的值的sproc即可。您必须为每个要提取的表调用一次sproc。 如果您需要结果集中的多个表,则效率低下,但它在纯TSQL中起作用。
请注意,对于INSERT INTO … EXEC语句还有一个额外的未logging的限制:它不能嵌套。 也就是说,EXEC调用的存储过程(或者它调用的任何进程)本身不能执行INSERT INTO … EXEC。 看起来,每个进程都有一个单独的暂存器来累积结果,如果它们嵌套,当调用者将其打开时,将会收到一个错误,然后被调用者尝试再次打开它。
Matthieu,你需要为每个“types”的结果维护单独的临时表。 另外,如果您多次执行相同的操作,则可能需要向该结果添加一个额外的列,以指示由此导致的调用。
可悲的是,这是不可能的。 问题当然是没有SQL语法来允许它。 它当然是在'引擎盖下'发生的,但是你不能在TSQL中得到这些其他的结果,只能通过ODBC或其他方法来获取这些结果。
和大多数事情一样,它有一个方法。 诀窍是在TSQL中使用ole自动化来创build一个ADODB对象,该对象依次打开每个结果集并将结果写入到您提名的表(或者对结果集执行任何您想要的操作)。 如果你喜欢痛苦,你也可以在DMO中做。
有两种方法可以轻松做到这一点。 将结果粘贴到临时表中,然后从您的存储过程引用临时表。 另一种方法是将结果放入一个用作OUTPUTvariables的XMLvariables中。
但是,这两种select都有利有弊。 使用临时表,您需要向创build调用过程的脚本添加代码,以在修改过程之前创build临时表。 此外,您应该在过程结束时清理临时表。
使用XML,它可能是内存密集和缓慢的。
您可以将它们select到临时表中或写入表值函数以返回结果集。 正在问如何遍历结果集?