【问题标题】:Counting the number of rows returned by stored procedure计算存储过程返回的行数
【发布时间】:2013-01-06 14:56:40
【问题描述】:

如何计算存储过程以最快方式返回的行数。存储过程返回大约 100K 到 1M 条记录的行。

【问题讨论】:

  • 最快的方法是创建一个新的过程来执行计数,在过程执行后使用@@ROWCOUNT 之类的东西会给你返回的行,但如果你只对如果您只需要计数,则无需进行检索和呈现输出列的工作。

标签: sql sql-server-2008


【解决方案1】:

选择@@rowcount:

SELECT @@ROWCOUNT;

执行存储过程后。

【讨论】:

  • 如果我有多个选择查询,那么它将返回最后一条语句的行数。
  • @VeeKayBee - 这就是它的作用,它返回Returns the number of rows affected by the last statement。见technet.microsoft.com/en-us/library/ms187316.aspx
  • 这并不总是有效。例如 - 存储过程在退出之前将临时表作为最后一件事删除并不少见。在这种情况下,您总是会在 rowcount 中得到 0
  • @neesh 谢谢你的解释。我无法弄清楚为什么我每次都得到零,这解释了它。 +1 给你。
  • 如果select语句在EXISTS的where子句中包含条件,会返回哪个语句的行数?
【解决方案2】:

你可以定义输出变量:

create procedure x
    (@p1 int output)
as
    select @p1 = count(*) 
    from Table

【讨论】:

    【解决方案3】:

    答案是使用@@ROWCOUNT仍然有效,但我不建议在EXEC之后直接运行existing answer。

    SELECT 语句并不总是最后一个语句是存储过程,或者您可能有多个 SELECT 语句:

    场景:

    CREATE PROCEDURE p
    AS
    BEGIN
      CREATE TABLE #t(i INT);
      INSERT INTO #t(i) VALUES (1),(2);
      SELECT i FROM #t;
      DROP TABLE IF EXISTS t;
    END
    
    EXEC p;
    -- i
    -- 1
    -- 2
    
    SELECT @@ROWCOUNT;
    -- 0 instead of 2
    

    db<>fiddle demo


    一种方法是使用输出参数(与存储过程结果集一样多):

    CREATE PROCEDURE p(@cnt INT OUT)
    AS
    BEGIN
      CREATE TABLE #t(i INT);
      INSERT INTO #t(i) VALUES (1),(2);
      SELECT i FROM #t;
      SET @cnt = @@ROWCOUNT;  -- immediately after SELECT
      DROP TABLE IF EXISTS t;
    END
    
    DECLARE @i INT;
    EXEC p2 @cnt = @i OUT;
    SELECT @i;
    -- 2
    

    db<>fiddle demo

    【讨论】:

      【解决方案4】:
      Create procedure procedurename
      AS
      Begin
      
          Select * from Table --if you want where condition write here
      
      End
      
      Exec Procedurename
      
      Select @@rowcount
      

      【讨论】:

      • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post。
      • @Hatem,我想你可能会误解什么是答案。这当然是在尝试回答——它可能不正确(我没有检查过),但它肯定会尝试回答这个问题。
      • 按原样进行查询无济于事,更多解释会有所帮助。
      • @OGHaza:这个答案是关于过滤查询的。与计算(现有)查询的行数无关。这是两个非常不同的事情。其次,纯代码答案存在严重的质量问题。解释是必要的。
      • @Flater 1) NAA 标志不适用于低质量答案。这是 4 年前的事了,在过去的 4 年里,NAA 的旗帜还没有被同意。 2)我同意这是一个糟糕的答案,它复制了前一年的答案,同时引入了拼写错误(Select @@roucount)。我很可能是从没有相关背景的审核队列中查看的。
      【解决方案5】:

      我有一个类似的任务,但我不能更改 SP 来获取计数。因此:

      sp_configure 'show advanced options', 1;  
      reconfigure;
      go
      
      sp_configure 'ad hoc distributed queries', 1;  
      reconfigure;  
      go
      
      select count(*) from 
          openrowset('SQLOLEDB','Data Source=localhost;Trusted_Connection=yes;
          Integrated Security=SSPI','exec DBNAME..SPName')
      

      【讨论】:

      • 潜在限制:“SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问,因为该组件作为该服务器安全配置的一部分被关闭。”跨度>
      【解决方案6】:

      获得相同结果的另一种方法

      CREATE PROCEDURE NOMBRE_PROCEDIMIENTO
         as
      BEGIN
         if EXISTS (SELECT * from NOMBRE_TABLA WHERE CONDITIONS HERE)
           BEGIN
             SELECT @@ROWCOUNT
           END
      END
      

      【讨论】:

        【解决方案7】:

        到目前为止,唯一对我有用的是:

        一个。暂时修改存储过程以将结果数据集转储到表中。如果更改存储过程不是一个选项,则将 Alter Procedure 替换为 Declare 并删除结尾,如果不是可选的,则提供参数值并作为查询将数据集转储到表中执行。

        b.编写表格并使用 SSMS 删除它。

        c。使用脚本在查询中创建一个虚拟表,并使用 Insert into 和 exec 存储过程来填充它。

        d。统计记录。

        【讨论】:

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