Oracle Database
Dynamisk SQL
Sök…
Introduktion
Med dynamisk SQL kan du montera en SQL-frågekod under körtiden. Denna teknik har vissa nackdelar och måste användas mycket noggrant. Samtidigt gör det möjligt att implementera mer komplex logik. PL / SQL kräver att alla objekt som används i koden måste existera och vara giltiga vid sammanställningstiden. Det är därför du inte kan utföra DDL-uttalanden i PL / SQL direkt, men med dynamisk SQL kan du göra det.
Anmärkningar
Några viktiga kommentarer:
Använd aldrig strängkoppling för att lägga till värden i frågan, använd parametrar istället. Detta är fel:
execute immediate 'select value from my_table where id = ' || id_valiable into result_variable;
Och det här är rätt:
execute immediate 'select value from my_table where id = :P ' using id_valiable into result_variable;
Det finns två skäl till detta. Den första är säkerheten. Strängen sammankoppling gör det möjligt att göra SQL-injektion. I frågan nedan, om en variabel kommer att innehålla värdet
1 or 1 = 1
, uppdaterarUPDATE
uttalandet alla rader i tabellen:execute immediate 'update my_table set value = ''I have bad news for you'' where id = ' || id;
Det andra skälet är prestanda. Oracle kommer att analysera frågan utan parametrar varje gång den körs, medan fråga med parameter kommer att analyseras endast en gång i sessionen.
Observera att när databasmotorn kör ett DDL-uttalande, utför den implicita åtaganden innan.
Välj värde med dynamisk SQL
Låt oss säga att en användare vill välja data från olika tabeller. En tabell specificeras av användaren.
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;
Ring den här funktionen som vanligt:
declare
table_name varchar2(30) := 'my_table';
id number := 1;
begin
dbms_output.put_line(get_value(table_name, id));
end;
Tabell att testa:
create table my_table (id number, column_value varchar2(100));
insert into my_table values (1, 'Hello, world!');
Infoga värden i dynamisk SQL
Exempel nedan sätter in värde i tabellen från föregående exempel:
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;
/
Uppdatera värden i dynamisk SQL
Låt oss uppdatera tabellen från det första exemplet:
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;
/
Kör DDL-uttalande
Den här koden skapar tabellen:
begin
execute immediate 'create table my_table (id number, column_value varchar2(100))';
end;
/
Kör anonymt block
Du kan köra anonymt block. Detta exempel visar också hur du returnerar värde från dynamisk SQL:
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;
/