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:

  1. 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 die UPDATE 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.

  2. 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;
/


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow