Oracle PL/SQL Dynamic SQL Tutorial: Execute Immediate & DBMS_SQL
Was ist dynamisches SQL?
Dynamisch SQL ist eine Programmiermethode zum Generieren und Ausfรผhren von Anweisungen zur Laufzeit. Es wird hauptsรคchlich zum Schreiben universeller und flexibler Programme verwendet, in denen die SQL-Anweisungen zur Laufzeit basierend auf den Anforderungen erstellt und ausgefรผhrt werden.
Mรถglichkeiten, dynamisches SQL zu schreiben
PL/SQL bietet zwei Mรถglichkeiten, dynamisches SQL zu schreiben
- NDS โ Natives dynamisches SQL
- DBMS_SQL
NDS (Native Dynamic SQL) โ Sofort ausfรผhren
Native Dynamic SQL ist die einfachere Mรถglichkeit, dynamisches SQL zu schreiben. Es verwendet den Befehl โEXECUTE IMMEDIATEโ, um SQL zur Laufzeit zu erstellen und auszufรผhren. Um diese Methode zu verwenden, mรผssen jedoch der Datentyp und die Anzahl der Variablen, die zur Laufzeit verwendet werden sollen, vorher bekannt sein. Im Vergleich zu DBMS_SQL bietet es auch eine bessere Leistung und weniger Komplexitรคt.
Syntax
EXECUTE IMMEDIATE(<SQL>) [INTO<variable>] [USING <bind_variable_value>]
- Die obige Syntax zeigt den Befehl EXECUTE IMMEDIATE.
- Die Klausel INTO ist optional und wird nur verwendet, wenn das dynamische SQL eine SELECT-Anweisung enthรคlt, die Werte abruft. Der Variablentyp sollte mit dem Variablentyp der Select-Anweisung รผbereinstimmen.
- Die Klausel USING ist optional und wird nur verwendet, wenn das dynamische SQL eine Bindevariable enthรคlt.
Beispiel 1: In diesem Beispiel werden wir die Daten aus der emp-Tabelle fรผr emp_no โ1001โ mithilfe der NDS-Anweisung abrufen.
DECLARE
lv_sql VARCHAR2(500);
lv_emp_name VARCHAR2(50):
ln_emp_no NUMBER;
ln_salary NUMBER;
ln_manager NUMBER;
BEGIN
ly_sql:=;SELECT emp_name,emp_no,salary,manager FROM emp WHERE
emp_no=:empmo:;
EXECUTE IMMEDIATE lv_sql INTO lv_emp_name,ln_emp_no:ln_salary,ln_manager
USING 1001;
Dbms_output.put_line('Employee Name:โ||lv_emp_name);
Dbms_output.put_line('Employee Number:โ||ln_emp_no);
Dbms_output.put_line(โSalary:'||ln_salaiy);
Dbms_output.put_line('Manager ID:โ||ln_manager);
END;
/
Ausgang
Employee Name : XXX Employee Number: 1001 Salary: 15000 Manager ED: 1000
Code-Erklรคrung:
- Codezeile 2-6: Variablen deklarieren.
- Codezeile 8: Framing der SQL zur Laufzeit. SQL enthรคlt die Bind-Variable in der Where-Bedingung โ:empnoโ.
- Codezeile 9: Ausfรผhren des gerahmten SQL-Textes (was in Codezeile 8 erfolgt) mit dem NDS-Befehl โEXECUTE IMMEDIATEโ
- Die Variablen in der โINTOโ-Klausel (lv_emp_name, ln_emp_no, ln_salary, ln_manager) werden verwendet, um die aus der SQL-Abfrage abgerufenen Werte zu speichern (emp_name, emp_no, Gehalt, Manager).
- Die Klausel โUSINGโ gibt die Werte an die Bindevariable in der SQL-Abfrage (:emp_no) weiter.
- Codezeile 10-13: Anzeige der abgerufenen Werte.
DBMS_SQL fรผr dynamisches SQL
PL/SQL stellt das DBMS_SQL-Paket bereit, mit dem Sie mit dynamischem SQL arbeiten kรถnnen. Der Prozess zum Erstellen und Ausfรผhren des dynamischen SQL umfasst den folgenden Prozess.
- CURSOR รFFNEN: Das dynamische SQL wird auf die gleiche Weise ausgefรผhrt wie a Cursor. Um die SQL-Anweisung auszufรผhren, mรผssen wir also den Cursor รถffnen.
- SQL PARSE: Der nรคchste Schritt besteht darin, das dynamische SQL zu analysieren. Dieser Prozess รผberprรผft lediglich die Syntax und hรคlt die Abfrage zur Ausfรผhrung bereit.
- BIND VARIABLE-Werte: Der nรคchste Schritt besteht darin, die Werte fรผr Bindevariablen zuzuweisen, falls vorhanden.
- SPALTE DEFINIEREN: Der nรคchste Schritt besteht darin, die Spalte anhand ihrer relativen Positionen in der SELECT-Anweisung zu definieren.
- EXECUTE: Der nรคchste Schritt besteht darin, die analysierte Abfrage auszufรผhren.
- WERTE FETCH: Der nรคchste Schritt besteht darin, die ausgefรผhrten Werte abzurufen.
- CURSOR SCHLIESSEN: Sobald die Ergebnisse abgerufen wurden, sollte der Cursor geschlossen werden.
Beispiel 1: In diesem Beispiel werden wir die Daten aus der emp-Tabelle fรผr emp_no โ1001โ mithilfe der DBMS_SQL-Anweisung abrufen.
DECLARE lv_sql VARCHAR2(500); lv_emp_name VARCHAR2(50); ln_emp_no NUMBER; ln_salary NUMBER; ln_manager NUMBER; ln_cursor_id NUMBER; ln_rows_processed; BEGIN lv_sql:=โSELECT emp_name,emp_no,salary,manager FROM emp WHERE emp_no=:empmoโ; in_cursor_id:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(ln_cursor_id,lv_sql,DBMS_SQL.NATIVE); DBMS_SQL.BIXD_VARLABLE(ln_cursor_id,:โempnoโ,1001); DBMS_SQL.DEFINE_COLUMN(ln_cursor_ici,1,ln_emp_name); DBMS_SQL.DEFINE_COLUMN(ln_cursor_id,2,ln_emp_no); DBMS_SQL .DEFINE_COLUMN(ln_cursor_id,3,ln_salary); DBMS_SQL .DEFINE_COLUMN(ln_cursor_id,4,ln_manager); ln_rows__processed:=DBMS_SQL.EXECUTE(ln_cursor_id);
LOOP
IF DBMS_SQL.FETCH_ROWS(ln_cursor_id)=0
THEN
EXIT;
ELSE
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,1,lv_emp_name);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,2,ln_emp_no);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,3,In_salary);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,4,In_manager);
Dbms_output.put_line('Employee Name:โ||lv_emp_name);
Dbms_output.put_line('Employee Number:lโ||ln_emp_no);
Dbms_output.put_line(โSalary:โ||ln_salary);
Dbms_output.put_line('Manager ID :โ| ln_manager);
END IF;
END LOOP;
DBMS_SQL.CLOSE_ClIRSOR(ln_cursor_id);
END:
/
Ausgang
Employee Name:XXX Employee Number:1001 Salary:15000 Manager ID:1000
Code-Erklรคrung:
- Codezeile 1-9: Variable Aussage.
- Codezeile 10: Rahmen der SQL-Anweisung.
- Codezeile 11: รffnen des Cursors mit DBMS_SQL.OPEN_CURSOR. Es wird die Cursor-ID zurรผckgegeben, die geรถffnet wird.
- Codezeile 12: Nachdem der Cursor geรถffnet wurde, wird die SQL analysiert.
- Codezeile 13: Die Bind-Variable โ1001โ weist der Cursor-ID statt โ:empnoโ zu.
- Codezeile 14-17: Definieren des Spaltennamens basierend auf ihrer relativen Position in der SQL-Anweisung. In unserem Fall ist die relative Position (1) emp_name, (2) emp_no (3) Gehalt (4) Manager. Basierend auf dieser Position definieren wir die Zielvariable.
- Codezeile 18: Ausfรผhren der Abfrage mit DBMS_SQL.EXECUTE. Es gibt die Anzahl der verarbeiteten Datensรคtze zurรผck.
- Codezeile 19-33: Datensรคtze mithilfe einer Schleife abrufen und anzeigen.
- Codezeile 20: DBMS_SQL.FETCH_ROWS ruft einen Datensatz aus den verarbeiteten Zeilen ab. Es kann wiederholt aufgerufen werden, um alle Zeilen abzurufen. Wenn keine Zeilen abgerufen werden kรถnnen, gibt es 0 zurรผck und verlรคsst damit die Schleife.
Zusammenfassung
In diesem Abschnitt haben wir dynamisches SQL und die Mรถglichkeiten zur Ausfรผhrung von DYNAMIC SQL besprochen. Wir haben auch die unterschiedlichen Schritte bei der Ausfรผhrung des dynamischen SQL auf beide Arten gesehen. Wir haben auch Beispiele gesehen, in denen das gleiche Szenario sowohl auf NDS- als auch auf DBMS_SQL-Art gehandhabt wird, um die Ausfรผhrung zur Laufzeit durchzufรผhren.



