Oracle Database
SQL dinámico
Buscar..
Introducción
SQL dinámico le permite ensamblar un código de consulta SQL en el tiempo de ejecución. Esta técnica tiene algunas desventajas y debe ser usada muy cuidadosamente. Al mismo tiempo, le permite implementar una lógica más compleja. PL / SQL requiere que todos los objetos, utilizados en el código, tengan que existir y ser válidos en el momento de la compilación. Es por eso que no puede ejecutar sentencias DDL en PL / SQL directamente, pero SQL dinámico le permite hacer eso.
Observaciones
Algunas observaciones importantes:
Nunca use la concatenación de cadenas para agregar valores a la consulta, use parámetros en su lugar. Esto está mal:
execute immediate 'select value from my_table where id = ' || id_valiable into result_variable;
Y esto es correcto:
execute immediate 'select value from my_table where id = :P ' using id_valiable into result_variable;
Hay dos razones para esto. El primero es la seguridad. La concatenación de cadenas permite realizar inyecciones SQL. En la consulta a continuación, si una variable contendrá el valor
1 or 1 = 1
, la instrucciónUPDATE
actualizará todas las líneas de la tabla:execute immediate 'update my_table set value = ''I have bad news for you'' where id = ' || id;
La segunda razón es el rendimiento. Oracle analizará la consulta sin parámetros cada vez que se ejecute, mientras que la consulta con el parámetro se analizará solo una vez en la sesión.
Tenga en cuenta que cuando el motor de base de datos ejecuta una sentencia DDL, ejecuta un compromiso implícito antes.
Seleccionar valor con SQL dinámico
Digamos que un usuario quiere seleccionar datos de diferentes tablas. Una tabla es especificada por el usuario.
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;
Llame a esta función como de costumbre:
declare
table_name varchar2(30) := 'my_table';
id number := 1;
begin
dbms_output.put_line(get_value(table_name, id));
end;
Tabla a probar:
create table my_table (id number, column_value varchar2(100));
insert into my_table values (1, 'Hello, world!');
Insertar valores en SQL dinámico
El siguiente ejemplo inserta valor en la tabla del ejemplo anterior:
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;
/
Actualizar valores en SQL dinámico
Vamos a actualizar la tabla del primer ejemplo:
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;
/
Ejecutar sentencia DDL
Este código crea la tabla:
begin
execute immediate 'create table my_table (id number, column_value varchar2(100))';
end;
/
Ejecutar bloque anonimo
Puede ejecutar bloque anónimo. Este ejemplo muestra también cómo devolver valor desde SQL dinámico:
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;
/