PL SQL dinámico
Consiste en la ejecución de sentencias SQL o bloques PL/SQL a partir de una cadena de texto montadas de manera dinámica.
El uso de execute immediate es muy cómodo para la construcción de sql dinámicos el problema es el parseo de estas sentencias. Las bind variables, evita parseos inecesarios. Para evitar SQL Injection en PL/SQL dinámico es importante utilizar bind variables en vez de concatenación de cadenas.
VENTAJAS:
- Creación de sentencias en tiempo de ejecución
- Interactivo con el usuario
- Acceder a objetos no existentes en tiempo de compilación
- Gestión de permisos de usuarios de forma dinámica
- Permite ejecutar instrucciones DDL (create, alter, drop, grant, …)
DESVENTAJAS:
- No siempre se forman las consultas más optimas
- Problemas de seguridad por ataques de inyección SQL
SINTAXIS:
EXECUTE IMMEDIATE es el sustituto del paquete DBMS_SQL
EXEC SQL EXECUTE IMMEDIATE cadena_txt [INTO {variable, ...|registro}] [USING {IN|OUT|INOUT} argumento ...] [{RETURNING|RETURN} INTO argumento, ...]
cadena_txt: instrucción SQL o bloque PL/SQL
variable: variable donde se guarda el valor de la columna seleccionada
registro: variable estructurada, en la que se obtiene una fila
EJEMPLOS:
Ejemplo de update utilizando bind variables:
DECLARE reg_actualizados NUMBER; sql_str VARCHAR2(100); nombre VARCHAR2(20) := 'Pepe'; codigo NUMBER(5) := 5; BEGIN sql_str := 'UPDATE DATOS SET NOMBRE = :nombre ' ||' WHERE CODIGO = :codigo'; EXECUTE IMMEDIATE sql_str USING nombre, codigo; reg_actualizados := SQL%ROWCOUNT; dbms_output.put_line('Se han actualizado '||TO_CHAR(reg_actualizados)||' registros'); END;
Ejemplo utilización en cursores utilizando bind variables:
DECLARE TYPE cur_typ IS REF CURSOR; c_cursor CUR_TYP; fila nombres%ROWTYPE; v_query VARCHAR2(255); co_nombre VARCHAR2(3) := 'JDF'; BEGIN v_query := 'SELECT * FROM nombres WHERE co_nombre = :cnombre'; OPEN c_cursor FOR v_query USING co_nombre; LOOP FETCH c_cursor INTO fila; EXIT WHEN c_cursor%NOTFOUND; dbms_output.put_line(fila.DESCRIPCION); END LOOP; CLOSE c_cursor; END;
Comments are closed.