如何禁止从SQL Server中的另一个存储过程调用的存储过程的SELECT输出?

Dav*_*nov 53 sql t-sql sql-server

我不是在谈论做"SET NOCOUNT OFF".但我有一个存储过程,我用它来将一些数据插入到某些表中.这个过程创建一个xml响应字符串,让我举个例子:

CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int) AS
DECLARE @reply varchar(2048)

... Do a bunch of inserts/updates...

SET @reply = '<xml><big /><outputs /></xml>'
SELECT @reply
GO
Run Code Online (Sandbox Code Playgroud)

所以我把一个使用这个SP的脚本放在一起,并且xml"输出"变得太多了(它已经崩溃了我的盒子).

有没有办法抑制或重定向从此存储过程生成的输出?我不认为修改此存储过程是一种选择.

谢谢.


我想我应该澄清一下.上面的SP由我编写的T-SQL Update脚本调用,通过企业工作室管理器等运行.

它也不是我写过的最优雅的SQL(一些psuedo-sql):

WHILE unprocessedRecordsLeft
  BEGIN
    SELECT top 1 record from updateTable where Processed = 0
    EXEC insertSomeData @param = record_From_UpdateTable
  END
Run Code Online (Sandbox Code Playgroud)

所以我们假设UpdateTable中有大约50k的记录.该SP被称为50k次,将50k xml字符串写入输出窗口.它没有让sql服务器停止,只是我的客户端应用程序(sql server management studio).

Ser*_*gan 37

您正在寻找的答案可以在Josh Burke 的类似问题中找到:

-- Assume this table matches the output of your procedure
DECLARE @tmpNewValue TABLE ([Id] int, [Name] varchar(50))

INSERT INTO @tmpNewValue 
  EXEC ProcedureB

SELECT * FROM @tmpNewValue
Run Code Online (Sandbox Code Playgroud)

  • 如果 ProcedureB 调用了 EXEC 过程,你会怎么做?我不认为 MS SQL 可以将这个插入到嵌套的 exec 中。 (2认同)

Dav*_*nov 27

我想我找到解决方案.

那么我现在在我的SQL脚本中可以做的就是这样(sql-psuedo代码):

create table #tmp(xmlReply varchar(2048))
while not_done
  begin
    select top 1 record from updateTable where processed = 0
    insert into #tmp exec insertSomeData @param=record
  end
drop table #tmp
Run Code Online (Sandbox Code Playgroud)

现在,如果有更有效的方法来做到这一点.SQL Server是否有类似于/ dev/null的东西?空表还是什么?

  • 'select top 1 record from updateTable...' 获取要处理的下一条记录。然而,在 SP insertSomeData 中,它执行一个 select 语句,该语句打印出 xml 字符串,这就是我想要抑制的内容。我发现通过执行“插入#tmp exec SP”,过去打印到屏幕上的输出将被转储到一个表中,然后我可以删除该表,因为我不关心该输出。 (2认同)

dys*_*oko 10

回答这个问题,"如何抑制存储过程输出?" 真的取决于你想要完成的事情.所以我想贡献我遇到的东西:

我需要压缩存储过程(USP)输出,因为我只想从输出中获取行计数(@@ ROWCOUNT).我做了什么,这可能对每个人都不起作用,因为我的查询已经是动态sql我向有问题的USP添加了一个名为@silentExecution的参数.这是一个我默认为零(0)的位参数.

接下来,如果将@silentExecution设置为一(1),我会将表内容插入一个临时表,这会压缩输出,然后执行@@ ROWCOUNT没有问题.

USP示例:

CREATE PROCEDURE usp_SilentExecutionProc
    @silentExecution bit = 0
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @strSQL VARCHAR(MAX);

    SET @strSQL = '';

    SET @strSQL = 'SELECT TOP 10 * ';

    IF @silentExecution = 1
         SET @strSQL = @strSQL + 'INTO #tmpDevNull ';

    SET @strSQL = @strSQL +     
    'FROM dbo.SomeTable ';

    EXEC(@strSQL);
END
GO
Run Code Online (Sandbox Code Playgroud)

然后你可以这样执行整个事情:

EXEC dbo.usp_SilentExecutionProc @silentExecution = 1;
SELECT @@ROWCOUNT;
Run Code Online (Sandbox Code Playgroud)

这样做的目的是,如果您需要USP能够在其他用途​​或案例中返回结果集,但仍然只将其用于行.

只是想分享我的解决方案.


Joh*_*ers 5

伙计,这是一个计算机做你告诉它做的事情而不是你想要它做的事情.

如果您不希望它返回结果,则不要求它返回结果.将存储过程重构为两个:

CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int) AS
BEGIN
DECLARE @reply varchar(2048)

--... Do a bunch of inserts/updates...

EXEC SelectOutput
END
GO

CREATE PROCEDURE SelectOutput AS
BEGIN
SET @reply = '<xml><big /><outputs /></xml>'
SELECT @reply
END
Run Code Online (Sandbox Code Playgroud)

  • 我在那里同意你的意见.如果这是我被允许修改的东西,我会拆分存储的proc,或者将参数附加到不显示输出等. (2认同)
  • 你不知道op在做什么。也许存储过程做了一些事情并返回不需要的结果。 (2认同)

Lin*_*Lin 5

我最近在编写迁移脚本时遇到了类似的问题,由于问题以不同的方式解决,我想记录下来。通过运行一个简单的 while 循环 3000 次并调用一个过程,我几乎杀死了我的 SSMS 客户端。

DECLARE @counter INT
SET @counter = 10
WHILE @counter > 0 
BEGIN 
    -- call a procedure which returns some resultset
    SELECT  @counter-- (simulating the effect of stored proc returning some resultset)
    SET @counter = @counter - 1
END
Run Code Online (Sandbox Code Playgroud)

脚本结果是使用 SSMS 执行的,查询窗口的默认选项设置为显示“结果到网格”[Ctrl+d 快捷键]。

简单的解决方案: 尝试将结果设置为文件,以避免在 SSMS 客户端上构建和绘制网格。[CTRL+SHIFT+F 键盘快捷键设置查询结果到文件]。

此问题与:stackoverflow 查询有关