DECLARE CURSOR przetwarzanie rekor po rekordzie w MS SQL


W pewnym momencie pracy z MS SQL server pojawia się potrzeba by przetwarzać dane rekord po rekordzie. Na przykład w sytuacji gdy potrzebuje by sprawdzać zależności pomiędzy poszczególnymi rekordami,a przy okazji pobierać dodatkowe informacje z innych tabel. Możliwość tą daje kursor. Kursor jest zbiorem rekordów który można przetwarzać rekordzie po rekordzie lub określone rekordy w zbiorze.


Składni deklaracji kursora:
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR 
    FOR select_statement 
[;]


cursor_name - nazwa kursora

[ INSENSITIVE ] [ SCROLL ] - rodzaj kursora (są również inne typy deklaracji kursora można o nich przeczytać na stronie MSDN)

select_statement - zapytanie które jest źródłem rekordów dla kursora



Przykład:

create table dane (lp int identity(1,1), nazwa nvarchar(30), flaga int default 0)

insert into dane (nazwa,flaga) values ('1',1),('2',1),('3',1),('4',1),('5',1)

DECLARE @I INT 
declare kur SCROLL cursor for  
select lp from dane ORDER BY LP
OPEN kur;
FETCH NEXT FROM kur INTO @I;
WHILE @@FETCH_STATUS=0
	BEGIN
	PRINT @I;
	IF @I % 2 =0 UPDATE dane SET flaga=0 WHERE lp = @I
	
	
	FETCH NEXT FROM kur INTO @I;
	END
CLOSE kur	
DEALLOCATE kur
SELECT * FROM DANE

DROP TABLE DANE

go


-------------------------

lp nazwa flaga

1 1 1

2 2 0

3 3 1

4 4 0

5 5 1


W/w przykład demonstruje jak przetwarzać dane rekord po rekordzie sprawdzać wartość lp i aktualizować jeśli jest podzielna przez dwa. Oczywiście przykład demonstruje tylko użycie kursora ten sam wynik można uzyskać w inny sposób.

W kodzie powyżej celem pobierania rekordów użyłem pętli WHILE warunek @@FETCH_STATUS=0 oznacz, że kursor wykona się do ostaniego rekordu. Polcenie FETCH NEXT FROM pobiera kolejny rekord i umieszcza wartości z niego w zmiennej lub zmienych (wymieniamy je po przecinku). Na sam koniec należy zamknąć kursor.

DECLARE @I INT, @y int 
declare kur SCROLL cursor for  
select lp from dane ORDER BY LP
OPEN kur;
FETCH NEXT FROM kur INTO @I;
WHILE @y<3
	BEGIN
	PRINT @I;
	IF @I % 2 =0 UPDATE dane SET flaga=0 WHERE lp = @I
	
	
	FETCH NEXT FROM kur INTO @I;
	END
CLOSE kur	
DEALLOCATE kur
SELECT * FROM DANE

go



Ten przykład demonstruje że możemy jako warunek podać dowolną wartość by przetwarzać dane w zbiorze z kursora.

Poruszanie się po rekordach w CURSOR



Deklaracja CURSOR typu CROLL pozwala nam na decydowanie jak chcemy się przemieszczać w naszym zbiorze.

Przykład:
create table dane (lp int identity(1,1), nazwa nvarchar(30), flaga int default 0)

insert into dane (nazwa,flaga) values ('1',1),('2',1),('3',1),('4',1),('5',1)

DECLARE @I INT 
declare kur SCROLL cursor for  
select lp from dane ORDER BY LP
OPEN kur;
FETCH FIRST FROM kur INTO @I;
PRINT @I
FETCH LAST FROM kur INTO @I;
PRINT @I
FETCH PRIOR FROM kur INTO @I;
PRINT @I
FETCH ABSOLUTE 2 FROM kur INTO @I;
PRINT @I
FETCH RELATIVE 3 FROM kur INTO @I;
PRINT @I
FETCH RELATIVE -2 FROM kur INTO @I;
PRINT @I
CLOSE kur;
DEALLOCATE kur;

drop table dane

go


-------------

(5 row(s) affected)

1

5

4

2

5

3

Kod powyżej demonstruje jak przemieszczać się po naszym zbiorze rekordów.

FETCH FIRST - ustawia kursor na pierwszy rekord

FETCH LAST - ustawia kursor na ostatni rekord

FETCH PRIOR FROM - ustawia kursor na rekord jeden przed bieżącym

FETCH ABSOLUTE n - ustawia kursor na rekord o pozycji n w zbiorze

FETCH RELATIVE n - ustawi kursor na rekord o pozycji n od bieżącej



CURSOR w MS SQL pozwala na wiele zastosowań do przetwarzania grupy rekordów rekord po rekordzie lub dowolnych rekordów gdy pojawia się taka potrzeba. Pamiętać należy jednak, że nie zawsze jest wydajnym rozwiązaniem choć czasem może być wydajniejszy niż standardowe zapytanie. Przed jego wykorzystaniem należy sprawdzić, które rozwiązanie będzie najleprze w Twoim środowisku.


powrót















SQL-KURSY.pl poleca:

Książki
ksikaksikaksikaksikaksika

Copyright 2010-2011mariuszhk@op.pl

obob ob

Valid HTML 4.01 Transitional

Strona internetowa wykorzystuje pliki cookie zapisywane w pamięci przeglądarki internetowej.

OK