Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описаны различные методы, которые можно использовать для итерации результирующих наборов с помощью Transact-SQL в SQL Server.
Исходная версия продукта: SQL Server
Исходный номер базы знаний: 111401
Итоги
В этой статье описаны различные методы, которые можно использовать для имитации логики курсора FETCH
-NEXT
в хранимой процедуре, триггере или пакете Transact-SQL.
Использование инструкций Transact-SQL для итерации с помощью результирующих наборов
Ниже приведены три метода, которые можно использовать для итерации с помощью результирующих наборов с помощью инструкций Transact-SQL. В приведенных ниже примерах используется таблица Production.Product из примера базы данных AdventureWorks
Одним из методов является использование временных таблиц. С помощью этого метода создается моментальный снимок начальной SELECT
инструкции и используется в качестве основы для курсора. Например:
/********** example 1 **********/
SET NOCOUNT ON
DROP TABLE IF EXISTS #MYTEMP
DECLARE @ProductID int
SELECT * INTO #MYTEMP FROM Production.Product
SELECT TOP(1) @ProductID = ProductID FROM #MYTEMP
WHILE @@ROWCOUNT <> 0
BEGIN
SELECT * FROM #MYTEMP WHERE ProductID = @ProductID
DELETE FROM #MYTEMP WHERE ProductID = @ProductID
SELECT TOP(1) @ProductID = ProductID FROM #MYTEMP
END
Второй метод — использовать min
функцию для пошаговой работы по одной строке. Этот метод перехватывает новые строки, добавленные после начала выполнения хранимой процедуры, при условии, что новая строка имеет уникальный идентификатор больше текущей строки, обрабатываемой в запросе. Рассмотрим пример.
/********** example 2 **********/
SET NOCOUNT ON
DROP TABLE IF EXISTS #MYTEMP
DECLARE @ProductID int
SELECT @ProductID = min( ProductID ) FROM Production.Product
WHILE @ProductID IS NOT NULL
BEGIN
SELECT * FROM Production.Product WHERE ProductID = @ProductID
SELECT @ProductID = min( ProductID ) FROM Production.Product WHERE ProductID > @ProductID
END
Примечание.
В примере 1 и 2 предполагается, что для каждой строки в исходной таблице существует уникальный идентификатор. В некоторых случаях уникальный идентификатор не может существовать. Если это так, можно изменить метод временной таблицы, чтобы использовать только что созданный ключевой столбец. Например:
/********** example 3 **********/
SET NOCOUNT ON
DROP TABLE IF EXISTS #MYTEMP
SELECT NULL AS mykey, * INTO #MYTEMP FROM Production.Product
UPDATE TOP(1) #MYTEMP SET mykey = 1
WHILE @@ROWCOUNT > 0
BEGIN
SELECT * FROM #MYTEMP WHERE mykey = 1
DELETE FROM #MYTEMP WHERE mykey = 1
UPDATE TOP(1) #MYTEMP SET mykey = 1
END