PL/SQL: Cursor

Aus Wikibooks

Wechseln zu: Navigation, Suche
Wikibooks buchseite.svg Zurück zu " Schleifen " | One wikibook.svg Hoch zu " Inhaltsverzeichnis " | Wikibooks buchseite.svg Vor zu " Exception-Handling"


[Bearbeiten] Implizierter cursor

Beispiel in einem anonymen Block:

declare
    v_user_id users.id%TYPE;
    v_username users.username%type;
begin
    -- implicit cursor
    SELECT id, username
    INTO v_user_id, v_username
    FROM users
    WHERE username='test';
 
    dbms_output.PUT_LINE('----------------------------');
    dbms_output.PUT_LINE('User-ID: '||v_user_id);
    dbms_output.PUT_LINE('Username: '||v_username);
    dbms_output.PUT_LINE('----------------------------');
end;

[Bearbeiten] Explizierter cursor

Beispiel in einem anonymen Block:

declare  
    CURSOR cur_users IS
        SELECT id, username, firstname, lastname
        FROM users;
    rec_users cur_users%ROWTYPE;
begin
    -- explicit cursor
    OPEN cur_users;
    LOOP
        FETCH cur_users INTO rec_users;
        EXIT WHEN cur_users%NOTFOUND;
 
        dbms_output.PUT_LINE('User-ID: '||rec_users.id);
        dbms_output.PUT_LINE('Username: '||rec_users.username);
        dbms_output.PUT_LINE('Firstname: '||rec_users.firstname);
        dbms_output.PUT_LINE('Lastname: '||rec_users.lastname);
        dbms_output.PUT_LINE('----------------------------');
    END LOOP;
end;


[Bearbeiten] Statusvariablen für Cursor

In einer Cursor-FOR-Schleife kann man die Anzahl der bereits gelesenen Sätze mit der Statusvariablen Rowcount abfragen. Diese Variable ist jedoch nur im Inneren der Schleife gültig. Wenn man sie außerhalb der Schleife verwendet, dann wird ein Syntaxfehler ausgegeben.

Beispiel

SET SERVEROUTPUT ON
DECLARE
CURSOR c IS
SELECT table_name 
FROM all_tables
WHERE ROWNUM <= 10
;
BEGIN
dbms_output.put_line('start');
-- gibt Fehler:
-- dbms_output.put_line('vor for i cursor rowcount=' || to_char(c%rowcount));
FOR i IN c LOOP
   dbms_output.put_line('cursor rowcount=' || to_char(c%rowcount));
END LOOP;
-- gibt Fehler:
-- dbms_output.put_line('nach end loop cursor rowcount=' || to_char(c%rowcount));
dbms_output.put_line('fertig');
END;
/
SHOW ERRORS

Das Programm hat folgende Ausgabe:

start
cursor rowcount=1
cursor rowcount=2
cursor rowcount=3
cursor rowcount=4
cursor rowcount=5
cursor rowcount=6
cursor rowcount=7
cursor rowcount=8
cursor rowcount=9
cursor rowcount=10
fertig
PL/SQL procedure successfully completed.
No errors.


Rowcount bei einem Cursor ausgeben

Die auskommentierten Zeilen ergeben eine Fehlermeldung, wenn sie ausgeführt werden sollen.

SET serveroutput ON
declare
cursor c IS
SELECT table_name 
FROM all_tables
WHERE rownum <= 1
;
name varchar2(100);
begin
dbms_output.put_line('start');
--dbms_output.put_line('c%found=' || case when c%found then 'TRUE' else 'FALSE' end);
--dbms_output.put_line('c%notfound=' || case when c%notfound then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%isopen=' || case when c%isopen then 'TRUE' else 'FALSE' end);
--dbms_output.put_line('c%rowcount=' || to_char(c%rowcount));
open c;
dbms_output.put_line('open c');
dbms_output.put_line('c%found=' || case when c%found then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%notfound=' || case when c%notfound then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%isopen=' || case when c%isopen then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%rowcount=' || to_char(c%rowcount));
fetch c INTO name;
dbms_output.put_line('fetch c');
dbms_output.put_line('c%found=' || case when c%found then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%notfound=' || case when c%notfound then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%isopen=' || case when c%isopen then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%rowcount=' || to_char(c%rowcount));
fetch c INTO name;
dbms_output.put_line('fetch c');
dbms_output.put_line('c%found=' || case when c%found then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%notfound=' || case when c%notfound then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%isopen=' || case when c%isopen then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%rowcount=' || to_char(c%rowcount));
fetch c INTO name;
dbms_output.put_line('fetch c');
dbms_output.put_line('c%found=' || case when c%found then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%notfound=' || case when c%notfound then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%isopen=' || case when c%isopen then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%rowcount=' || to_char(c%rowcount));
close c;
dbms_output.put_line('close c');
--dbms_output.put_line('c%found=' || case when c%found then 'TRUE' else 'FALSE' end);
--dbms_output.put_line('c%notfound=' || case when c%notfound then 'TRUE' else 'FALSE' end);
dbms_output.put_line('c%isopen=' || case when c%isopen then 'TRUE' else 'FALSE' end);
--dbms_output.put_line('c%rowcount=' || to_char(c%rowcount));
dbms_output.put_line('fertig');
end;
/
SHOW errors

Das Programm hat folgende Ausgabe:

start
c%isopen=FALSE
open c
c%found=FALSE
c%notfound=FALSE
c%isopen=TRUE
c%rowcount=0
fetch c
c%found=TRUE
c%notfound=FALSE
c%isopen=TRUE
c%rowcount=1
fetch c
c%found=FALSE
c%notfound=TRUE
c%isopen=TRUE
c%rowcount=1
fetch c
c%found=FALSE
c%notfound=TRUE
c%isopen=TRUE
c%rowcount=1
close c
c%isopen=FALSE
fertig
PL/SQL procedure successfully completed.
No errors.
Persönliche Werkzeuge