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

时间:2009-05-15 00:08:07

标签: sql sql-server tsql

我不是在谈论做“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

所以我把一个使用这个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

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

10 个答案:

答案 0 :(得分:33)

你正在寻找的答案可以在Josh Burke的similar SO question中找到:

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

INSERT INTO @tmpNewValue 
  EXEC ProcedureB

答案 1 :(得分: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

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

答案 2 :(得分:9)

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

我需要压缩存储过程(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

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

EXEC dbo.usp_SilentExecutionProc @silentExecution = 1;
SELECT @@ROWCOUNT;

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

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

答案 3 :(得分: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

答案 4 :(得分:2)

您从哪个客户端调用存储过程?说它来自C#,你称之为:

var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
var read = com.ExecuteReader();

这还不会从服务器检索结果;你必须为此调用Read():

read.Read();
var myBigString = read[0].ToString();

因此,如果您不调用Read,则XML将不会离开Sql Server。您甚至可以使用ExecuteNonQuery调用该过程:

var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
com.ExecuteNonQuery();

此处客户端甚至不会要求选择结果。

答案 5 :(得分:2)

我最近在编写迁移脚本时遇到了类似的问题,并且由于问题以不同的方式解决,我想记录它。 我通过运行一个简单的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

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

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

此问题与:stackoverflow query

有关

答案 6 :(得分:1)

您可以创建一个执行此操作的SQL CLR存储过程。应该很容易。

答案 7 :(得分:0)

我不知道SQL Server是否有抑制输出的选项(我认为不会这样做),但SQL查询分析器有一个选项(在结果选项卡下)“丢弃结果”。

您是通过isql运行吗?

答案 8 :(得分:0)

你说你的服务器崩溃了。什么是使应用程序崩溃消耗此SQL或SQL Server本身的输出(假设SQL Server)。

如果您使用.Net Framework应用程序来调用存储过程,那么请查看SQLCommand.ExecuteNonQuery。这只执行存储过程而没有返回结果。如果问题出在SQL Server级别,那么您将不得不做一些不同的事情(即更改存储过程)。

答案 9 :(得分:-2)

曾尝试SET NOCOUNT ON;作为选项吗?