Kursory

Kursory FOR UPADTE

Aby modyfikować zawartość kursora (bieżący wiersz) podczas jego przetwarzania, można skorzystać z klauzuli CURRENT OF;


FOR zmienna_kursorowa IN nazwa_kursora LOOP
  ...
  UPDATE tabela1 
     SET kol1 = v1
        ,kol2 = v2
   WHERE CURRENT OF nazwa_kursora;
  ...
END LOOP;
                        

W tym celu należy wcześniej podczas deklaracji kursora dołożyć po zapytaniu klauzule FOR UPDATE, która powoduje założenie blokady na wiersze objęte kursorem.


DECLARE
  ...
  CURSOR nazwa_kursora IS
    wyrażenie_select
    FOR UPDATE;
BEGIN
                        

Jeżeli kursor jest zadeklarowany jako FOR UPDATE, to wykonanie instrukcji COMMIT lub ROLLBACK podczas jego przetwarzanie powoduje uszkodzenie tego kursora.

Kursory jawne i niejawne

Kursory, o których była mowa dotychczas, to tzw. kursory jawne, ponieważ jawnie je definiujemy. Oprócz tych jawnych kursorów mogą istnieć kursory niejawne powodowane wykonaniem się instrukcji UPDATE lub DELETE. Powodują one również chwilowe otwarcie kursora na czas wykonania się operacji. W ten sposób niejawnie otwarte kursory również posiadają swoje atrybuty. Możemy się do nich odwoływać tuż po wykonaniu się operacji UPDATE lub DELETE korzystając z wyrażenia: SQL%atrybut

Przykład


DECLARE
  v_ile number;
BEGIN
  UPDATE emp
     SET sal = sal+1000
   WHERE job = ‘MANAGER’;
  v_ile := SQL%rowcount; -- ilość zmodyfikowanych wierszy
END;
                        

Kursory dynamiczne

Kursory dynamiczne pozwalają przetwarzać kursory oparte na dynamicznie definiowanych zapytaniach. Zapytanie, które będzie wybierać wiersze podczas otwarcia kursora nie musi być znane podczas implementowania kodu PL/SQL.

Aby korzystać z dynamicznych kursorów, należy najpierw zdefiniować odpowiedni typ referencyjny.


TYPE nazwa_typu IS REF CURSOR [RETURN typ_rekordowy];
                        

Następnie zmienną tego typu.

zmienna_referencyjna nazwa_typu;

Również otwarcie kursora dynamicznego różni się od otwarcia kursora statycznego.


OPEN zmienna_referencyjna FOR
  instrukcja_select | zmienna;
                        

Przykład


DECLARE
  TYPE t_ref IS REF CURSOR;
  v_cur t_ref;
  v_sel varchar2(256);
  v_kol1 number;
  v_kol2 number;
BEGIN
  SELECT ‘SELECT ’||kolumna1||’, ’||kolumna2||’ FROM ‘||tabela
    INTO v_sel;
    FROM zapytania;
  OPEN v_cur FOR v_sel;
  LOOP
    FETCH v_cur INTO v_kol1, v_kol2;
    EXIT WHEN v_cur%NOTFOUND;
    ...
  END LOOP;
  CLOSE v_cur;
END;