代码之家  ›  专栏  ›  技术社区  ›  Will Marcouiller

MSTSQL:SP能否同时返回out参数和结果集

  •  0
  • Will Marcouiller  · 技术社区  · 6 年前

    我想知道让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(*) )。

    我是否可以使用相同的存储过程获取这两个存储过程,或者最好将它们拆分?

    我认为这在甲骨文的这篇文章中是可行的。我希望在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 回复  |  直到 6 年前
        1
  •  1
  •   HABO    6 年前

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

    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;
    

    旁白:我为我提到 DataReader 。我只是想传递我在C#应用程序中的经验,而没有深入了解您使用的数据库的连接类型、可能涉及的驱动程序等。