当我执行一个存储过程时,如何禁用查询结果?

25

在存储过程中,光标内调用了另一个存储过程。每次调用时,SQL Management Studio都会显示结果。当光标循环100次时,结果窗口就会因为错误而停止工作。有没有办法阻止光标内的存储过程输出任何结果?

  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC @RC = dbo.NoisyProc
    SELECT @RValue2 = 1 WHERE @@ROWCOUNT = 0
    FETCH NEXT FROM RCursor INTO @RValue1, @RValue2
  END

谢谢!


1
你真的确定需要使用游标吗?在SQL Server中,这些不应该是首选。事实上,许多专家都憎恶它们。 - DOK
1
请在此处发布您收到的错误。 - Joe Pineda
7个回答

33

您可以按照以下步骤在SQL Server Mgmt Studio 2005中丢弃结果集:

• 在查询窗口中右键单击
• 选择“查询选项”
• 单击左侧面板树视图中的“结果”“节点”
• 在表单中央/右侧勾选“执行后丢弃结果”

您可以尝试一下。

DECLARE @i int
SET @i = 1
WHILE (@i <= 100)
  BEGIN
    SELECT @i as Iteration
    SET @i = @i + 1
  END


3
这应该是被接受的答案——这是SQL Server Management Studio中的选项,可以完全满足原帖作者的要求。 - Evan M

16

您可以将结果插入到临时表中,然后删除临时表。

create table #tmp (columns)

while
    ...
    insert into #tmp exec @RC=dbo.NoisyProc
    ...
end
drop table #tmp
否则,您能否修改被调用的过程以接受一个标志,告诉它不要输出结果集?

我正在重用一个由Web应用程序使用的过程以进行可重复使用的导入过程,因此我无法更改任何过程的行为。这正是我需要的。 - Nate Anderson

12

我知道这个问题很久了,但你可以设置SET NOCOUNT ON,以防止存储过程为每一行输出一条消息。


1
谢谢,谢谢,谢谢!这是针对SQL 2000的确切答案。我认为Adam的答案适用于SQL 2005+。 - RLH
3
NOCOUNT很好,因为它可以避免显示结果数,但是6eorge Jetson/Robert Koritnik会排除额外的结果集(我认为这就是原始问题的意思)? - Chris Woodruff

3

光标不好。如果意味着你必须使用光标执行基于集合的函数,则不要重用存储过程代码。为了性能更好,最好以基于集合的方式编写代码。

我认为你更关心抑制消息而不是你在光标中遇到错误。


1
你说得对 - 尽管我在这里受到限制。由于它属于第三方,出于支持原因,我无法更改存储过程。 - Alex Angas

1

可能错误来自于返回了太多的记录集,而不是你的存储过程或游标本身存在逻辑缺陷。看看这个例子:

DECLARE @I INT
SET @I=0
WHILE @I<200 BEGIN
    SELECT * FROM INFORMATION_SCHEMA.TABLES
    SET @I = @I + 1
END

程序将运行多次(略大于100),然后出现以下错误:

查询已超过结果网格中可显示的最大结果集数量。仅在网格中显示前100个结果集。

SSMS有限制它可以向您显示的记录集的数量。 绕过该限制的一种快速方法是按Ctrl+T(或菜单查询->结果到->结果到文本)强制输出为纯文本,而不是表格状的记录集。您最终会达到另一个限制(结果窗口无法处理无限量的文本输出),但它会大得多。

在上面的示例中,更改结果为文本形式后就不会出现错误!


1
这个页面很旧,回复也很老。但是,最佳答案没有得到顶部的投票。我想这是因为没有提供足够的解释。
使用NOCOUNT设置。每个人都应该查看NOCOUNT设置。默认设置为OFF。
即使在新数据库上通用地更改此默认设置也可能会对某些程序员/用户造成困惑。我建议使用在更改设置之前捕获设置的方法,然后将其设置回去。下面的示例脚本演示了NOCOUNT设置的使用。
这是一篇好文章。 https://www.sqlshack.com/set-nocount-on-statement-usage-and-performance-benefits-in-sql-server/
DROP TABLE IF EXISTS TestTable
GO
CREATE TABLE TestTable (ID INT, TestText VARCHAR (40))
GO

-- Get the Original NOCOUNT setting and save it to @OriginalNoCountSettingIsOn
DECLARE @options INT
SET @options = @@OPTIONS
DECLARE @OriginalNoCountSettingIsOn AS bit
SET @OriginalNoCountSettingIsOn = IIF(( (512 & @@OPTIONS) = 512 ),1,0)

-- Now set NOCOUNT ON to suppress result output returned from INSERTS 
-- Note - this does not affect @@ROWCOUNT values from being set 
SET NOCOUNT ON --  <---- Try running script with SET NOCOUNT ON and SET NOCOUNT OFF to See difference

INSERT INTO TestTable (ID, TestText)
VALUES  (0, 'Test Row 1')

INSERT INTO TestTable (ID, TestText)
VALUES  (0, 'Test Row 2'),
        (0, 'Test Row 3'),
        (0, 'Test Row 4')

INSERT INTO TestTable (ID, TestText)
VALUES  (0, 'Test Row 5')

/*Now set NOCOUNT back to original setting*/
IF @OriginalNoCountSettingIsOn = 1 
BEGIN
    SET NOCOUNT ON
END
ELSE
BEGIN
    SET NOCOUNT OFF
END 

DROP TABLE IF EXISTS TestTable
GO

0

地点:

SET ROWCOUNT OFF
/* the internal SP */
SET ROWCOUNT ON

可以将其包裹在内部的SP周围,或者甚至可以将其包裹在来自原始查询的SELECT语句周围,这将防止结果出现。


我尝试了,但收到了错误消息。我还尝试将其包装在SET ROWCOUNT 1和SET ROWCOUNT 0周围,但没有成功。 - Alex Angas
我相信这适用于SQL Server 2005及以上版本。如果您使用的是SQL 2000,请参阅Estanislao的回复。 - RLH
3
SET ROWCOUNT 的语法是 SET ROWCOUNT {number|@number_var}。它不接受 ON/OFF 作为参数。 - Tony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接