如何执行SQL查询而不显示结果

51

有没有可能执行SQL查询但不显示结果?

类似于

Select * from Table_Name

运行此查询后,结果不应在 SQL Server 中显示。


2
如果这是面试问题,那么它似乎非常奇怪且没有经过深思熟虑。您可以在SQL Server Management Studio中“解析”(执行按钮旁边的勾号图标)SQL查询。它不会运行查询,但确实检查SQL是否有效。也许这就是他们想要表达的意思。 - Colin Mackay
9
关闭屏幕 ;) - Guido
5
有合理的(非面试)原因想要这样做。我已经尝试过两次找到一种方法来实现这个目标,两次都是出于几乎相同的原因,并且都是为了与劣质第三方软件协作而进行的黑客操作。简单来说:假设你正在使用某个软件,该软件接受用户输入的SQL(具有自定义查询的报告软件)。现在想象一下,你想为用户在顶部设置一些变量,以便提高可读性和简易性。现在想象一下,这个愚蠢的软件会让你这样做,但是需要检查SQL的第一个单词是否为SELECT。现在请开枪打死我吧,我不能再这样继续下去了。 - DaveRandom
2
我有一个使用案例。来这里寻找解决方案。我想找到所有包含“ItemID”字段的表...并且进一步,我想找到所有表格,其中至少有一条记录包含某些特定值的“ItemID”。并非所有表都有这个。如果只有在记录中“ItemID”等于此值时,我才想打印出表的名称。我不想要任何仅会混淆输出的结果。 - Luke
1
我还有另一个情况需要这样做: 我正在对数据库中的100多个表运行查询,以查找自然键中的重复项。 然后保存@@rowcount值。 然后我不关心结果,只关心返回的行数。 - Tech
显示剩余9条评论
12个回答

96

我很惊讶没有人提出答案:打开“执行后丢弃查询结果”选项;我非常确定这就是面试官想要的。 SET FMT ONLY 在我看来完全是另一回事。

在 SSMS 中:

  • 打开一个新查询
  • 在菜单中选择 查询 / 查询选项
  • 选择“结果”窗格
  • 选中“执行后丢弃结果”

你可能想这样做的原因是避免等待和浪费资源将结果加载到网格中,但仍然能够获取例如实际执行计划等信息。


我同意答案有歧义。它缺少“你为什么想这样做”和“我想在哪里这样做”的解释。如果他谈论的是SMSS并且只想执行一个查询而不显示结果(无论出于何种原因-我可以想象几个),我更喜欢你的答案。 - marsze
30
很棒的回答。我需要知道查询运行的时间,但不希望使用 SSMS 浪费 CPU 周期来绘制网格、占用显示内存和其他无关紧要的操作。 - Alex from Jitbit
8
就是这个。我需要连续运行 1000 个查询,每个查询都返回一个结果集并记录执行时间。如果结果集被显示出来,我很容易就会崩溃 SSMS。 - John B
3
性能优化/基准测试脚本正是你希望做到这一点的原因——你正在跟踪执行时间,并想忽略将结果传回所需的时间(这并不完全由你控制),而是关注查询执行时间(这是由你控制的)。这是完全合理的! - SqlRyan
1
我曾经看到在循环中调用了一个存储过程,它返回了一个非常小的结果集。在执行几百次这样的循环并因此返回几百个结果集后,SSMS会变得非常缓慢,完全无响应,并有可能因内存错误而崩溃。除了修改代码以插入和丢弃所有这些单独的结果之外,我可以看到设置上述选项将是一个有用的解决方法。 - Larry Smith
2
似乎也会丢弃消息,所以对我使用“set statistics”没有帮助。 - Paul

37

执行将会返回一个记录集。当然它可能没有行,但会得到结果。

您可以使用SET FMTONLY来抑制行,但不能抑制结果集。

SET FMTONLY ON
SELECT * FROM sys.tables

SET FMTONLY OFF
SELECT * FROM sys.tables

个人从未用过它......

编辑2018年。如注所述,现在可以参考@ deroby的答案以获得更好的解决方案。


2
值得一提的是,从SQL Server 2012开始,此功能已被弃用,并改为使用一些函数代替。请查看帖子中的链接以获取更多信息。 - Tech
8
值得一提的是,设置 fmtonly 不会实际运行查询,它只会获取元数据(因此得名)。对于运行基准测试没有什么用处... - thomasb
1
如果我使用SET FMTONLY ON,则WHILE @@FETCH_STATUS = 0不再用于通过游标进行迭代。 - profimedica
2
看看 @deroby 的回答,获取当前解决方案。 - Jon McEroy

15
听起来像是一个可疑的面试问题。我曾经做过,也需要这样做,但只有在非常模糊的情况下才需要这样做。虽然比较模糊,但有时非常重要。 正如@gbn所说,一种编程方式是使用SET FMTONLY(谢谢,现在我不必从旧脚本文件中挖掘了)。一些程序和实用程序在查询SQL时会这样做;首先他们提交一个带有FMTONLY ON的查询,以确定结果表结构的布局,然后当他们准备好后再运行它,带有FMTONLY OFF,以获取实际数据。(我发现这一点时,该过程调用了第二个过程,第二个过程返回了数据集,但由于某些模糊原因,整个过程都倒塌了。) 这也可以在SSMS中完成。对于所有查询窗口,在“工具/选项”,查询结果/SQL Server/结果到XX下,勾选“查询执行后丢弃结果”;对于当前窗口,在“查询/查询选项”,结果/XX下,同样的复选框。这里的优势在于查询将在数据库服务器上运行,但数据结果将不会返回。如果您正在检查查询计划但不想收到超过10GB的结果数据(通过网络传输到您的笔记本电脑),或者如果您正在进行一些严重的循环测试,这可能非常有价值,因为SSMS只能接受来自给定“运行”的有限数量的结果集,然后用“太多的结果集”消息停止查询。[嗯,关于那个“仅查询计划”的问题要再检查一下——我觉得它确实会这样做,但已经很久了。]

4
“Discard Results”似乎是唯一正确的方法来做到这一点 - 所有其他选项实际上并没有执行SQL :| - Spikeh
1
我认为这是一个有效的问题,它帮助我解决了我的问题。我之前一直遇到 SQL 内存异常问题,而这个解决方案对我很有帮助。 - Kalpesh Popat

9
也许面试官本意是问另一个问题:
如何执行SQL查询而不返回结果的数量?
在这种情况下,答案是SET NOCOUNT ON。

1
这个很好用,但是记得在运行查询或存储过程后加上“SET NOCOUNT OFF”。 - Troglo
这正是我想要的 :-) 只是我不记得语法了。 - Simon_Weaver

9
insert anothertable
Select * from Table_Name

执行select语句但不返回任何结果

set noexec on 
Select * from Table_Name

解析但不执行,因此不返回任何内容。

SET NOEXEC ON; SELECT 1 FROM MyTable WHERE 1 = 2; SET NOEXEC OFF;。可以完美地工作,并且可以查看在链接服务器上的破损动态SQL或丢失的表。 - it3xl

5
如果您需要执行查询但不需要实际结果集,可以在 EXISTS (或 NOT EXISTS) 语句中包装查询: IF EXISTS(SELECT * FROM TABLE_NAME...)。或者,您可以选择 INTO #temp,然后稍后删除临时表。

IF EXISTS (SELECT 1 FROM MyTable WHERE 1 = 2) BEGIN DoNothingHere: END; - it3xl
虽然这可能是避免复制大量数据的一种方式,但它并不完全相同。 WHERE EXISTS() 可能会在第一个符合条件的记录后停止。 但是,当以这种方式工作时,可能会遇到1000个“以下”的记录出现(例如)除以零错误,这将保持不被注意。 - deroby

3
在我的情况下,我正在测试数据在所有视图中的行为,例如任何cast()函数都不会导致转换错误等,因此抑制实际数据不是一个选项,显示不太糟糕,但浪费了一些资源,如果仅以文本形式发送结果,则最好不要显示。
我想出了以下脚本以此方式测试所有视图,唯一的问题是当遇到具有text/ntext列的视图时。
declare csr cursor local for select name from sys.views order by name
declare @viewname sysname
declare @sql nvarchar(max)

open csr
fetch next from csr into @viewname
while @@fetch_status = 0 begin
    --set @sql = 'select top 1 * from ' + @viewname 

    set @sql = 'declare @test nvarchar(max) select @test = checksum(*) from ' + @viewname 

    print @viewname

    exec sp_executesql @sql
    fetch next from csr into @viewname
end
close csr
deallocate csr

2

目的是要抑制所有行吗?那么请使用一个对每一行都评估为false的过滤器:

SELECT * FROM Table_Name WHERE 1 = 2

1
如果您正在使用PostgreSQL,可以将您的选择放入一个函数中并使用PERFORM语句。PERFORM语句执行一个参数并且不返回结果。
A PERFORM statement sets FOUND true if it produces (and discards) one or more rows, false if no row is produced.

https://www.postgresql.org/docs/9.1/plpgsql-statements.html#:~:text=A%20PERFORM%20statement%20sets%20FOUND,if%20no%20row%20is%20returned

这段内容与编程有关。它讲述了PERFORM语句的作用,该语句可以设置FOUND变量并返回一个结果集。如果没有返回任何行,则FOUND变量将被设置为false。


1
楼主要求使用SQL Server。 - Steve Scott

0
另一个用例是当您只想读取表的所有行时,例如针对损坏进行测试。在这种情况下,您不需要数据本身,只需要知道它是否可读。 然而,“执行后丢弃结果”选项名称有点令人困惑 - 它告诉我结果被获取,然后才被丢弃。相反,它确实获取数据,但不会将其存储在任何地方(默认情况下,行被放入网格或您选择的任何输出中) - 接收到的行会即时丢弃(而不是在执行之后)。

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