@@ROWCOUNT: примеры (SQL)
@@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() при работе с потенциально очень большими объемами данных, например, в хранимых процедурах массовой обработки.
Расширенные сценарии использования
Использование в транзакциях для условного подтверждения изменений:
BEGIN TRANSACTION;
UPDATE Invoices SET Status = 'Paid' WHERE DueDate < GETDATE();
IF @@ROWCOUNT > 1000
BEGIN
ROLLBACK TRANSACTION;
RAISERROR('Обновлено слишком много строк. Откат.', 16, 1);
END
ELSE
COMMIT TRANSACTION;Применение в цикле для пакетной обработки:
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Логирование действий в таблице аудита:
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;Проверка существования данных перед выполнением операции:
IF EXISTS(SELECT 1 FROM Customers WHERE Country = 'Germany')
BEGIN
SELECT * FROM Customers WHERE Country = 'Germany';
PRINT 'Найдено клиентов: ' + CAST(@@ROWCOUNT AS VARCHAR(10));
END