Oracle Database
Dynamiczny SQL
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:
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
, instrukcjaUPDATE
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.
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;
/