@@ROWCOUNT: примеры (SQL)

Работа с функцией @@ROWCOUNT в Microsoft SQL Server
Раздел: Функции управления системой
@@ROWCOUNT: int

Описание функции @@ROWCOUNT

@@ROWCOUNT является системной функцией в Microsoft SQL Server, которая возвращает количество строк, затронутых последним выполненным оператором. Эта функция не требует аргументов и возвращает целочисленное значение типа int.

Использование функции актуально сразу после выполнения операторов DML (SELECT, INSERT, UPDATE, DELETE), а также команд управления потоком, таких как IF или WHILE. Значение сбрасывается после каждого выполненного оператора, поэтому функция должна применяться непосредственно после нужной инструкции.

Возвращаемое значение представляет собой число обработанных строк. Если последняя команда не затронула ни одной строки, результатом будет 0. В случае, когда оператор по умолчанию затрагивает все строки, например, SELECT без фильтра, возвращается общее количество строк в результирующем наборе.

Простые примеры применения

Пример после выполнения оператора SELECT:

SELECT * FROM Products WHERE CategoryID = 1;
SELECT @@ROWCOUNT AS 'Количество найденных товаров';
Количество найденных товаров
---------------------
12

Пример после выполнения UPDATE:

UPDATE Products SET Price = Price * 1.1 WHERE CategoryID = 2;
SELECT @@ROWCOUNT AS 'Обновлено строк';
Обновлено строк
--------------
7

Пример, когда строки не затронуты:

DELETE FROM Products WHERE ProductID = 999999;
SELECT @@ROWCOUNT AS 'Удалено строк';
Удалено строк
-------------
0

Похожие возможности в MS SQL

Косвенной альтернативой может служить предложение OUTPUT, которое возвращает информацию о затронутых строках непосредственно в рамках DML-оператора. Это удобно для получения данных модифицированных строк.

Функция ROWCOUNT_BIG() аналогична @@ROWCOUNT, но возвращает значение типа bigint. Она применяется, когда количество обработанных строк может превысить максимальное значение int (2^31-1).

Для управления поведением запросов ранее использовалась инструкция SET ROWCOUNT, которая ограничивала количество строк, обрабатываемых последующими командами. В современных версиях SQL Server предпочтительнее использовать TOP или OFFSET-FETCH.

Аналоги в других СУБД

MySQL: Функция ROW_COUNT() возвращает число строк, измененных последним оператором. Отличие в поведении для SELECT: в MySQL она возвращает -1 для SELECT, а в SQL Server - количество выбранных строк.

UPDATE users SET active=1 WHERE id=5;
SELECT ROW_COUNT();
ROW_COUNT()
----------
1

Oracle (PL/SQL): Атрибут SQL%ROWCOUNT возвращает количество строк, обработанных последним SQL-оператором.

BEGIN
  UPDATE employees SET salary = salary * 1.1;
  DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT);
END;
45

PostgreSQL: Команда GET DIAGNOSTICS позволяет получить количество обработанных строк. Также можно использовать специальную логическую переменную FOUND.

UPDATE products SET price = price * 0.9;
GET DIAGNOSTICS row_count = ROW_COUNT;
SELECT row_count;
row_count
---------
23

SQLite: Функция changes() возвращает количество строк, измененных последним оператором в текущем соединении.

UPDATE orders SET status='shipped' WHERE order_id=100;
SELECT changes();
changes()
---------
1

Частые ошибки

Основная ошибка - проверка значения @@ROWCOUNT после другого оператора, что приводит к получению некорректного результата.

UPDATE Products SET Price = 100 WHERE ProductID = 1;
PRINT 'Текст сообщения';
IF @@ROWCOUNT > 0 -- Проверяется количество строк, затронутых PRINT
    PRINT 'Строка обновлена';
Текст сообщения
(Сообщение об обновлении не выводится, так как @@ROWCOUNT после PRINT равен 0)

Еще одна проблема - попытка сохранить значение в переменную без учета сброса.

DECLARE @Count INT;
UPDATE Products SET Price = Price * 1.05;
SET @Count = @@ROWCOUNT;
SELECT @Count AS 'Количество', @@ROWCOUNT AS 'Текущее значение';
Количество Текущее значение
--------- -----------------
15        1

В данном случае @@ROWCOUNT в SELECT возвращает 1 (количество строк в результирующем наборе SELECT), а не 15 от UPDATE.

История изменений

Функция @@ROWCOUNT присутствует во всех версиях SQL Server. Существенных изменений в ее поведении не было. В SQL Server 2000 и более ранних версиях для обработки очень больших наборов данных могла возникнуть необходимость в использовании функции ROWCOUNT_BIG(), представленной как альтернатива для случаев, когда количество строк превышает 2^31-1.

В современных версиях SQL Server (2012 и выше) рекомендуется использовать функцию ROWCOUNT_BIG() при работе с потенциально очень большими объемами данных, например, в хранимых процедурах массовой обработки.

Расширенные сценарии использования

Использование в транзакциях для условного подтверждения изменений:

Пример sql
BEGIN TRANSACTION;
UPDATE Invoices SET Status = 'Paid' WHERE DueDate < GETDATE();
IF @@ROWCOUNT > 1000
BEGIN
    ROLLBACK TRANSACTION;
    RAISERROR('Обновлено слишком много строк. Откат.', 16, 1);
END
ELSE
    COMMIT TRANSACTION;

Применение в цикле для пакетной обработки:

Пример sql
DECLARE @RowsAffected INT = 1;
WHILE @RowsAffected > 0
BEGIN
    DELETE TOP (1000) FROM LargeTable WHERE Condition = 0;
    SET @RowsAffected = @@ROWCOUNT;
    PRINT 'Удалено строк: ' + CAST(@RowsAffected AS VARCHAR(10));
    CHECKPOINT;
END

Логирование действий в таблице аудита:

Пример sql
DECLARE @ChangeCount INT;
BEGIN TRANSACTION;
    INSERT INTO ArchiveTable SELECT * FROM CurrentTable WHERE IsOld = 1;
    SET @ChangeCount = @@ROWCOUNT;
    DELETE FROM CurrentTable WHERE IsOld = 1;
    INSERT INTO AuditLog (Operation, RowsAffected, UserName, Timestamp)
    VALUES ('Archiving', @ChangeCount, SUSER_SNAME(), GETDATE());
COMMIT TRANSACTION;

Проверка существования данных перед выполнением операции:

Пример sql
IF EXISTS(SELECT 1 FROM Customers WHERE Country = 'Germany')
BEGIN
    SELECT * FROM Customers WHERE Country = 'Germany';
    PRINT 'Найдено клиентов: ' + CAST(@@ROWCOUNT AS VARCHAR(10));
END

MS SQL @@ROWCOUNT function comments

En
@@ROWCOUNT Returns the number of rows affected by the last statement