Oracle Database
SQL dynamique
Recherche…
Introduction
SQL dynamique vous permet d'assembler un code de requête SQL dans l'environnement d'exécution. Cette technique présente certains inconvénients et doit être utilisée très soigneusement. Dans le même temps, il vous permet de mettre en œuvre une logique plus complexe. PL / SQL exige que tous les objets, utilisés dans le code, doivent exister et être valides au moment de la compilation. C'est pourquoi vous ne pouvez pas exécuter les instructions DDL directement dans PL / SQL, mais SQL dynamique vous permet de le faire.
Remarques
Quelques remarques importantes:
N'utilisez jamais la concaténation de chaîne pour ajouter des valeurs à la requête, utilisez plutôt des paramètres. C'est faux:
execute immediate 'select value from my_table where id = ' || id_valiable into result_variable;
Et c'est juste:
execute immediate 'select value from my_table where id = :P ' using id_valiable into result_variable;
Il y a deux raisons à cela. Le premier est la sécurité. La concaténation de chaînes permet d'effectuer une injection SQL. Dans la requête ci-dessous, si une variable contient la valeur
1 or 1 = 1
, l'instructionUPDATE
à jour toutes les lignes de la table:execute immediate 'update my_table set value = ''I have bad news for you'' where id = ' || id;
La deuxième raison est la performance. Oracle analysera les requêtes sans paramètres à chaque exécution, tandis que la requête avec paramètre sera analysée une seule fois dans la session.
Notez que lorsque le moteur de base de données exécute une instruction DDL, il exécute une validation implicite avant.
Sélectionnez une valeur avec SQL dynamique
Supposons qu'un utilisateur souhaite sélectionner des données provenant de différentes tables. Une table est spécifiée par l'utilisateur.
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;
Appelez cette fonction comme d'habitude:
declare
table_name varchar2(30) := 'my_table';
id number := 1;
begin
dbms_output.put_line(get_value(table_name, id));
end;
Tableau à tester:
create table my_table (id number, column_value varchar2(100));
insert into my_table values (1, 'Hello, world!');
Insérer des valeurs dans SQL dynamique
L'exemple ci-dessous insère de la valeur dans le tableau de l'exemple précédent:
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;
/
Mettre à jour les valeurs en SQL dynamique
Mettons à jour la table du premier exemple:
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;
/
Exécuter l'instruction DDL
Ce code crée la table:
begin
execute immediate 'create table my_table (id number, column_value varchar2(100))';
end;
/
Exécuter un bloc anonyme
Vous pouvez exécuter un bloc anonyme. Cet exemple montre également comment renvoyer une valeur à partir d'un SQL dynamique:
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;
/