pl-sql
propósito
- notas sobre
pl/sql
objetivos
- plantilla de paquete, función, y procedimiento con tratamiento de errores
- una ayuda por pantalla que con el menú genérico muestre una que se llama con el nombre de la pantalla como parámetro de forma que muestra desde base de datos lo que se quiere mostrar en la ayuda
- ver el fallo del trigger sobre la tabla
AUD
cuando la tabla esta vacía. - la parte general del paquete plantilla sacarla a otro paquete por ejemplo utilidades.
- llevar estos paquetes a un repositorio privado en Bitbucket junto con lo de las gráficas
- entender la inyección de dependencias y ver como aplicarlo a los programas del curro
plantilla de paquete
- en el esquema de la aplicacion base
gab
paquete de propósito general
- general a todos los proyectos SIGI
ref cursor
- los ref cursores
-- DESDE SQL PLUS
SQL> conn gab/desarrollo@xe
Connected.
SQL> SHOW USER
USER is "GAB"
SQL> VAR RC REFCURSOR;
SQL> exec :rc := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1);
PL/SQL procedure successfully completed.
SQL> print rc
GAB_ALUMNO
--------------------------------------------------
GAB_DESCRIPCION
--------------------------------------------------------------------------------
ALUMNO1
DESCRIPCION DEL ALUMNO 1
ALUMNO2
DESCRIPCION DEL ALUMNO 2
ALUMNO3
DESCRIPCION DEL ALUMNO 3
SQL> print rc
SP2-0625: Error printing variable "rc"
SQL>
- el
ref cursor
no contiene los datos resultado de la consulta sino que contiene un puntero a la consulta y por eso el segundoprint
da error - el primer
print
funciona porqueSQL Plus
mira el cursor de referencia y ve que es un cursor abierto pues la sentencia no lo cierra. - Entra en el bucle, obteniendo cada fila de datos de la base de datos, utilizando el cursor de referencia como referencia (puntero) a la consulta relevante, y mostrando cada fila de datos hasta que no tenía más filas para recuperar.
- Una vez que se han obtenido todas las filas, cierra el cursor.
SQL> ed
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Alumnos: '||c_alumnos%ROWCOUNT);
close c_alumnos;
end;
SQL> /
Alumnos: 0
PL/SQL procedure successfully completed.
- sale 0 a pesar de que existen 3 alumnos por que
c_alumnos%ROWCOONT
muestra el número de fila leídas a través del cursos y no hemos leído ninguna.
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
v_id_alumno varchar2(50);
v_descripcion varchar2(200);
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Pre Fetch: Alumnos: '||c_alumnos%ROWCOUNT);
fetch c_alumnos into v_id_alumno, v_descripcion;
dbms_output.put_line('Post Fetch: Rows: '||c_alumnos%ROWCOUNT);
close c_alumnos;
end;
SQL> /
Pre Fetch: Alumnos: 0
Post Fetch: Rows: 1
PL/SQL procedure successfully completed.
- ahora sí que ha leído una fila del cursor.
SQL> ed
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
v_id_alumno varchar2(50);
v_descripcion varchar2(200);
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Pre Fetch: Alumnos: '||c_alumnos%ROWCOUNT);
loop
fetch c_alumnos into v_id_alumno, v_descripcion;
exit when c_alumnos%NOTFOUND;
dbms_output.put_line('Post Fetch: Rows: '||c_alumnos%ROWCOUNT||' '||v_id_alumno||' '||v_descripcion);
end loop;
close c_alumnos;
end;
SQL> /
Pre Fetch: Alumnos: 0
Post Fetch: Rows: 1 ALUMNO1 DESCRIPCION DEL ALUMNO 1
Post Fetch: Rows: 2 ALUMNO2 DESCRIPCION DEL ALUMNO 2
Post Fetch: Rows: 3 ALUMNO3 DESCRIPCION DEL ALUMNO 3
PL/SQL procedure successfully completed.
-- DESDE EPACF
/* Formatted on 18/12/2017 10:12:13 (QP5 v5.287) */
DECLARE
RetVal EPACF.EPACF_PCK_ACTO_CANDIDATO_VAC.cursorActos;
P_ID_CURSO NUMBER;
P_ID_ACTO NUMBER;
P_ID_VACANTE NUMBER;
V_DTP_NIF VARCHAR2( 200 );
V_DTP_NOMBRE VARCHAR2( 200 );
V_DTP_APELLIDO1 VARCHAR2( 200 );
V_DTP_APELLIDO2 VARCHAR2( 200 );
V_DTP_FECHA_NACIMIENTO VARCHAR2( 200 );
V_DTP_TELEFONO VARCHAR2( 200 );
V_DTP_EMAIL VARCHAR2( 200 );
V_ACF_ID_COLECTIVO VARCHAR2( 200 );
V_ACF_DESCRIPCION VARCHAR2( 200 );
V_ACF_TIPO_RESOLUCION VARCHAR2( 200 );
V_ACF_DESC_TIPO_RESOLUCION VARCHAR2( 200 );
V_DTM_GESTOR VARCHAR2( 200 );
V_DTM_DESC_GESTOR VARCHAR2( 200 );
V_ACF_ID_ESTADO VARCHAR2( 200 );
V_ACF_DESC_ESTADO VARCHAR2( 200 );
BEGIN
P_ID_CURSO := 2017;
P_ID_ACTO := 1;
P_ID_VACANTE := 10003;
RetVal :=
EPACF.EPACF_PCK_ACTO_CANDIDATO_VAC.F_OBTENER_ACTO_CANDIDATOS_VAC
(
P_ID_CURSO,
P_ID_ACTO,
P_ID_VACANTE
);
DBMS_OUTPUT.PUT_LINE
(
'El resultado ' || RETVAL%ROWCOUNT
);
LOOP
FETCH RETVAL
INTO V_DTP_NIF,
V_DTP_NOMBRE,
V_DTP_APELLIDO1,
V_DTP_APELLIDO2,
V_DTP_FECHA_NACIMIENTO,
V_DTP_TELEFONO,
V_DTP_EMAIL,
V_ACF_ID_COLECTIVO,
V_ACF_DESCRIPCION,
V_ACF_TIPO_RESOLUCION,
V_ACF_DESC_TIPO_RESOLUCION,
V_DTM_GESTOR,
V_DTM_DESC_GESTOR,
V_ACF_ID_ESTADO,
V_ACF_DESC_ESTADO;
EXIT WHEN RETVAL%NOTFOUND;
DBMS_OUTPUT.PUT_LINE
(
'El resultado '
|| RETVAL%ROWCOUNT
|| ' '
|| V_DTP_NIF
|| ' V_DTP_NIF '
|| V_DTP_NOMBRE
|| ' V_DTP_NOMBRE '
|| V_DTP_APELLIDO1
|| ' V_DTP_APELLIDO1 '
|| V_DTP_APELLIDO2
|| ' V_DTP_APELLIDO2 '
|| V_DTP_FECHA_NACIMIENTO
|| ' V_DTP_FECHA_NACIMIENTO '
|| V_DTP_TELEFONO
|| ' V_DTP_TELEFONO '
|| V_DTP_EMAIL
|| ' V_DTP_EMAIL '
|| V_ACF_ID_COLECTIVO
|| ' V_ACF_ID_COLECTIVO '
|| V_ACF_DESCRIPCION
|| ' V_ACF_DESCRIPCION '
|| V_ACF_TIPO_RESOLUCION
|| ' V_ACF_TIPO_RESOLUCION '
|| V_ACF_DESC_TIPO_RESOLUCION
|| ' V_ACF_DESC_TIPO_RESOLUCION '
|| V_DTM_GESTOR
|| ' V_DTM_GESTOR '
|| V_DTM_DESC_GESTOR
|| ' V_DTM_DESC_GESTOR '
|| V_ACF_ID_ESTADO
|| ' V_ACF_ID_ESTADO '
|| V_ACF_DESC_ESTADO
);
END LOOP;
--COMMIT;
END;
de esta forma se lee el contenido del cursor
- funciona tanto en
SQL
como desde elTOAD
- funciona tanto en
ver una forma rápida de sacar la información que retorna una función con un
refcursor
con muchos campos.- ¿sacando los campos de la
select
que crea el cursor? EER * [Error] Execution (2: 1): ORA-06504: PL/SQL: Los tipos de retorno de variables de juego de resultados o la consulta no coinciden ORA-06512: en línea 123
- ¿sacando los campos de la
forma sencilla
- la forma más sencilla es ejecutando cualquiera de esta select sobre funciones que retornan refcursores
-- DESDE GAB
select gab.gab_pck_adm_permiso.f_obtener_permisos_usuario ('jiranzo') from dual;
-- DESDE EPACF
SELECT EPACF.EPACF_PCK_ACTO.F_OBTENER_ACTOS_ACTIVOS FROM DUAL;
SELECT EPACF.EPACF_PCK_ACTO_CANDIDATO_COL_6.F_OBTENER_ACTO_CANDIDATOS_COL(2017,6,6,'PROVISIONAL') FROM DUAL;
- luego doble click donde pone (CURSOR)
lanzarlo directamente sobre el editor en Toad
para procedimientos que tiene un
REFCURSOR
como parámetro de salida se puede usar este sistema
create or replace function f_refcur return sys_refcursor
is
v_refcur sys_refcursor;
Begin
v_refcur := gab.gab_pck_adm_permiso.f_obtener_permisos_usuario ('jiranzo');
return v_refcur;
End;
select f_refcur from dual;
select gab.gab_pck_adm_permiso.f_obtener_permisos_usuario ('jiranzo') from dual;
- una vez que tenemos el contenido del
REFCURSOR
podemos seleccionar todas las columnas en la salida
spool
- para crearlo desde PL/SQL
Developer
Archivo / Nuevo / ventana de comandos configuración de spool
para configurar una salida y generar por ejemplo un conjunto de
inserts
spool c:\inicio\ficheroSpool.sql
SET HEADING OFF
SET FEEDBACK OFF
SET LINESIZE 1000
SET TERMOUT OFF -- anula la salida por pantalla lo que reduce el tiempo de creación del fichero
PROMPT SET TERMOUT OFF
SELECT 'insert into T_PET (cod_cue, cod_esp, pos_can, nif, nombre, pos_pet,vac, EST_PET,num_fila) values (''' || P.COD_CUE || ''' , ''' || P.COD_ESP || ''' , ' ||POS_CAN || ' , ''' || P.NIF || ''' , ''' || P.NOMBRE || ''' , ' ||POS_PET || ' , ' || VAC || ' , ' || 0 || ' , ' || NUM_FILA || ' );' || DECODE(MOD(ROWNUM, 10), 0, CHR(10) || 'COMMIT;', NULL) FROM T_PET P WHERE P.NUM_FILA < 11 ORDER BY P.NUM_FILA
/
spool off
- lleva incluido el commit cada 11 filas
el fichero generado lleva la opción de anular la salida por pantalla
otras opciones de spool por explorar
SET HEADING OFF
SET FEEDBACK OFF
SET SERVEROUTPUT ON SIZE 1000000
SET PAGESIZE 0
SET FEEDBACK OFF
SET LINESIZE 4096
SET VERIFY OFF
SET TERMOUT OFF -- anula la salida por pantalla lo que reduce el tiempo de creación del fichero
SELECT 1 FROM DUAL;
ejemplo de spool con commit
spool c:\inicio\ficheroSpool.sql
SET HEADING OFF
SET FEEDBACK OFF
SET LINESIZE 1000
SET TERMOUT OFF -- anula la salida por pantalla lo que reduce el tiempo de creación del fichero
PROMPT SET TERMOUT OFF
SELECT 'insert into EPACT_ACTO_ADJ_VAC_SOL
(ACT_ID_CURSO, ACT_ID_ACTO, ACT_ID_VACANTE, ACT_ID_CUERPO, ACT_ID_ESPECIALIDAD,
ACT_NIF, ACT_ORDEN, ACT_ID_ESTADO)
values ( 2017, 1,'|| V.N_VACANTE||','''|| V.C_CUERPO||''','''|| V.C_ESPEC||''' , ''' ||FB_DNI_A_NIF(P.DNI)||''' , '||P.N_ORD_PREF ||', '||
'''PENDIENTE'' ); '||
DECODE(MOD(ROWNUM,10),0,CHR(10)||CHR(13)||'COMMIT;',NULL)
FROM PETICVAC_AE P, V_VACANTES_AE V
WHERE P.F_CONV_AE = '27/07/2017'
AND P.AÑO_INI_CUR = V.AÑO_INI_CUR
AND P.N_VACANTE = V.N_VACANTE
AND V.C_ESPEC = 'EF1'
and rownum < 12 -- para pruebas
ORDER BY P.N_ORD_PREF;
SELECT 'COMMIT;' FROM DUAL;`
spool off
añadir a un spool
- para añadir información a un spoll y no borarlo se usa
spool <nombre_fichero_spool> append
filas afectadas
- para saber el número de filas afectadas por una sentencia se usa
SQL%ROWCOUNT
CREATE TABLE employees_temp AS SELECT * FROM employees;
BEGIN
UPDATE employees_temp SET salary = salary * 1.05 WHERE salary < 5000;
DBMS_OUTPUT.PUT_LINE('Updated ' || SQL%ROWCOUNT || ' salaries.');
END;
- tiene que estar justo despues de la sentencia.
numero de filas de una consulta
SELECT COD_CUE, COD_ESP, POS_CAN, NIF, NOMBRE, POS_PET, VAC, NIF_ADJ,
EST_PET, NUM_FILA--, COUNT(*) OVER()
tunning
interesante post sobre tunning de consultas
Cuando se hace una consulta multi-tabla con //joins//, el orden en que se ponen las tablas en el FROM influye en el plan de ejecución. Aquellas tablas que retornan más filas deben ir en las primeras posiciones, mientras que las tablas con pocas filas deben situarse al final de la lista de tablas.
Colocar la tabla que devuelve menor número de registros en el último lugar del FROM.
Utilizar siempre que sea posible las mismas consultas. La segunda vez que se ejecuta una consulta, se ahorrará mucho tiempo de parsing y optimización, así que se debe intentar utilizar las mismas consultas repetidas veces.
fiddle
- para probar sentencias sql online
- sqlfiddle
- sqlfiddle ejemplo con oracle
- muestra el plan de ejecucción
- se puede generar un link y compartir
- ejemplo propio 😄
- el usuario
USER_4_C6E41
forma parte del link generado
trigger autoincremental
- cuidado con el trigger para aumentar el contador cuando empezamos con la tabla vacía
SELECT '1 MAX(NUM)' SENTENCIA , MAX(NUM) FROM AUD_APL UNION
SELECT '2 NVL(MAX(NUM),0)' , NVL(MAX(NUM),0) FROM AUD_APL UNION
SELECT '3 NVL(MAX(NUM),0) + 1' ,NVL(MAX(NUM),0) + 1 FROM AUD_APL UNION
SELECT '4 NVL(NUM,0)' SENTENCIA , NVL(NUM,0) FROM AUD_APL UNION
SELECT '5 MAX(NVL(NUM,0))' , MAX(NVL(NUM,0)) FROM AUD_APL UNION
SELECT '6 MAX(NVL(NUM,0)) + 1' , MAX(NVL(NUM,0)) + 1 FROM AUD_APL
- los ref cursores
-- DESDE SQL PLUS
SQL> conn gab/desarrollo@xe
Connected.
SQL> SHOW USER
USER is "GAB"
SQL> VAR RC REFCURSOR;
SQL> exec :rc := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1);
PL/SQL procedure successfully completed.
SQL> print rc
GAB_ALUMNO
--------------------------------------------------
GAB_DESCRIPCION
--------------------------------------------------------------------------------
ALUMNO1
DESCRIPCION DEL ALUMNO 1
ALUMNO2
DESCRIPCION DEL ALUMNO 2
ALUMNO3
DESCRIPCION DEL ALUMNO 3
SQL> print rc
SP2-0625: Error printing variable "rc"
SQL>
- el
ref cursor
no contiene los datos resultado de la consulta sino que contiene un puntero a la consulta y por eso el segundoprint
da error - el primer
print
funciona porqueSQL Plus
mira el cursor de referencia y ve que es un cursor abierto pues la sentencia no lo cierra. - Entra en el bucle, obteniendo cada fila de datos de la base de datos, utilizando el cursor de referencia como referencia (puntero) a la consulta relevante, y mostrando cada fila de datos hasta que no tenía más filas para recuperar.
- Una vez que se han obtenido todas las filas, cierra el cursor.
SQL> ed
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Alumnos: '||c_alumnos%ROWCOUNT);
close c_alumnos;
end;
SQL> /
Alumnos: 0
PL/SQL procedure successfully completed.
- sale 0 a pesar de que existen 3 alumnos por que
c_alumnos%ROWCOONT
muestra el número de fila leídas a través del cursos y no hemos leído ninguna.
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
v_id_alumno varchar2(50);
v_descripcion varchar2(200);
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Pre Fetch: Alumnos: '||c_alumnos%ROWCOUNT);
fetch c_alumnos into v_id_alumno, v_descripcion;
dbms_output.put_line('Post Fetch: Rows: '||c_alumnos%ROWCOUNT);
close c_alumnos;
end;
SQL> /
Pre Fetch: Alumnos: 0
Post Fetch: Rows: 1
PL/SQL procedure successfully completed.
- ahora sí que ha leído una fila del cursor.
SQL> ed
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
v_id_alumno varchar2(50);
v_descripcion varchar2(200);
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Pre Fetch: Alumnos: '||c_alumnos%ROWCOUNT);
loop
fetch c_alumnos into v_id_alumno, v_descripcion;
exit when c_alumnos%NOTFOUND;
dbms_output.put_line('Post Fetch: Rows: '||c_alumnos%ROWCOUNT||' '||v_id_alumno||' '||v_descripcion);
end loop;
close c_alumnos;
end;
SQL> /
Pre Fetch: Alumnos: 0
Post Fetch: Rows: 1 ALUMNO1 DESCRIPCION DEL ALUMNO 1
Post Fetch: Rows: 2 ALUMNO2 DESCRIPCION DEL ALUMNO 2
Post Fetch: Rows: 3 ALUMNO3 DESCRIPCION DEL ALUMNO 3
PL/SQL procedure successfully completed.
de esta forma se lee el contenido del cursor
- funciona tanto en
SQL
como desde elTOAD
|
SENTENCIA | MAX(NUM) | | :——————-: |:——: |
- funciona tanto en
los ref cursores
-- DESDE SQL PLUS
SQL> conn gab/desarrollo@xe
Connected.
SQL> SHOW USER
USER is "GAB"
SQL> VAR RC REFCURSOR;
SQL> exec :rc := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1);
PL/SQL procedure successfully completed.
SQL> print rc
GAB_ALUMNO
--------------------------------------------------
GAB_DESCRIPCION
--------------------------------------------------------------------------------
ALUMNO1
DESCRIPCION DEL ALUMNO 1
ALUMNO2
DESCRIPCION DEL ALUMNO 2
ALUMNO3
DESCRIPCION DEL ALUMNO 3
SQL> print rc
SP2-0625: Error printing variable "rc"
SQL>
- el
ref cursor
no contiene los datos resultado de la consulta sino que contiene un puntero a la consulta y por eso el segundoprint
da error - el primer
print
funciona porqueSQL Plus
mira el cursor de referencia y ve que es un cursor abierto pues la sentencia no lo cierra. - Entra en el bucle, obteniendo cada fila de datos de la base de datos, utilizando el cursor de referencia como referencia (puntero) a la consulta relevante, y mostrando cada fila de datos hasta que no tenía más filas para recuperar.
- Una vez que se han obtenido todas las filas, cierra el cursor.
SQL> ed
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Alumnos: '||c_alumnos%ROWCOUNT);
close c_alumnos;
end;
SQL> /
Alumnos: 0
PL/SQL procedure successfully completed.
- sale 0 a pesar de que existen 3 alumnos por que
c_alumnos%ROWCOONT
muestra el número de fila leídas a través del cursos y no hemos leído ninguna.
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
v_id_alumno varchar2(50);
v_descripcion varchar2(200);
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Pre Fetch: Alumnos: '||c_alumnos%ROWCOUNT);
fetch c_alumnos into v_id_alumno, v_descripcion;
dbms_output.put_line('Post Fetch: Rows: '||c_alumnos%ROWCOUNT);
close c_alumnos;
end;
SQL> /
Pre Fetch: Alumnos: 0
Post Fetch: Rows: 1
PL/SQL procedure successfully completed.
- ahora sí que ha leído una fila del cursor.
SQL> ed
Wrote file afiedt.buf
declare
c_alumnos sys_refcursor;
v_id_alumno varchar2(50);
v_descripcion varchar2(200);
begin
c_alumnos := gab.gab_pck_alumno.f_buscar_alumnos (null,null,1); -- This returns an open cursor
dbms_output.put_line('Pre Fetch: Alumnos: '||c_alumnos%ROWCOUNT);
loop
fetch c_alumnos into v_id_alumno, v_descripcion;
exit when c_alumnos%NOTFOUND;
dbms_output.put_line('Post Fetch: Rows: '||c_alumnos%ROWCOUNT||' '||v_id_alumno||' '||v_descripcion);
end loop;
close c_alumnos;
end;
SQL> /
Pre Fetch: Alumnos: 0
Post Fetch: Rows: 1 ALUMNO1 DESCRIPCION DEL ALUMNO 1
Post Fetch: Rows: 2 ALUMNO2 DESCRIPCION DEL ALUMNO 2
Post Fetch: Rows: 3 ALUMNO3 DESCRIPCION DEL ALUMNO 3
PL/SQL procedure successfully completed.
- de esta forma se lee el contenido del cursor
- funciona tanto en
SQL
como desde el `TOAD
- funciona tanto en
1 MAX(NUM) | null |
---|---|
2 NVL(MAX(NUM),0) | 0 |
3 NVL(MAX(NUM),0) + 1 | 1 |
5 MAX(NVL(NUM,0)) | |
6 MAX(NVL(NUM,0)) + 1 |
blogs
por explorar
sys.dbms_utility.format_error_backtrace
- interesante entrada sobre el tema
sqlplus
OWA_UTIL.CALENDARPRINT
- leo que genera un calendario en HTML
- uso del paquete
owa_util.calendarprint
pero me da un error
-- como GAB
SQL> exec OWA_UTIL.CALENDARPRINT(P_QUERY => 'SELECT sysdate ,gab_alumno, null FROM gab_alumno where gab_alumno = ''ALUMNO1'' order by sysdate', P_MF_ONLY =>'Y');
BEGIN OWA_UTIL.CALENDARPRINT(P_QUERY => 'SELECT sysdate ,gab_alumno, null FROM gab_alumno where gab_alumno = ''ALUMNO1'' order by sysdate', P_MF_ONLY =>'Y'); END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SYS.OWA_UTIL", line 2356
ORA-06512: at line 1
SQL> exec OWA_UTIL.CALENDARPRINT(P_QUERY => 'SELECT sysdate ,gab_alumno, null FROM gab_alumno order by gab_alumno', P_MF_ONLY =>'Y');
desactivar constraints
- sacado de este gist
-- C - Check constraint on a table
-- P - Primary key
-- U - Unique key
-- R - Referential integrity
-- V - With check option, on a view
-- O - With read only, on a view
-- H - Hash expression
-- F - Constraint that involves a REF column
-- S - Supplemental logging
SET SERVEROUTPUT ON
exec dbms_output.enable(1000000);
DECLARE
v_typ VARCHAR2(32);
v_name VARCHAR2(32);
v_constraint VARCHAR2(32);
v_sql VARCHAR2(100);
CURSOR c_constraints IS
SELECT table_name, constraint_name
FROM user_constraints
WHERE constraint_type = 'R'
;
BEGIN
OPEN c_constraints;
LOOP
BEGIN
FETCH c_constraints
INTO v_name, v_constraint;
EXIT WHEN c_constraints%NOTFOUND;
v_sql := 'alter table ' || v_name || ' DISABLE constraint ' || v_constraint;
DBMS_OUTPUT.put_line(v_sql);
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('Error in exec ' || v_sql);
END;
END LOOP;
CLOSE c_constraints;
v_sql := 'PURGE RECYCLEBIN';
DBMS_OUTPUT.put_line(v_sql);
EXECUTE IMMEDIATE v_sql;
END;
/
EXIT;
objetos inválidos
- para todos los usuarios comentando la línea del
OWNER
--SET SERVEROUTPUT ON SIZE 1000000
BEGIN
FOR cur_rec IN (SELECT owner,
object_name,
object_type,
DECODE(object_type, 'PACKAGE', 1,
'PACKAGE BODY', 2, 2) AS recompile_order
FROM dba_objects
WHERE object_type IN ('PACKAGE', 'PACKAGE BODY')
AND status != 'VALID'
AND OWNER = USER
ORDER BY 4)
LOOP
BEGIN
IF cur_rec.object_type = 'PACKAGE' THEN
EXECUTE IMMEDIATE 'ALTER ' || cur_rec.object_type ||
' "' || cur_rec.owner || '"."' || cur_rec.object_name || '" COMPILE';
ElSE
EXECUTE IMMEDIATE 'ALTER PACKAGE "' || cur_rec.owner ||
'"."' || cur_rec.object_name || '" COMPILE BODY';
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line(cur_rec.object_type || ' : ' || cur_rec.owner ||
' : ' || cur_rec.object_name);
END;
END LOOP;
END;
sinónimos inválidos
- de este blog
rem
rem Exludes SYS and SYSTEM users
rem
select 'drop '||decode (s.owner,'PUBLIC','PUBLIC SYNONYM ',
'SYNONYM'||s.owner||'.')||s.synonym_name||';'
from dba_synonyms s
where table_owner not in('SYSTEM','SYS')
and db_link is null
and not exists
(select 1
from dba_objects o
where s.table_owner=o.owner
and s.table_name=o.object_name)
pl-sql developer
- para ejecutar la sentencia en la que esta el cursor
- Tools-preferences-SQL-window
cerrar report background engine
Add_Parameter(pl_id,'ORACLE_SHUTDOWN',TEXT_PARAMETER,'Yes');
comandos
TERMOUT
SET TERMOUT OFF
- anula la salida del comando por el terminal lo que reduce el tiempo de ejecución
usarlo en el script que se lanza y en el generado si es de carga
interesantes
sudoku
- un programa en pl sql para resolver sudokus
- lo resuelve solo creando types