【问题标题】:How To Turn off Stored Procedure Output如何关闭存储过程输出
【发布时间】:2011-05-19 04:34:07
【问题描述】:

SQL Server 2008 R2。通过 SS Management Studio 中的游标控制循环运行存储过程。 (以下)。在 9,000 次循环中的 3,000 次后,我收到内存不足错误。我相信这仅与 SS Mgmt Studio 有关。那么如何关闭调用例程(如下)和调用的 SPROC 的输出?我愿意接受另一种调用 SPROC 的方法(EXECUTE POPULATE_EMA @sym_in, 20,50,100,12,26, @mink_in, @maxk_in;)

DELETE FROM TA_HISTORY

DECLARE tables_cursor CURSOR
   FOR
   SELECT symbol, MinDSeqKey, MaxDSeqKey
   FROM STOCK_VITALS;

OPEN tables_cursor;

DECLARE @sym_in NVARCHAR(10);
DECLARE @mink_in bigint;
DECLARE @maxk_in bigint;

FETCH NEXT FROM tables_cursor INTO @sym_in, @mink_in, @maxk_in;

WHILE (@@FETCH_STATUS <> -1)
BEGIN;
    --PRINT 'Now Processing. ' + @sym_in;
   EXECUTE POPULATE_EMA @sym_in, 20,50,100,12,26, @mink_in, @maxk_in;

   INSERT INTO TA_HISTORY(SYMBOL, DSEQKEY, EMA20, EMA50, EMA100, EMA12, EMA26)
   SELECT @sym_in, DSEQKEY, EMA1, EMA2,EMA3,EMA4,EMA5
   FROM temp_ema_data
   WHERE @maxk_in - @mink_in > 49

   FETCH NEXT FROM tables_cursor INTO @sym_in, @mink_in, @maxk_in;
END;

CLOSE tables_cursor;

DEALLOCATE tables_cursor;

** 编辑 5/18 - 这是 SPROC - 我需要 SPROC 才能在另一个表中的 9,000 多行上运行。

BEGIN

DROP TABLE temp_ema_data

CREATE TABLE [dbo].[temp_ema_data](
    [n] [int] IDENTITY(1,1) NOT NULL,
    [dseqkey] [bigint] NULL,
    [close_price] [decimal](6, 2) NULL,
    [ema1] [decimal](8, 4) NULL,
    [ema2] [decimal](8, 4) NULL,
    [ema3] [decimal](8, 4) NULL,
    [ema4] [decimal](8, 4) NULL,
    [ema5] [decimal](8, 4) NULL
) ON [PRIMARY]

insert into temp_ema_data (dseqkey, close_price)
select dseqkey,prclose
from STOCK_HIST
where Symbol = @Symbol and dseqkey > @MinKey 
order by dseqkey asc

--declare variables needed
declare @K1 decimal(4,4), @K2 decimal(4,4), @K3 decimal(4,4), @K4 decimal(4,4)
, @K5 decimal(4,4)
declare @prev_ema_1 decimal(8,4), @prev_ema_2 decimal(8,4), @prev_ema_3 decimal(8,4)
, @prev_ema_4 decimal(8,4), @prev_ema_5 decimal(8,4),@initial_sma_1 decimal(8,4)
, @initial_sma_2 decimal(8,4), @initial_sma_3 decimal(8,2), @initial_sma_4 decimal(8,4)
, @initial_sma_5 decimal(8,4)
declare @anchor int

    set @K1 = 2/(1 + @ema_1_intervals + .000)
    set @K2 = 2/(1 + @ema_2_intervals + .000)
    set @K3 = 2/(1 + @ema_3_intervals + .000)
    set @K4 = 2/(1 + @ema_4_intervals + .000)
    set @K5 = 2/(1 + @ema_5_intervals + .000)           

select  @initial_sma_1 = avg(case when n < @ema_1_intervals 
        then close_price else null end),    
        @initial_sma_2  = avg(case when n < @ema_2_intervals 
        then close_price else null end),
        @initial_sma_3  = avg(case when n < @ema_3_intervals 
        then close_price else null end),
        @initial_sma_4  = avg(case when n < @ema_4_intervals 
        then close_price else null end),
        @initial_sma_5  = avg(case when n < @ema_5_intervals 
        then close_price else null end)                     
from temp_ema_data
where n < @ema_1_intervals or n < @ema_2_intervals or 
      n < @ema_3_intervals or n < @ema_4_intervals or
      n < @ema_5_intervals

update t1 
    set @prev_ema_1 = case 
    when n < @ema_1_intervals then null         
    when n = @ema_1_intervals then t1.close_price * @K1 + @initial_sma_1 * (1-@K1)  
    when n > @ema_1_intervals then t1.close_price * @K1 + @prev_ema_1 * (1-@K1) 
    end,
    @prev_ema_2 = case when n < @ema_2_intervals then null          
    when n = @ema_2_intervals then t1.close_price * @K2 + @initial_sma_2 * (1-@K2)  
    when n > @ema_2_intervals then t1.close_price * @K2 + @prev_ema_2 * (1-@K2)         
    end, 
    @prev_ema_3 = case when n < @ema_3_intervals then null          
    when n = @ema_3_intervals then t1.close_price * @K3 + @initial_sma_3 * (1-@K3)  
    when n > @ema_3_intervals then t1.close_price * @K3 + @prev_ema_3 * (1-@K3)         
    end, 
    @prev_ema_4 = case when n < @ema_4_intervals then null          
    when n = @ema_4_intervals then t1.close_price * @K4 + @initial_sma_4 * (1-@K4)  
    when n > @ema_4_intervals then t1.close_price * @K4 + @prev_ema_4 * (1-@K4)         
    end, 
    @prev_ema_5 = case when n < @ema_5_intervals then null          
    when n = @ema_5_intervals then t1.close_price * @K5 + @initial_sma_5 * (1-@K5)  
    when n > @ema_5_intervals then t1.close_price * @K5 + @prev_ema_5 * (1-@K5)         
    end,            
    ema1 = @prev_ema_1, ema2 = @prev_ema_2, ema3 = @prev_ema_3, ema4 = @prev_ema_4,
    ema5 = @prev_ema_5, @anchor = n --anchor so that carryover works properly   
from temp_ema_data t1 with (TABLOCKX) OPTION (MAXDOP 1)

END

【问题讨论】:

  • 你的存储过程'populate_ema'做什么?如果您进行任何类型的选择,它将输出结果 - 除非选择被插入(如上)。如果您执行了“选择”,则无法抑制输出结果 - 这就是“选择”的作用......
  • @M.R. - 好吧,如果存储过程只返回一个结果集,您可以将结果重新插入另一个表中
  • 我想不出为什么我会为任何插入使用游标。这只是糟糕的编码。您应该使 proc 接受表变量作为输入并执行基于集合的操作,或者您根本不应该使用子 proc 并在调用 proc 中执行基于集合的插入。这种编写方式总是会花费太多时间,并且会破坏您的系统性能。立即修复。
  • @tao - 这就是我所说的 - 只有在插入时才能抑制它......否则直接选择将输出结果......
  • @M.R.公平地说,我(错误)理解您的评论是在说明无法从我们提供的上下文中捕获/丢弃该 proc 调用的结果(不更改正在执行选择的 proc)

标签: sql sql-server stored-procedures


【解决方案1】:

你可以在菜单项下试试:查询->查询选项...

在树上选择结果-> 网格和结果-> 文本(以您适用的为准)有一个“执行后丢弃结果”复选框。我没用过,但听起来它可以满足你的需要。

编辑: 快速测试表明这会丢弃查询结果和 PRINT 语句输出。此外,对简单存储过程的 100 次调用循环从花费几秒钟(大部分时间花费在显示结果上)变为几乎即时运行时间。我想这就是你想要找到的。

【讨论】:

    【解决方案2】:

    您是否尝试将以下内容添加到您的 SPROC 顶部:

    SET ANSI_NULLS ON
    SET ANSI_WARNINGS ON
    SET NOCOUNT ON
    

    【讨论】:

    • ANSI_NULLS 和 ANSI_WARNINGS 对您有什么作用? NOCOUNT 将消除行数,但不会消除实际结果。
    【解决方案3】:

    基于游标消耗资源这一事实,如果不需要游标,我建议使用 sql server table variables 作为替代方案。

    还可以查看link,了解如何将基于游标的过程转换为基于表变量的过程。

    【讨论】:

      【解决方案4】:

      正如@Mark Kram 指出的那样,SET NOCOUNT ON 是您需要做的一件事,以防止从您向我们展示的存储过程中输出。

      对于被调用的 sproc POPULATE_EMA,我们无法根据您提供的详细信息知道它的输出 - 您是否将结果集返回到 SSMS?

      如果每次调用POPULATE_EMA 都会返回一个结果集(给客户端),您可以在服务器端INSERT INTO 一个临时表,以避免将该表发送到客户端。这看起来像:

      DELETE FROM TA_HISTORY
      
      --This table would need to match the structure of POPULATE_EMA!
      CREATE TABLE #TempResults (Column1 Int, Column2 Int) --, etc
      
      DECLARE tables_cursor CURSOR
         FOR
         SELECT symbol, MinDSeqKey, MaxDSeqKey
         FROM STOCK_VITALS;
      
      OPEN tables_cursor;
      
      DECLARE @sym_in NVARCHAR(10);
      DECLARE @mink_in bigint;
      DECLARE @maxk_in bigint;
      
      FETCH NEXT FROM tables_cursor INTO @sym_in, @mink_in, @maxk_in;
      
      WHILE (@@FETCH_STATUS <> -1)
      BEGIN;
          --PRINT 'Now Processing. ' + @sym_in;
         INSERT INTO #TempResults
         EXECUTE POPULATE_EMA @sym_in, 20,50,100,12,26, @mink_in, @maxk_in;
      
         INSERT INTO TA_HISTORY(SYMBOL, DSEQKEY, EMA20, EMA50, EMA100, EMA12, EMA26)
         SELECT @sym_in, DSEQKEY, EMA1, EMA2,EMA3,EMA4,EMA5
         FROM temp_ema_data
         WHERE @maxk_in - @mink_in > 49
      
         FETCH NEXT FROM tables_cursor INTO @sym_in, @mink_in, @maxk_in;
      END;
      
      CLOSE tables_cursor;
      
      DEALLOCATE tables_cursor;
      

      【讨论】:

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