Почему @@ ROWCOUNT возвращает 1 для оператора NULL с использованием sp_executesql? - PullRequest
4 голосов
/ 01 июля 2019

Если бы я запустил это:

DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;

Я бы ожидал получить 0, возможно, даже NULL будет иметь смысл.Но я тоже не получаю, я получаю 1. Почему на 1 строку влияет выполнение NULL-запроса?Если я передаю «правильный» (non_NULL) запрос, то он работает нормально.


Фон (для тех, кто заботится): это процесс, который должен генерировать динамический SQL для его обновления.ряд и ТОЛЬКО один ряд.Мне нужно проверить, была ли затронута 1 строка, а не 0, 2 или более 2. Она работала нормально, пока каким-то образом не удалось сгенерировать оператор NULL SQL, и это было расценено как успех - упс!

Фактическое исправление будет состоять в том, чтобы проверить, что SQL не равен NULL, прежде чем запускать его, и обрабатывать оператор NULL таким же образом, как и результат, отличный от 1. Но мне все равно было любопытно, почему он так себя вел.

Ответы [ 2 ]

4 голосов
/ 01 июля 2019

Это потому, что вы вводите NULL в свою переменную. Операторы, которые выполняют простое присваивание, всегда устанавливают значение @@ ROWCOUNT равным 1.

См. Пример ниже. Поскольку студия управления может выполнять свои собственные запросы для соединения и связываться со значением @@ROWCOUNT, она начинает с выбора пустого результирующего набора, чтобы гарантировать, что начальное значение @@ROWCOUNT равно нулю.

Если назначения нет, SELECT @@ROWCOUNT возвращает 0 (исходное значение не было изменено). В противном случае возвращается 1

/*Ensure @@ROWCOUNT starts off at 0*/
SELECT 1 WHERE 1 = 0;

DECLARE @sql NVARCHAR(10);
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;

GO

/*Ensure @@ROWCOUNT starts off at 0*/
SELECT 1 WHERE 1 = 0;

DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;

Вы также можете попробовать подобное с ненулевым начальным значением

/*Ensure @@ROWCOUNT starts off at 3*/
SELECT 1 UNION SELECT 2 UNION SELECT 3

DECLARE @sql NVARCHAR(10);
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT; --Returns 3

GO

/*Ensure @@ROWCOUNT starts off at 3*/
SELECT 1 UNION SELECT 2 UNION SELECT 3

DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT; --Returns 1
1 голос
/ 01 июля 2019

Обратите внимание, что мой ответ был написан исключительно из моего опыта работы с SQL Server Management Studio и не дает точного объяснения этому поведению. Мартин Смит объяснил, почему это не так в комментарии ниже.

Похоже, sp_executesql вообще не запускается с нулевым параметром, возможно, как отказоустойчивый.

Попробуйте запустить «SELECT @@ ROWCOUNT» отдельно в пакете, и вы увидите, что он возвращает 1, независимо от того, что текущий счетчик строк отсутствует. Вполне вероятно, что 1 является возвращаемым значением по умолчанию, и именно поэтому вы видите это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...