【问题标题】:What is the most efficient way to count the results of a stored procedure, from another stored procedure?从另一个存储过程计算存储过程结果的最有效方法是什么?
【发布时间】:2010-09-09 22:34:33
【问题描述】:

在一个存储过程中,我需要获取另一个存储过程的结果计数。具体来说,我需要知道它是否返回任何结果或一个空集。

我可以创建一个临时表/表变量,在其中执行存储过程,然后对该数据运行选择计数。但我真的不关心数据本身,我需要的只是计数(或数据的存在/不存在)。我想知道是否有更有效的方法来获取这些信息。

我不想只是复制其他存储过程的内容并将其重写为选择计数。存储过程更改太频繁以至于无法使用。

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

    嗯,根据存储过程的工作方式,@@ROWCOUNT 返回 SP 将执行的任何操作(包括更新)的结果数: http://msdn.microsoft.com/en-us/library/ms187316.aspx

    只有当您在 sp 中做的最后一件事是将行返回给客户端时,这才有效...否则您将获得其他语句的结果。有意义吗?

    【讨论】:

      【解决方案2】:

      @@ROWCOUNT

      【讨论】:

        【解决方案3】:

        使用输出参数

        【讨论】:

          【解决方案4】:

          我认为您可以返回行数(使用 RETURN)或使用 out 参数来获取值。

          【讨论】:

          • 其实我认为这不是一个好主意。因为返回值是 int 类型,你不能用它传递 bigint。因此,如果您有一个包含数百万条记录且具有 bigint 主键的表,您的解决方案可能会面临风险,而且它根本不起作用。另外我应该说sql中返回值的定义是只报告一个操作的结果,而不是别的(就像C#中的枚举它应该总是有一些特定的值)。可能最好使用输出参数来做这样的事情,或者正如我们的朋友已经说过的那样,使用@@RowCount 变量。干杯
          【解决方案5】:

          如果你可以将其他过程重写为一个返回结果集的简单函数,你可以简单地从中选择count(*)。

          【讨论】:

            【解决方案6】:

            似乎是其他人更改了另一个存储过程,无论对此类过程进行何种更改,您都需要一些东西来有效地检查结果。

            创建一个 tempt 表并将该过程的结果插入其中。

            然后您可以对结果执行行计数。如果我正确理解您的问题,这不是最有效但最可靠的解决方案。

            片段:

            DECLARE @res AS TABLE (
                [EmpID] [int] NOT NULL,
                [EmpName] [varchar](30) NULL,
                [MgrID] [int] NULL
            )
            
            INSERT @res 
            EXEC dbo.ProcFoo
            
            SELECT COUNT(*) FROM @res
            

            【讨论】:

              【解决方案7】:

              鉴于您实际上并不需要知道计数,只需要知道您的 sproc 是否有数据,我建议您这样做:

              CREATE PROCEDURE subProcedure @param1, @param2, @Param3 tinyint OUTPUT
              AS
              BEGIN
                IF EXISTS(SELECT * FROM table1 WHERE we have something to work with)
                 BEGIN
                  -- The body of your sproc
                  SET @Param3 = 1
                 END
                ELSE
                 SET @Param3 = 0
              END
              

              现在您可以执行存储过程并检查@Param3 的值:

              DECLARE @ThereWasData tinyint
              exec subProcedure 'foo', 'bar', @ThereWasData OUTPUT
              IF @ThereWasData = 1 
                PRINT 'subProcedure had data'
              ELSE
                PRINT 'subProcedure had NO data'
              

              【讨论】:

              • -1 因为“TinyInt”数据类型不是数据库中记录计数的好选择,尤其是在处理一些大数据时。很明显,您不知道数据库将来会有多大,因为您的软件一直在运行,直到那时为止。一个完整的解决方案应该始终有效,而不是例外。所以我认为你应该改变数据类型。干杯。
              【解决方案8】:

              我认为你应该这样做:

              Create  Procedure   [dbo].[GetResult]   (
                  @RowCount   BigInt  =   -1  Output
              )   As  Begin
              
                  /*
                      You can do whatever else you should do here.
                  */
              
                  Select  @RowCount   =   Count_Big(*)
                      From    dbo.SomeLargeOrSmallTable
                      Where   SomeColumn  =   'Somefilters'
                      ;
              
                  /*
                      You can do whatever else you should do here.
                  */
              
                  --Reporting how your procedure has done the statements. It's just a sample to show you how to work with the procedures. There are many ways for doing these things.
                  Return  @@Error;
              
              End;
              

              写完后可以得到如下输出结果:

              Declare @RowCount   BigInt
              ,   @Result     Int
              ;
              
              Execute @Result =   [dbo].[GetResult]   @RowCount   Out
              
              Select  @RowCount
              ,   @Result
              ;
              

              干杯

              【讨论】:

                【解决方案9】:
                  create proc test
                    as
                    begin
                     select top 10 * from customers
                    end
                    go
                
                
                    create proc test2 (@n int out)
                    as
                    begin
                    exec test
                    set @n = @@rowcount
                    --print @n
                    end
                    go
                
                    declare @n1 int =0
                
                    exec test2 @n1 out
                    print @n1
                    --output result: 10
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-03-03
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-09-17
                  • 1970-01-01
                  • 2013-07-06
                  相关资源
                  最近更新 更多