我正在使用 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

我需要能够单独迭代两个结果集。

编辑:只是为了澄清问题,我想测试存储过程。我有一组从 VB.NET 客户端使用的存储过程,它返回多个结果集。这些不会更改为表值函数,事实上我根本无法更改程序。改变程序不是一个选择。

过程返回的结果集的数据类型或列数不同。

有帮助吗?

解决方案

简短的回答是:你做不到。

从 T-SQL 中,如果不按照其他人的建议更改存储过程,就无法访​​问嵌套存储过程调用的多个结果。

为了完整起见,如果过程返回单个结果,您可以使用以下语法将其插入临时表或表变量中:

INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...

您可以对返回多个结果的过程使用相同的语法,但它只会处理第一个结果,其余结果将被丢弃。

其他提示

通过创建一个包含内部数据集的 SQL2005 CLR 存储过程,我可以轻松地做到这一点。

您会看到,默认情况下,新的 SqlDataAdapter 会将多结果集存储过程填充到多表数据集中。这些表中的数据可以依次插入到您要编写的调用存储过程中的#Temp 表中。 数据集.ReadXmlSchema 将向您显示每个结果集的架构。

步骤1:开始写入将从多结果集存储过程中读取数据的存储过程

A。根据架构为每个结果集创建一个单独的表。

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));

b.此时,您可能需要声明一个游标来重复调用您将在此处创建的 CLR 存储过程:

第2步:制作 CLR 存储过程

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub usp_SF_ReadSFIntoTables()

    End Sub
End Class

A。连接使用 New SqlConnection("context connection=true").

b.设置命令对象 (cmd) 以包含多结果集存储过程。

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.迭代每个表并将每一行插入相应的临时表(您在上面的第一步中创建的)。

最后说明:根据我的经验,您可能希望在表之间强制执行一些关系,以便您知道每个记录来自哪个批次。

这就是全部了!

~ 肖恩,西雅图附近

您也可以做一个拼凑的事情。将可选参数 N int 添加到您的存储过程中。默认 N 值为 -1。如果 N 的值为 -1,则执行每一项选择。否则,进行第 N 次选择,并且仅进行第 N 次选择。

例如,

if (N = -1 or N = 0)
    select ...

if (N = -1 or N = 1)
    select ...

未指定 N 的存储过程的调用者将获得包含多个表的结果集。如果您需要从另一个存储过程中提取一个或多个这些表,只需调用您的存储过程并指定 N 值即可。您必须为要提取的每个表调用一次存储过程。如果您需要结果集中的多个表,则效率较低,但它在纯 TSQL 中确实有效。

请注意,对于 INSERT INTO ... 有一个额外的、未记录的限制。执行声明:它不能嵌套。也就是说, EXEC 调用的存储过程(或它依次调用的任何存储过程)本身不能执行 INSERT INTO ...执行。似乎每个进程都有一个累积结果的暂存器,如果它们是嵌套的,那么当调用者打开它时,你会收到错误,然后被调用者尝试再次打开它。

Matthieu,您需要为每种“类型”的结果维护单独的临时表。此外,如果您多次执行相同的操作,则可能需要向该结果添加一列,以指示它是由哪个调用产生的。

遗憾的是这是不可能做到的。当然,问题是没有 SQL 语法允许这样做。当然,它发生在“幕后”,但您无法在 TSQL 中获得这些其他结果,只能通过 ODBC 或其他方式从应用程序中获得。

就像大多数事情一样,有一种解决方法。诀窍是使用 TSQL 中的 ole 自动化创建一个 ADODB 对象,该对象依次打开每个结果集并将结果写入您指定的表(或对结果集执行任何您想要的操作)。如果你喜欢痛苦,也可以在 DMO 中进行。

有两种方法可以轻松做到这一点。将结果粘贴到临时表中,然后从存储过程中引用临时表。另一种选择是将结果放入用作 OUTPUT 变量的 XML 变量中。

然而,这两种选择都各有利弊。对于临时表,您需要将代码添加到创建调用过程的脚本中,以在修改过程之前创建临时表。另外,您应该在过程结束时清理临时表。

对于 XML,它可能会占用大量内存并且速度很慢。

您可以将它们选择到临时表中或编写表值函数来返回结果集。正在询问如何迭代结果集?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top