Szukaj…


Wprowadzenie

Dynamiczny SQL pozwala na skompletowanie kodu zapytania SQL w czasie wykonywania. Ta technika ma pewne wady i należy ją stosować bardzo ostrożnie. Jednocześnie pozwala na implementację bardziej złożonej logiki. PL / SQL wymaga, aby wszystkie obiekty użyte w kodzie istniały i były poprawne w czasie kompilacji. Dlatego nie można wykonywać instrukcji DDL bezpośrednio w PL / SQL, ale dynamiczny SQL pozwala na to.

Uwagi

Kilka ważnych uwag:

  1. Nigdy nie używaj konkatenacji ciągów, aby dodać wartości do zapytania, zamiast tego użyj parametrów. To jest źle:

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

    I to prawda:

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

    Istnieją dwa powody tego. Pierwszy to bezpieczeństwo. Łączenie ciągów pozwala na wstrzyknięcie SQL. W poniższym zapytaniu, jeśli zmienna będzie zawierać wartość 1 or 1 = 1 , instrukcja UPDATE zaktualizuje wszystkie wiersze w tabeli:

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

    Drugim powodem jest wydajność. Oracle będzie analizować zapytanie bez parametrów za każdym razem, gdy zostanie wykonane, podczas gdy zapytanie z parametrem zostanie przeanalizowane tylko raz w sesji.

  2. Zauważ, że gdy aparat bazy danych wykonuje instrukcję DDL, wykonuje wcześniej ukryte zatwierdzenie.

Wybierz wartość za pomocą dynamicznego SQL

Załóżmy, że użytkownik chce wybrać dane z różnych tabel. Tabela jest określana przez użytkownika.

 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;

Wywołaj tę funkcję jak zwykle:

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

Tabela do przetestowania:

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

Wstaw wartości do dynamicznego SQL

Przykład poniżej wstawia wartość do tabeli z poprzedniego przykładu:

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

Zaktualizuj wartości w dynamicznym SQL

Zaktualizujmy tabelę z pierwszego przykładu:

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

Wykonaj instrukcję DDL

Ten kod tworzy tabelę:

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

Wykonaj anonimowy blok

Możesz wykonać anonimowy blok. W tym przykładzie pokazano również, jak zwrócić wartość z dynamicznego 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow