Интересное поведение в "NOEXEC ON"

Пока я писал несколько запросов 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 строк (строк))

Ответ 1

Хотя это может и не быть ответом на ваш вопрос:

Но когда вы удаляете

SET NOEXEC ON 
DELETE FROM Test 

Если вы добавите условие where в DELETE STATEMENT, например DELETE FROM Test WHERE COLUMN1='etc'

Вы получите желаемые результаты... Это может быть из-за выполненных нами команд DDL и DML.

Я также проанализировал третью ситуацию, когда in, если вы вставляете во временную таблицу, она дает вам (0 строк Affected), но если одна и та же вставка находится в некоторой базе данных или выполняется постоянная таблица, она дает (команда успешно завершена. )

Здесь это может быть из-за таблицы temp и постоянной таблицы.

Для 4-го вы добавили GO:

GO будет выполнять соответствующие команды sql n раз.

Итак, если вы индивидуально выполняете оператор insert, а оператор delete имеет некоторое возвращаемое значение, а GO добавляет их в пакетный план.

Ответ 2

Я воспроизвожу поведение на SQl Server 2005 и 2008, поэтому он не является эксклюзивным для R2 и тем же самым, что происходит со вставкой, происходит со статусом обновления, поэтому исключение кажется исключением. Даже Truncate (который в значительной степени удаляет, получает стандартное сообщение)

Я также подумал, что это может быть проблема с SQL Server Management Studio, но нет, я тестировал другой инструмент и даже запускал его на SQLCMD и видел такое же поведение:

enter image description here

За исключением того, что "Команда успешно". сообщение не появляется (это должно быть исключительно SSMS)

В любом случае, я не могу объяснить, но могу догадаться. Я предполагаю, что это происходит, потому что оператор delete делает что-то другое (или меньше), которое нет в Insert и Update. Процесс компиляции делится на четыре части: синтаксический анализ, нормализация, компиляция и оптимизация. Я предполагаю, что что-то внутри этих шагов выполняется по-разному с помощью инструкции delete, поэтому мы получаем другой результат