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

ref cursor

-- 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 segundo print da error
  • el primer print funciona porque SQL 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 el TOAD
  • 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

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)

`REFCURSOR` DESDE TOAD

  • 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

`REFCURSOR` DESDE TOAD

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.

  • otro post interesante sobre el tema

fiddle

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  
-- 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 segundo print da error
  • el primer print funciona porque SQL 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|
      SENTENCIA | MAX(NUM) | | :——————-: |:——: |
  • 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 segundo print da error
  • el primer print funciona porque SQL 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
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

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

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

`pl_sql_developer_seleccionar_consultas_automaticamente`

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