Suche…


Syntax

  • DECLARE Cursorname CURSOR [LOCAL | GLOBAL]
    • [FORWARD_ONLY | SCROLL]
      [STATIC | KEYSET | DYNAMISCH | FAST_FORWARD]
      [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
      [TYPE_WARNING]
    • FOR select_statement
    • [FOR UPDATE [OF Spaltenname [, ... n]]]

Bemerkungen

Normalerweise möchten Sie die Verwendung von Cursors vermeiden, da diese die Leistung beeinträchtigen können. In einigen speziellen Fällen müssen Sie Ihren Datensatz jedoch Datensatz für Datensatz durchlaufen und einige Aktionen ausführen.

Einfacher Vorwärtspfeil

Normalerweise möchten Sie die Verwendung von Cursors vermeiden, da diese die Leistung beeinträchtigen können. In einigen speziellen Fällen müssen Sie Ihren Datensatz jedoch Datensatz für Datensatz durchlaufen und einige Aktionen ausführen.

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

Rudimentäre Cursor-Syntax

Eine einfache Cursor-Syntax, die an einigen Beispiel-Testzeilen ausgeführt wird:

/* 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;

Ergebnisse aus SSMS. Beachten Sie, dass es sich hierbei um separate Abfragen handelt, die in keiner Weise vereinheitlicht werden. Beachten Sie, wie die Abfrage-Engine jede Iteration einzeln und nicht als Satz verarbeitet.

Ich würde Val
1 Foo
(1 Zeile (n) betroffen)
Ich würde Val
2 Bar
(1 Zeile (n) betroffen)
Ich würde Val
3 Baz
(1 Zeile (n) betroffen)


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow