MSTSQL:SP是否可以返回out参数和结果集

时间:2019-02-08 19:13:18

标签: tsql sql-server-2008 stored-procedures resultset output-parameter

我想知道让TSQL存储过程像这样返回结果集和输出参数是否可行。

create procedure uspReadMyXmlInformation(@myXmlDoc xml, @myProductNum varchar(18) output) as
    begin
        set nocount on;

        declare @myXmlContent table(MyOrderId varchar(12) not null
                                   ,CreatedAt datetime not null)

        insert into @myXmlContent
            select x.c.value('MyOrderID[1]', 'varchar(12)')
                    x.c.value('CreatedAt[1]', 'datetime')
                from @myXmlDoc.nodes('MyRootNodeName/MyChildNodeName') x(c)

        set @myProductNum='MyProductNum'

        select *
            from @myXmlContent

        return;
    end

因此,这里发生的是,当我删除输出参数时,我可以获取结果集,或者我获取输出参数并且结果集始终为空(0=count(*))。

无论如何,我都可以使用相同的存储过程来获得两者吗?还是最好将它们分开?

我认为这在Oracle的这篇文章中是可行的。我希望在SQL Server中实现相同的目标,尽管仅限于2008版本。

Oracle stored procedure: return both result set and out parameters

使用相同的SP进行操作,我喜欢的是结果集和输出参数都代表我从XML文档读取的信息。因此,SP的名称以某种方式说明了一切。

编辑

有人认为这可能是以下项目的重复项目:

Possible to return an out parameter with a DataReader

我不认为答案是与DataReader的行为有关,而不是与TSQL如何实现有关。

事实是,我从输出参数中获得了值,但我根本没有从结果集中得到它,它总是返回null。

所以,我在一个仅SQL Server的项目上,我需要它。否则,如果无法及时实现,我会将其分成两部分。

使用方法如下:

declare @xmlInformationData table(MyOrderId varchar(12) not null
                                  ,CreatedAt datetime not null)
insert into @xmlInformationData
    execute uspReadMyXmlInformation @myXmlDoc, @myProductNum output

while 0<(select count(*) from @xmlInformationData)
    begin
        -- This will never be executed because I have no rows in @xmlInformationData
        -- And yet, before the loop, I have my out param value!
    end

1 个答案:

答案 0 :(得分:1)

以下是使用输出参数和结果集的简单演示。尝试运行几次,结果应该会有所不同。

<input type="text" placeholder="line&#13;&#10;line2">
<textarea placeholder="line1&#13;&#10;line2"></textarea>

在旁边:我为提到create procedure Arthur( @TheAnswer as Int Output ) as begin -- Set the value of the output parameter. set @TheAnswer = 42; -- Generate a single row most of the time. select GetDate() as NextVogonPoetryReading where DatePart( millisecond, GetDate() ) < 750; end; go 1 -- Declare the variables for the test. declare @HHGTTU as Table ( HHGTTUId Int Identity, NextVogonPoetryReading DateTime ); declare @SixTimesNine as Int; -- Execute the SP once so that the while loop might. insert into @HHGTTU ( NextVogonPoetryReading ) execute Arthur @TheAnswer = @SixTimesNine Output; -- See what happens. while exists ( select Pi() from @HHGTTU ) begin -- See where we are at. select @SixTimesNine as SixTimesNine, Max( HHGTTUId ) as MaxHHGTTUId, Max( NextVogonPoetryReading ) as MaxNextVogonPoetryReading from @HHGTTU; -- Reset. delete from @HHGTTU; set @SixTimesNine = 54; select @SixTimesNine as SixTimesNineAfterReset; waitfor delay '00:00:00.100'; -- Execute the SP again. insert into @HHGTTU ( NextVogonPoetryReading ) execute Arthur @TheAnswer = @SixTimesNine Output; end; 而对您的生活造成的创伤表示歉意。我只是在尝试传递我在C#应用程序中的经验,而又不搞清楚与您正在使用的数据库建立什么样的连接,可能涉及哪些驱动程序……。