Oracle Database
SQL dinamico
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:
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'istruzioneUPDATE
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.
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;
/