12

当我用 编写一些 T-SQL 查询时NOEXEC ON,我经历了 SQL Server 的有趣行为,我很好奇它为什么会发生。有时我只得到

命令成功。

消息如我所料,但有时我收到一个或多个

(0 行受影响)

消息。

我知道该SET NOEXEC ON命令编译查询但不执行它,所以我认为我不应该得到任何

(0 行受影响)

消息。

在第一个示例中,一切看起来都很正常。

SET NOEXEC ON
INSERT INTO Test (column1) VALUES ('etc')

结果:

命令成功。

但在第二个例子中,我认为出了点问题......

SET NOEXEC ON
DELETE FROM Test

结果:

(0 行受影响)

在第三个示例中,我使用了临时表:

CREATE TABLE #tmp (id INT IDENTITY(1, 1), idX INT)

SET NOEXEC ON
INSERT INTO #tmp (idX) VALUES (1)
DELETE FROM Test

SET NOEXEC OFF
DROP TABLE #tmp

结果:

(0 行受影响)

最后我只添加GO到我的查询中,我认为结果很有趣

CREATE TABLE #tmp (id INT IDENTITY(1, 1), idX INT)
SET NOEXEC ON
GO

INSERT INTO #tmp (idX) VALUES (1)
DELETE FROM Test

SET NOEXEC OFF
DROP TABLE #tmp

结果:

(0 行受影响)

(0 行受影响)

4

2 回答 2

2

尽管这可能不是您问题的答案:

但是当你删除

SET NOEXEC ON 
DELETE FROM Test 

如果您向DELETESTATEMENT 添加 where 条件,例如DELETE FROM Test WHERE COLUMN1='etc'

你会得到想要的结果...这种行为可能是因为我们执行了 DDL 和 DML 语句。

我还分析了第三种情况,如果您在临时表中插入它会给您(0 行受影响),但如果在某个数据库或永久表上完成相同的插入,它会给出(命令成功完成。)

这里可能是因为临时表和永久表。

对于第四个,您添加了一个GO

GO将执行相关的 sql 命令 n 次。

因此,如果您单独执行插入语句和删除语句都有一些返回值并且GO正在将它们添加到批处理计划中。

于 2012-05-15T04:40:58.827 回答
1

我在 SQl Server 2005 和 2008 上重现了该行为,因此它不是 R2 独有的,并且插入发生的相同事情发生在更新语句中,因此删除似乎是例外。甚至截断(这几乎是一个删除获取标准消息)

我还认为它可能是 SQL Server Management Studio 的东西,但不是,我在另一个工具上进行了测试,甚至在 SQLCMD 上运行它并且可以看到相同的行为:

在此处输入图像描述

除了“命令成功”。消息未出现(这必须是 SSMS 专有的)

无论如何,我无法解释,但我能猜到。我想它的发生是因为 delete 语句做了其他(或更少) Insert 和 Update 没有做的事情。编译过程分为四个部分:解析、规范化、编译和优化。我假设这些步骤中的某些内容由 delete 语句以不同的方式完成,这就是我们得到不同结果的原因

于 2012-05-16T12:24:06.277 回答