Поиск…


Синтаксис

  • DECLARE cursor_name CURSOR [LOCAL | ГЛОБАЛЬНЫЙ ]
    • [FORWARD_ONLY | SCROLL]
      [STATIC | KEYSET | ДИНАМИКА | ПЕРЕМОТКА ВПЕРЕД ]
      [READ_ONLY | SCROLL_LOCKS | ОПТИМИЗАЦИЯ]
      [TYPE_WARNING]
    • ДЛЯ select_statement
    • [FOR UPDATE [OF column_name [, ... n]]]

замечания

Обычно вы хотели бы избежать использования курсоров, поскольку они могут отрицательно влиять на производительность. Однако в некоторых особых случаях вам может потребоваться выполнить запись записи по записи и выполнить некоторые действия.

Основной прямой только курсор

Обычно вы хотели бы избежать использования курсоров, поскольку они могут отрицательно влиять на производительность. Однако в некоторых особых случаях вам может потребоваться выполнить запись записи по записи и выполнить некоторые действия.

DECLARE @orderId AS INT

-- here we are creating our cursor, as a local cursor and only allowing 
-- forward operations
DECLARE rowCursor CURSOR LOCAL FAST_FORWARD FOR
    -- this is the query that we want to loop through record by record
    SELECT [OrderId]
    FROM [dbo].[Orders]

-- first we need to open the cursor
OPEN rowCursor

-- now we will initialize the cursor by pulling the first row of data, in this example the [OrderId] column,
-- and storing the value into a variable called @orderId
FETCH NEXT FROM rowCursor INTO @orderId

-- start our loop and keep going until we have no more records to loop through
WHILE @@FETCH_STATUS = 0 
BEGIN

    PRINT @orderId
    
    -- this is important, as it tells SQL Server to get the next record and store the [OrderId] column value into the @orderId variable
    FETCH NEXT FROM rowCursor INTO @orderId

END

-- this will release any memory used by the cursor
CLOSE rowCursor
DEALLOCATE rowCursor

Синтаксис рудиментарного курсора

Простой синтаксис курсора, работающий на нескольких примерах тестовых строк:

/* Prepare test data */
DECLARE @test_table TABLE
(
    Id INT,
    Val VARCHAR(100)
);
INSERT INTO @test_table(Id, Val)
VALUES 
    (1, 'Foo'), 
    (2, 'Bar'), 
    (3, 'Baz');
/* Test data prepared */

/* Iterator variable @myId, for example sake */
DECLARE @myId INT;

/* Cursor to iterate rows and assign values to variables */
DECLARE myCursor CURSOR FOR
    SELECT Id
    FROM @test_table;

/* Start iterating rows */
OPEN myCursor;
FETCH NEXT FROM myCursor INTO @myId;

/* @@FETCH_STATUS global variable will be 1 / true until there are no more rows to fetch */
WHILE @@FETCH_STATUS = 0
BEGIN

    /* Write operations to perform in a loop here. Simple SELECT used for example */
    SELECT Id, Val
    FROM @test_table 
    WHERE Id = @myId;

    /* Set variable(s) to the next value returned from iterator; this is needed otherwise the cursor will loop infinitely. */
    FETCH NEXT FROM myCursor INTO @myId;
END
/* After all is done, clean up */
CLOSE myCursor;
DEALLOCATE myCursor;

Результаты SSMS. Обратите внимание, что это все отдельные запросы, они никоим образом не унифицированы. Обратите внимание, как механизм запросов обрабатывает каждую итерацию один за другим, а не как набор.

Я бы Val
1 Foo
(Затронуты 1 ряд)
Я бы Val
2 Бар
(Затронуты 1 ряд)
Я бы Val
3 Baz
(Затронуты 1 ряд)


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow