EWSIE
28.11.2010
KURSORY
W PostgreSQL kursor jest wskaźnikiem tylko-do-odczytu do zestawu wyników zakończonej instrukcji SELECT. Kursory zazwyczaj stosuje się w aplikacjach, które utrzymują trwałe połączenie z serwerem PostgreSQL. Poprzez utworzenie kursora i utrzymanie połączenia do jego zestawu wyników, można w bardziej efektywny sposób decydować o tym, które wiersze mają być pobrane z zestawu wyników w różnych sytuacjach, bez potrzeby ponownego wykonywania zapytania z klauzulami LIMIT oraz OFFSET. Ponadto kursory stosuje się w celu umożliwienia w obrębie interfejsu programowania aplikacji wykonania wielu zapytań do tego samego serwera, śledzenia ich i przetwarzania oddzielnie oraz uniknięcia konieczności zapisywania wszystkich wyników poprzez aplikację. Kursory można również tworzyć i wykorzystywać bezpośrednio za pomocą standardowych instrukcji SQL.
W języku SQL mamy cztery instrukcje obsługujące kursory:
1. DECLARE – definiuje i równocześnie otwiera kursor: zdefiniowanie kursora w pamięci, następnie wypełnienie go informacjami zwróconymi w wyniku wykonania zapytania.
2. FETCH – pozwala pobrać wiersze z otwartego kursora.
3. MOVE – przesuwa bieżące położenie kursora w obrębie zestawu wyników.
4. CLOSE – zamyka kursor i zwalnia przydzieloną pamięć.
DEKLARACJA KURSORA
Instrukcja DECLARE powoduje zarówno utworzenie, jak i zainicjalizowanie kursora – czyli jego
„otwarcie”. Kursor można zadeklarować jedynie wewnątrz istniejącego bloku transakcji, dlatego przed jego zadeklarowaniem należy wykonać instrukcję BEGIN.
DECLARE nazwa_kursora [ BINARY ] [ INSENSITIVE ] [ [ NO] SCROLL ]
CURSOR [ { WITH | WITHOUT } HOLD ] FOR zapytanie;
nazwa_kursora – nazwa kursora, który ma być utworzony;
1
EWSIE
28.11.2010
BINARY – opcjonalne słowo kluczowe, które powoduje, że uzyskany wynik ma format binarny (standardowym formatem jest ASCII).
INSENSITIVE – zapewnia, że żadna z danych pobieranych z kursora nie będzie modyfikowana przez inne kursory lub połączenia. Ponieważ w PostgreSQL lursory muszą być definiowane w obrębie bloków transakcji, takie działanie jest domyślne.
[ NO ] SCROLL - pozwala na przemieszczanie się do tyłu (BACKWARD) po zbiorze kursora.
Zadeklarowanie kursora jako NO SCROLL blokuje przechodzenie po kursorze do tyłu. Jeżeli w definicji kursora nie zostanie jawnie użyte ani SCROLL ani NO SCROLL, wówczas, jeżeli plan zapytania jest prosty i niezbyt kosztowny, kursor będzie się zachowywał jakby użyto SCROLL i pozwoli na przechodzenie po wierszach w obie strony. Może się jednak okazać, że tak zadeklarowany kursor pozwoli jedynie na przechodzenie w kierunku FORWARD, a BACKWARD
będzie niedostępny.
WITH HOLD – pozwala na używanie kursora nawet wtedy, gdy transakcja, w której go utworzono, zostanie pozytywnie zakończona (COMMIT).
WITHOUT HOLD – mówi, że kursor nie może być użyty poza obrębem transakcji, w której został
utworzony. Jest to domyślne działanie kursora, jeżeli ani WITH HOLD, ani WITHOUT HOLD nie zostanie jawnie użyta.
UWAGA: Kursor z opcją HOLD jest zamykany albo w wyniku polecenia CLOSE nazwa_kursora, albo z chwilą zakończenia sesji.
zapytanie - określa zapytanie do wykonania. Zestaw wyników tego zapytania będzie dostępny za pośrednictwem kursora.
PRZYKŁAD 1
BEGIN;
DECLARE wszyscy_pracownicy CURSOR FOR SELECT * FROM pracownik; W przykładzie 1 rozpoczęto blok transakcji, a następnie otwarto kursor zawierający wszystkie informacje o pracownikach.
2
EWSIE
28.11.2010
POBIERANIE DANYCH Z KURSORA
FETCH [ FORWARD | BACKWARD ]
[ # | ALL | NEXT | PRIOR ]
[ I N | FROM ] nazwa_kursora;
Kursor zawsze wskazuje na bieżącą pozycję w zestawie wyników wykonanej instrukcji. W celu określenia kierunku „przesunięcia” kursora stosujemy słowa kluczowe:
FORWARD – w przód (działanie domyślne) lub
BACKWARD – w tył.
Następnie określa się liczbę zwracanych wierszy:
# - w postaci stałej całkowitej,
ALL – wszystkie wiersze,
NEXT – następny wiersz w stosunku do bieżącej pozycji kursora (działanie domyślne) lub PRIOR – pojedynczy wiersz poprzedzający bieżącą pozycję kursora.
W przypadku słów kluczowych I N lub FROM, należy wybrać jedno z nich.
PRZYKŁAD 2
FETCH 4 FROM wszyscy_pracownicy;
FETCH NEXT FROM wszyscy_pracownicy;
FETCH PRIOR FROM wszyscy_pracownicy;
FETCH NEXT FROM wszyscy_pracownicy;
PRZESUWANIE POZYCJI KURSORA
Kursor utrzymuje pozycję w zestawie wyników skojarzonej z nim instrukcji SELECT. Aby przemieścić go do określonej pozycji wiersza w określonym zestawie danych stosujemy polecenie: MOVE [ FORWARD | BACKWARD ]
[ # | ALL | NEXT | PRIOR ]
[ I N | FROM ] nazwa_kursora;
PRZYKŁAD 3
MOVE FORWARD 10 IN wszyscy_pracownicy;
3
EWSIE
28.11.2010
ZAMYKANIE KURSORA
CLOSE nazwa_kursora;
Kursor zostanie również zamknięty pośrednio, jeżeli blok transakcji, w którym kursor został
zdefiniowany, zostanie zatwierdzony za pomocą instrukcji COMMIT lub anulowany za pomocą instrukcji ROLLBACK.
PRZYKŁAD 4
CLOSE wszyscy_pracownicy;
COMMIT;
4