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:

  1. 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ón UPDATE 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.

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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow