Oracle Database
Dynamisches SQL
Suche…
Einführung
Mit Dynamic SQL können Sie einen SQL-Abfragecode zur Laufzeit zusammenstellen. Diese Technik hat einige Nachteile und muss sehr sorgfältig angewendet werden. Gleichzeitig können Sie komplexere Logik implementieren. PL / SQL erfordert, dass alle im Code verwendeten Objekte zum Zeitpunkt der Kompilierung vorhanden und gültig sein müssen. Aus diesem Grund können Sie DDL-Anweisungen nicht direkt in PL / SQL ausführen. Dynamisches SQL ermöglicht dies jedoch.
Bemerkungen
Einige wichtige Anmerkungen:
Verwenden Sie niemals Zeichenfolgenverkettung, um Werte zur Abfrage hinzuzufügen. Verwenden Sie stattdessen Parameter. Das ist falsch:
execute immediate 'select value from my_table where id = ' || id_valiable into result_variable;
Und das ist richtig:
execute immediate 'select value from my_table where id = :P ' using id_valiable into result_variable;
Dafür gibt es zwei Gründe. Der erste ist die Sicherheit. String-Verkettung ermöglicht die SQL-Injection. Wenn in der folgenden Abfrage eine Variable den Wert
1 or 1 = 1
, aktualisiert dieUPDATE
Anweisung alle Zeilen in der Tabelle:execute immediate 'update my_table set value = ''I have bad news for you'' where id = ' || id;
Der zweite Grund ist die Leistung. Oracle analysiert die Abfrage bei jeder Ausführung ohne Parameter, während die Abfrage mit dem Parameter in der Sitzung nur einmal analysiert wird.
Beachten Sie, dass das Datenbankmodul beim Ausführen einer DDL-Anweisung zuvor ein implizites Commit ausführt.
Wählen Sie einen Wert mit dynamischem SQL
Angenommen, ein Benutzer möchte Daten aus verschiedenen Tabellen auswählen. Eine Tabelle wird vom Benutzer angegeben.
function get_value(p_table_name varchar2, p_id number) return varchar2 is
value varchar2(100);
begin
execute immediate 'select column_value from ' || p_table_name ||
' where id = :P' into value using p_id;
return value;
end;
Rufen Sie diese Funktion wie gewohnt auf:
declare
table_name varchar2(30) := 'my_table';
id number := 1;
begin
dbms_output.put_line(get_value(table_name, id));
end;
Tabelle zum Testen:
create table my_table (id number, column_value varchar2(100));
insert into my_table values (1, 'Hello, world!');
Werte in dynamisches SQL einfügen
Das folgende Beispiel fügt einen Wert aus dem vorherigen Beispiel in die Tabelle ein:
declare
query_text varchar2(1000) := 'insert into my_table(id, column_value) values (:P_ID, :P_VAL)';
id number := 2;
value varchar2(100) := 'Bonjour!';
begin
execute immediate query_text using id, value;
end;
/
Aktualisieren Sie die Werte in dynamischem SQL
Lassen Sie uns die Tabelle aus dem ersten Beispiel aktualisieren:
declare
query_text varchar2(1000) := 'update my_table set column_value = :P_VAL where id = :P_ID';
id number := 2;
value varchar2(100) := 'Bonjour le monde!';
begin
execute immediate query_text using value, id;
end;
/
DDL-Anweisung ausführen
Dieser Code erstellt die Tabelle:
begin
execute immediate 'create table my_table (id number, column_value varchar2(100))';
end;
/
Anonymen Block ausführen
Sie können eine anonyme Sperre ausführen. Dieses Beispiel zeigt auch, wie ein Wert aus dynamischem SQL zurückgegeben wird:
declare
query_text varchar2(1000) := 'begin :P_OUT := cos(:P_IN); end;';
in_value number := 0;
out_value number;
begin
execute immediate query_text using out out_value, in in_value;
dbms_output.put_line('Result of anonymous block: ' || to_char(out_value));
end;
/