Ricerca…


introduzione

Dynamic SQL consente di assemblare un codice di query SQL nel runtime. Questa tecnica ha alcuni svantaggi e deve essere usata con molta attenzione. Allo stesso tempo, consente di implementare una logica più complessa. PL / SQL richiede che tutti gli oggetti, utilizzati nel codice, debbano esistere e che siano validi al momento della compilazione. Ecco perché non è possibile eseguire istruzioni DDL direttamente in PL / SQL, ma SQL dinamico consente di farlo.

Osservazioni

Alcune importanti osservazioni:

  1. Non utilizzare mai concatenazioni di stringhe per aggiungere valori alla query, utilizzare invece i parametri. Questo è sbagliato:

    execute immediate 'select value from my_table where id = ' || 
         id_valiable into result_variable;
    

    E questo è giusto:

    execute immediate 'select value from my_table where id = :P '
        using id_valiable into result_variable;
    

    Ci sono due ragioni per questo. Il primo è la sicurezza. La concatenazione di stringhe consente di eseguire l'iniezione SQL. Nella query seguente, se una variabile conterrà il valore 1 or 1 = 1 , l'istruzione UPDATE aggiornerà tutte le righe nella tabella:

    execute immediate 'update my_table set value = ''I have bad news for you'' where id = ' || id;
    

    La seconda ragione è la prestazione. Oracle analizzerà la query senza parametri ogni volta che viene eseguita, mentre la query con parametro verrà analizzata solo una volta nella sessione.

  2. Si noti che quando il motore di database esegue un'istruzione DDL, esegue prima il commit implicito.

Seleziona il valore con SQL dinamico

Supponiamo che un utente desideri selezionare i dati da tabelle diverse. Una tabella è specificata dall'utente.

 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;

Chiama questa funzione come al solito:

declare
  table_name varchar2(30) := 'my_table';
  id number := 1;
begin
  dbms_output.put_line(get_value(table_name, id));
end;

Tabella da testare:

create table my_table (id number, column_value varchar2(100));
insert into my_table values (1, 'Hello, world!');

Inserisci valori in SQL dinamico

L'esempio seguente inserisce il valore nella tabella dell'esempio precedente:

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

Aggiorna valori in SQL dinamico

Aggiorniamo la tabella dal primo esempio:

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

Esegui la dichiarazione DDL

Questo codice crea la tabella:

begin
  execute immediate 'create table my_table (id number, column_value varchar2(100))';
end;
/

Esegui blocco anonimo

Puoi eseguire un blocco anonimo. Questo esempio mostra anche come restituire il valore dall'SQL dinamico:

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow