PL-SQL: DML-Befehle

Aus Wikibooks


Im Anweisungsteil eines PL/SQL-Programms können DML-Befehle ausgeführt werden.

SELECT[Bearbeiten]

Mit dem Select-Befehl werden Daten aus einer Tabelle oder View gelesen. Die Ergebnisse werden in PL/SQL-Variablen gespeichert. Dabei sind grundsätzlich zwei Fälle zu unterscheiden:

1. Es wird ein Select-Befehl verwendet, der entweder keinen oder maximal einen Satz als Ergebnis liefern kann.

2. Ein Select-Befehl kann auch mehrere Sätze als Ergebnis liefern.

Select-Befehl, der maximal einen Satz liefern kann[Bearbeiten]

Select-Befehle, die maximal einen Datensatz lesen, sind meistens Zugriffe über den Primärschlüssel einer Tabelle. Dabei kann man entweder für jede Spalte des Ergebnissatzes eine einzelne Variable angeben oder eine Struktur angeben, in die die gelesenen Werte eingetragen werden.

Beispiel für die Verwendung einzelner Variablen:

Für jede Spalte, die durch das Select-Statement gelesen wird, muss eine Variable bereitgestellt werden.

SET SERVEROUTPUT ON
DECLARE 
nachname varchar2(100);
beruf varchar2(100);
gehalt number;
BEGIN
   SELECT ename, job, sal
   INTO nachname, beruf, gehalt
   FROM scott.emp
   WHERE empno = 7566
   ;
   dbms_output.put_line('Nachname=' || nachname);
   dbms_output.put_line('Beruf=' || beruf);
   dbms_output.put_line('Gehalt=' || to_char(gehalt));
END;
/
SHOW ERRORS

Das Programm gibt folgendes Ergebnis aus:

Nachname=JONES
Beruf=MANAGER
Gehalt=2975

PL/SQL-Prozedur erfolgreich abgeschlossen.

SQL> SHOW ERRORS
Keine Fehler.

Beispiel für die Verwendung einer Struktur:

SET SERVEROUTPUT ON
DECLARE 
emp_rec scott.emp%ROWTYPE;
BEGIN
   SELECT *
   INTO emp_rec
   FROM scott.emp
   WHERE empno = 7566
   ;
   dbms_output.put_line('Ename=' || emp_rec.ename);
   dbms_output.put_line('Job=' || emp_rec.job);
   dbms_output.put_line('Sal=' || to_char(emp_rec.sal));
END;
/
SHOW ERRORS

Das Programm gibt folgendes Ergebnis aus:

Ename=JONES
Job=MANAGER
Sal=2975

PL/SQL-Prozedur erfolgreich abgeschlossen.

SQL> show errors
Keine Fehler.

Wenn kein Satz gefunden werden kann, dann wird eine Fehlermeldung ausgegeben.

Select-Befehl, der mehrere Sätze liefern kann[Bearbeiten]

Wenn ein Select-Befehl verwendet wird, der auch mehr als einen einzigen Satz lesen kann, dann gibt es mehrere Möglichkeiten.

1. kann man mit einem Cursor arbeiten. Siehe Kapitel Cursor.

2. man kann auch alle Sätze in eine PL/SQL-Struktur einlesen

Beispiel für einen Bulk-Select

...

INSERT, UPDATE, DELETE[Bearbeiten]

Angenommen, es existiert eine Tabelle t_test mit folgender Definition:

CREATE TABLE t_test (i NUMBER);

Dann kann man die Daten, die in dieser Tabelle gespeichert werden, mit dem folgenden PL/SQL-Programm verändern:

BEGIN
INSERT INTO t_test VALUES(1);
INSERT INTO t_test VALUES(2);
UPDATE t_test SET i = 3;
DELETE FROM t_test;
COMMIT;
END;
/
SHOW ERRORS

Durch den Befehl COMMIT werden die Änderungen endgültig und die geänderten Sätze können auch von anderen Sessions gelesen oder weiter verändert werden.

Man hat auch die Möglichkeit, mit dem Befehl ROLLBACK die letzten Änderungen wieder zurückzunehmen. Das geht aber nur dann, wenn die Änderungen noch nicht mit COMMIT freigegeben wurden.

Vordefinierte Statusvariablen[Bearbeiten]

Es kann sein, dass ein DML-Befehl keinen Satz findet der gelesen, geändert oder gelöscht werden kann. Um sich zu vergewissern, ob ein Satz gefunden wurde, gibt es die vordefinierte Variable sql%rowcount.

SET SERVEROUTPUT ON
BEGIN
dbms_output.put_line('start');
INSERT INTO t_test values(1);
dbms_output.put_line('insert rowcount=' || to_char(sql%rowcount));
INSERT INTO t_test values(1);
dbms_output.put_line('insert rowcount=' || to_char(sql%rowcount));
UPDATE t_test SET i = 3;
dbms_output.put_line('update rowcount=' || to_char(sql%rowcount));
DELETE FROM t_test;
dbms_output.put_line('delete rowcount=' || to_char(sql%rowcount));
COMMIT;
dbms_output.put_line('fertig');
END;
/
SHOW ERRORS

Das Programm ergibt folgende Ausgabe

start
insert rowcount=1
insert rowcount=1
update rowcount=2
delete rowcount=2
fertig
PL/SQL procedure successfully completed.
No errors.