PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de...

24
PL/SQL PL/SQL Francisco Moreno Universidad Nacional

Transcript of PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de...

Page 1: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

PL/SQLPL/SQLFrancisco Moreno

Universidad Nacional

Page 2: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Paquetes: sobrecarga de subprogramas

• Sobrecarga de subprogramas:obrecarga de subprogramas: Varios subprogramas pueden tener el mismo nombre en un paquetepaquete siempre y cuando no haya ambigüedad con los tipos de los parámetros y de retorno

Page 3: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

• No puede haber sobrecarga si la diferencia entre los subprogramas con el mismo nombre solo se basa en:– el modo (IN, OUT)

– el tipo de retorno de una función

– Tipos de datos de la misma familia como CHAR y VARCHAR*

* Se permite para ciertos tipos de datos, por ejemplo NUMBER vs POSITIVE, aunque el comportamiento es bastante peculiar.

Page 4: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

No puede haber sobrecarga entre:

PROCEDURE xxx(a VARCHAR)

PROCEDURE yyy(a IN NUMBER)

FUNCTION zzz(a IN NUMBER)

RETURN NUMBER

PROCEDURE xxx(b CHAR)

PROCEDURE yyy(b OUT NUMBER)

FUNCTION zzz(b IN NUMBER)

RETURN VARCHAR

Page 5: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Ejemplo

CREATE OR REPLACE PACKAGE mat ISFUNCTION area(radio NUMBER) RETURN NUMBER;FUNCTION area(largo NUMBER, ancho NUMBER) RETURN NUMBER;END;/

Page 6: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

CREATE OR REPLACE PACKAGE BODY mat IS FUNCTION area(radio NUMBER) RETURN NUMBER IS BEGIN RETURN 3.1416*radio*radio; END; FUNCTION area(largo NUMBER, ancho NUMBER) RETURN NUMBER IS BEGIN RETURN largo*ancho; END;END;/

Page 7: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Para ejecutar:

BEGINDBMS_OUTPUT.PUT_LINE(mat.area(10));DBMS_OUTPUT.PUT_LINE(mat.area(20,30

));END;/

SELECT mat.area(10), mat.area(20,30) FROM dual;

Page 8: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Variables en los Paquetes

• Las variables de los paquetes son persistentes durante la sesión• Las variables declaradas en la especificación son

públicas: se pueden acceder y modificar directamente desde otros subprogramas o bloques anónimos

• Las variables declaradas en el cuerpo son privadas: solo se pueden acceder dentro del cuerpo. Si se desea ver su valor desde afuera del cuerpo, se

debe crear un subprograma (público) a través del cual se acceden (cf. encapsulamiento)

Page 9: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

CREATE OR REPLACE PACKAGE vbles IS nro_veces NUMBER(3) := 0; -- Vble

pública PROCEDURE incrementa_veces; PROCEDURE muestra_veces; PROCEDURE muestra_impresiones; END; /

Ejemplo

Subprogramas públicos

Este procedimiento no es estrictamente necesario aunque es recomendable ¿por qué?

Page 10: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

CREATE OR REPLACE PACKAGE BODY vbles IS nro_impresiones NUMBER(3) := 0; --Variable privada PROCEDURE incrementa_veces IS BEGIN nro_veces := nro_veces + 1; END; PROCEDURE muestra_veces IS BEGIN DBMS_OUTPUT.PUT_LINE(nro_veces); nro_impresiones := nro_impresiones + 1; END;

PROCEDURE muestra_impresiones IS BEGIN DBMS_OUTPUT.PUT_LINE(nro_impresiones); END;END;/

Page 11: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Para ejecutar:

• EXECUTE vbles.muestra_veces; • EXECUTE vbles.muestra_impresiones;• EXECUTE vbles.incrementa_veces;• EXECUTE vbles.muestra_veces;• EXECUTE vbles.muestra_veces; • EXECUTE vbles.muestra_impresiones;

0 1

1 1

3

Page 12: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Directamente se pueden acceder las variables públicas pero NO las privadas. Igual sucede cuando hay subprogramas privados. Por ejemplo:

BEGIN vbles.nro_veces := vbles.nro_veces + 1;END;/

BEGIN DBMS_OUTPUT.PUT_LINE(vbles.nro_veces);END;/

BEGIN DBMS_OUTPUT.PUT_LINE(vbles.nro_impresiones);END;/ Genera error porque nro_impresiones NO es pública

Page 13: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Cursores REF

• Los cursores REF permiten pasar los resultados de una consulta a otro subprograma

• El programa que recibe el cursor REF lo puede recorrer como un cursor normal

• Hay cursores REF fuertes (se les especifica el tipo de retorno) y débiles.

Page 14: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Ejemplo de cursor REF fuerte

--Sea la tabla:DROP TABLE emp;CREATE TABLE emp( cedula NUMBER(8) PRIMARY KEY, nom VARCHAR2(10) NOT NULL);

INSERT INTO emp VALUES(8,'Loui');INSERT INTO emp VALUES(7,'Dina');INSERT INTO emp VALUES(5,'Xena');

Page 15: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Se define el tipo del cursor REF y su tipo de retorno:

CREATE OR REPLACE PACKAGE prueba_ref_cursor

IS TYPE ref_emp_type IS REF CURSOR RETURN emp%ROWTYPE; END;/

Tipo de retorno del REF CURSOR: es lo que lo hace “fuerte”

Page 16: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

CREATE OR REPLACE PROCEDURE devuelve_cursor

/*Se envía el cursor REF fuerte como parámetro de salida:*/

(c OUT prueba_ref_cursor.ref_emp_type)ASBEGIN OPEN c FOR SELECT * FROM emp; --Se

llenaEND;/

Ya el cursor REF c queda lleno (pero los datos no se recorren acá)

Page 17: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

--Se invoca el procedimiento anterior y se imprimen--los resultados:DECLAREresultados prueba_ref_cursor.ref_emp_type;a emp%ROWTYPE;BEGINdevuelve_cursor(resultados); --Se invocaLOOP --Se recorre FETCH resultados INTO a; EXIT WHEN resultados%NOTFOUND; DBMS_OUTPUT.PUT_LINE(a.cedula || ' ' || a.nom);END LOOP;CLOSE resultados;END;/

Page 18: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

Ejemplo de cursor REF débil: SYS_REFCURSOR

CREATE OR REPLACE PROCEDURE devuelve_cursor/*Se envía el cursor REF débil (parámetro de salida) y el

nombre de la tabla a consultar */ (c OUT SYS_REFCURSOR, nom_tabla IN VARCHAR)ASBEGIN OPEN c FOR 'SELECT * FROM ' || nom_tabla; --Se llenaEND;/

Nótese que la consulta asociada con un REF CURSOR puede ser ¡una cadena de caracteres!, esto permite crear cursores cuya consulta no se conoce en tiempo de compilación.

Page 19: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

--Sea la tabla:

DROP TABLE cliente;CREATE TABLE cliente( ced NUMBER(8) PRIMARY KEY, nom VARCHAR2(10) NOT NULL, ciudad VARCHAR2(10) NOT NULL);

INSERT INTO cliente VALUES(1,'Pedra', 'Cali');INSERT INTO cliente VALUES(2,'Kathy',

'Londres');INSERT INTO cliente VALUES(3,'Donna', 'Paris');

Page 20: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

DECLARE--Una variable de tipo SYS_REFCURSORmi_ref_cursor SYS_REFCURSOR;a1 emp%ROWTYPE; a2 cliente%ROWTYPE;BEGINdevuelve_cursor(mi_ref_cursor,'emp'); --Se invocaLOOP FETCH mi_ref_cursor INTO a1; EXIT WHEN mi_ref_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE(a1.cedula || ' ' ||

a1.nom);END LOOP;CLOSE mi_ref_cursor; El programa

continua en la próxima

diapositiva

Page 21: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

devuelve_cursor(mi_ref_cursor, 'cliente'); --Se invocaLOOP FETCH mi_ref_cursor INTO a2; EXIT WHEN mi_ref_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE(a2.ced || ' ' || a2.nom || '

' || a2.ciudad);END LOOP;CLOSE mi_ref_cursor;END;/

Page 22: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

¿Se podrá adaptar el programa anterior de tal forma que quede funcionando para imprimir los resultados de cualquier consulta? El problema es que solo en tiempo de ejecución se sabe cual es la tabla a consultar y sus columnas Solución: Usar el paquete DBMS_SQL.

Page 23: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

DECLARErcursor SYS_REFCURSOR;theCursor INTEGER;colCnt NUMBER;dTbl DBMS_SQL.DESC_TAB;val VARCHAR2(100);BEGINOPEN rcursor FOR SELECT * FROM cliente;theCursor := DBMS_SQL.TO_CURSOR_NUMBER(rcursor);DBMS_SQL.DESCRIBE_COLUMNS(theCursor,colCnt,dTbl);FOR i IN 1 .. colCnt LOOP DBMS_SQL.DEFINE_COLUMN(theCursor,i,val,100);END LOOP;

Ensayar con emp

Page 24: PL/SQL Francisco Moreno Universidad Nacional. Paquetes: sobrecarga de subprogramas obrecarga de subprogramas: paqueteSobrecarga de subprogramas: Varios.

WHILE(DBMS_SQL.FETCH_ROWS(theCursor) > 0) LOOP FOR i IN 1 .. colCnt LOOP DBMS_SQL.COLUMN_VALUE(theCursor,i,val); DBMS_OUTPUT.PUT_LINE(dTbl(i).col_name || ': ' || val); END LOOP; DBMS_OUTPUT.PUT_LINE('Siguiente registro');END LOOP;DBMS_SQL.CLOSE_CURSOR(theCursor);END;/