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:

  1. 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 , uppdaterar UPDATE 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.

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow