Az implicit kurzor attribútumai

Az implicit kurzor attribútumai az INSERT, DELETE, UPDATE és SELECT INTO utasítások végrehajtásáról adnak információt. Az információ mindig a legutoljára végrehajtott utasításra vonatkozik. Mielőtt az Oracle megnyitja az implicit kurzort, az attribútumok értéke NULL.

%FOUND

Az utasítás végrehajtása alatt értéke NULL. Utána értéke TRUE, ha az INSERT, DELETE, UPDATE utasítás egy vagy több sort érintett, illetve a SELECT INTO legalább egy sort visszaadott. Különben értéke FALSE.

%ISOPEN

Az Oracle automatikusan lezárja az implicit kurzort az utasítás végrehajtása után, ezért értéke mindig FALSE.

%NOTFOUND

Értéke TRUE, ha az INSERT, DELETE, UPDATE egyetlen sorra sem volt hatással, illetve ha SELECT INTO nem adott vissza sort, egyébként FALSE.

%ROWCOUNT

Értéke az INSERT, DELETE, UPDATE utasítások által kezelt sorok darabszáma. A SELECT INTO utasítás esetén értéke 0, ha nincs visszaadott sor és 1, ha van. Ha a SELECT INTO utasítás egynél több sort ad vissza, akkor a TOO_MANY_ROWS kivétel váltódik ki. Ekkor tehát a %ROWCOUNT nem a visszaadott sorok tényleges számát tartalmazza.

Az implicit kurzor rendelkezik még két további attribútummal (%BULK_ROWCOUNT, %BULK_EXCEPTIONS), ezeket a 12. fejezetben tárgyaljuk.

Példák

BEGIN
  /* Az SQL-kurzor attribútumai, az SQL%ISOPEN kivételével
    NULL-t adnak vissza első híváskor. */
  IF SQL%FOUND IS NULL AND SQL%NOTFOUND IS NULL AND SQL%ROWCOUNT IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('Az attribútumok NULL-t adtak.');
  END IF;
  IF NOT SQL%ISOPEN THEN
    DBMS_OUTPUT.PUT_LINE('Az SQL%ISOPEN hamis.');
  END IF;

  /* Néhány könyvből utánpótlást kapott a könyvtár. */
  UPDATE konyv SET keszlet = keszlet + 5, szabad = szabad + 5
  WHERE id IN (45, 50);
  IF (SQL%FOUND) THEN
    DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' rekord módosítva.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Nincsenek ilyen könyveink.');
  END IF;

  /* Most nem létező könyveket adunk meg. */
  UPDATE konyv SET keszlet = keszlet + 5, szabad = szabad + 5
  WHERE id IN (-45, -50);
  IF (SQL%FOUND) THEN
    DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' rekord módosítva.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Nincsenek ilyen könyveink.');
  END IF;
  DECLARE
    i NUMBER;
  BEGIN
    /* Ez bizony sok lesz. */
    SELECT id INTO i FROM ugyfel
    WHERE id = id;
  EXCEPTION
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: ' || SQL%ROWCOUNT);
  END;
  DECLARE
    i NUMBER;
  BEGIN
    /* Iyen nem lesz. */
    SELECT id INTO i FROM ugyfel
    WHERE id < 0;
  EXCEPTION
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: ' || SQL%ROWCOUNT);
  END;
END;
/

/*
Eredmény:
Az attribútumok NULL-t adtak.
Az SQL%ISOPEN hamis.
2 rekord módosítva.
Nincsenek ilyen könyveink.
SQL%ROWCOUNT: 1
SQL%ROWCOUNT: 0

A PL/SQL eljárás sikeresen befejeződött.
*/

Implicit kurzor esetén külön figyelni kell arra, hogy az attribútum által visszaadott eredmény mindig az időben utolsó SQL műveletre vonatkozik:

DECLARE
  v_Temp NUMBER;
  /* Eljárás, ami implicit kurzort használ. */
  PROCEDURE alprg IS
    i NUMBER;
  BEGIN
    SELECT 1 INTO i FROM DUAL;
  END;
BEGIN
  /* Ez a DELETE nem töröl egy sort sem. */
  DELETE FROM konyv
  WHERE 1 = 2;

  /* Nem biztonságos használat! Az alprogramhívás megváltoztathatja az
  implicit attribútumok értékét, mert azok mindig a legutolsó
  SQL-utasításra vonatkoznak. */
  alprg;
  DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: ' || SQL%ROWCOUNT);
  /* Ez a DELETE nem töröl egy sort sem. */
  DELETE FROM konyv
  WHERE 1 = 2;

  /* Az a biztonságos, ha a szükséges attribútumok értékét
  ideiglenesen tároljuk. */
  v_Temp := SQL%ROWCOUNT;
  alprg;
  DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: ' || v_Temp);
END;
/

/* Eredmény:
SQL%ROWCOUNT: 1
SQL%ROWCOUNT: 0

A PL/SQL eljárás sikeresen befejeződött.
*/

A 8.1. táblázat azt összegzi, hogy az egyes kurzorattribútumok mit adnak vissza az OPEN, FETCH és CLOSE utasítások végrehajtása előtt és után.

8.1. táblázat - Kurzorattribútumok értékei

 

%FOUND

%ISOPEN

%NOTFOUND

%ROWCOUNT

OPEN

Előtt

Kivétel

FALSE

Kivétel

Kivétel

 

Után

NULL

TRUE

NULL

0

Első

FETCH

Előtt

NULL

TRUE NULL

0

 

Után

TRUE

TRUE

FALSE

1

Következő

FETCH(-ek)

Előtt

TRUE

RUE

FALSE

1

Után

TRUE

TRUE

FALSE

Az adatoktól függ

Utolsó FETCH

Előtt

TRUE

TRUE

FALSE

Az adatoktól függ

 

Után

FALSE

TRUE

TRUE

Az adatoktól függ

CLOSE

Előtt

FALSE

TRUE

TRUE

Az adatoktól függ

 

Után

Kivétel

FALSE

Kivétel

Kivétel

Megjegyzések:

  1. Az INVALID_CURSOR kivétel váltódik ki, ha a %FOUND, %NOTFOUND vagy %ROWCOUNT attribútumokra hivatkozunk a kurzor megnyitása előtt, vagy a kurzor lezárása után.

  2. Ha a kurzor nem adott vissza egy sort sem, akkor az első FETCH után a %FOUND értéke FALSE, a %NOTFOUND értéke TRUE, és a %ROWCOUNT értéke 0 lesz.