Está en la página 1de 33

PL/SQL

Estructura de un procedimiento

1ºCreación: CREATE OR REPLACE PROCEDURE <PROCEDIMIENTO>,

2º Declarativa: Donde se declaran las variables

3º Instrucciones: Consultas y demás…

NOMBRE_PROCEDIMIENTO: Es el nombre del procedimiento, el cual se usará para identificarlo.

PARÁMETROS: Los parámetros son como variables, contienen datos que se pueden especificar al
momento de llamar al procedimiento.

VARIABLES: Como en un bloque anónimo, en los procedimientos se pueden crear variables, pero éstas
variables sólo pueden usadas en código dentro del procedimiento.

CÓDIGO PL/SQL: Es el código propio ejecutado al momento de llamar al procedimiento, se pueden


hacer uso de las variables declaradas así como de los parámetros.

Los parámetros no llevan tamaño de caracteres (Por ejemplo, con NUMBER)

Para poder ejecutar los procedimientos PL/SQL hay que ejecutar primero en la consola el comando

SET SERVEROUTPUT ON;

Para ejecutar un procedimiento hay que ejecutar

EXECUTE NOMBRE DEL PROCEDIMIENTO PARAMETRO;

%TYPE PARA INDICAR QUE LA VARIABLE TENGA EL MISMO TIPO DE DATO Y


LONGITUD QUE LA COLUMNA DE LA TABLA A LA QUE REPRESENTA.
V_DNOMBRE DEPART.DNOMBRE%TIPE

%ROWTYPE

NOMBRE_VARIABLE NOMBRE_OBJETO%ROWTYPE;
Ejercicio1

Crear un procedimiento que muestre por pantalla el apellido y el salario de un empleado, cuyo
emp_no pasamos como parametro.

CREATE OR REPLACE PROCEDURE EJEMPLO1 (EMP NUMBER)


AS

V_APELLIDO VARCHAR2(15);
V_SALARIO NUMBER(6,2);

BEGIN

SELECT APELLIDO, SALARIO INTO V_APELLIDO, V_SALARIO FROM EMPLE WHERE


EMP_NO=EMP;

DBMS_OUTPUT.PUT_LINE ('El apellido y salario de '|| EMP ||'es '||V_APELLIDO||' '||V_SALARIO);

EXCEPTION

WHEN NO_DATA_FOUND THEN


DBMS_OUTPUT.PUT_LINE('No se encuentra el empleado');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error general');
END EJEMPLO1;
/

Ejercicio 2

Crear un procedimiento que muestre por pantalla el nombre y la localidad de un departamento,


cuyo dept_no pasamos como parámetro.

CREATE OR REPLACE PROCEDURE EJEMPLO2 (DEPT NUMBER)


AS

V_DNOMBRE VARCHAR2(15);
V_LOC VARCHAR2(15);

BEGIN

SELECT DNOMBRE, LOC INTO V_DNOMBRE, V_LOC FROM DEPART WHERE


DEPT_NO=DEPT;
DBMS_OUTPUT.PUT_LINE ('El nombre y localidad de '|| DEPT ||' es '||V_DNOMBRE||' '||V_LOC);

EXCEPTION

WHEN NO_DATA_FOUND THEN


DBMS_OUTPUT.PUT_LINE('No se encuentra el departamento');

WHEN OTHERS THEN


DBMS_OUTPUT.PUT_LINE('Error general');
END EJEMPLO2;
/
Ejercicio 3

Crear un procedimiento que suba el salario un 3% a los empleados del departamento que pasemos
como paramento. (El parámetro es el nombre del departamento).

CREATE OR REPLACE PROCEDURE EJEMPLO3 (DNOM VARCHAR2)


AS

BEGIN

UPDATE EMPLE SET SALARIO = SALARIO*1.03


WHERE DEPT_NO=(SELECT DEPT_NO FROM DEPART WHERE DNOMBRE=DNOM);

EXCEPTION

WHEN OTHERS THEN


DBMS_OUTPUT.PUT_LINE(‘ERROR GENERAL’);
END EJEMPLO3;
/

Ejercicio 4

CREATE OR REPLACE PROCEDURE EJEMPLO4 (DNOM VARCHAR2)


AS

V_DEPART DEPART%ROWTYPE;

BEGIN

SELECT * INTO V_DEPART FROM DEPART WHERE DNOMBRE=DNOM;

DBMS_OUTPUT.PUT_LINE(V_DEPART.DEPT_NO||' '||V_DEPART.DNOMBRE||'
'||V_DEPART.LOC);

EXCEPTION

WHEN NO_DATA_FOUND THEN


DBMS_OUTPUT.PUT_LINE('No se encuentra el departamento');

WHEN OTHERS THEN


DBMS_OUTPUT.PUT_LINE('ERROR GENERAL');
END EJEMPLO4;
/
Estructura de una función

CREATE OR REPLACE FUNCTION NOMBRE DE LA FUNCION (PARAMETROS)


RETURN TIPO DE DATO
AS
VARIABLES

BEGIN
SENTENCIAS A REALIZAR

RETURN VARIABLE

END NOMBRE DE LA FUNCION;


/

Ejecutar funciones

BEGIN
DBMSOUTPUT.PUT_LINE(NOMBRE DE LA FUNCION(PARAMETROS));

Ejercicio 1

CREATE OR REPLACE FUNCTION CON_IVA (CANTIDAD NUMBER, IVA NUMBER DEFAULT


16)
RETURN NUMBER
AS
V_RESULTADO NUMBER (10,2) DEFAULT 0;

BEGIN
V_RESULTADO := CANTIDAD * (1 + (IVA / 100));
RETURN V_RESULTADO;
END CON_IVA;
/

BEGIN
DBMS_OUTPUT.PUT_LINE(CON_IVA(1000, 25));
END;
/
3ºEVALUACION
Funciones y procedimientos locales

Ejercicio 9

CREATE OR REPLACE PROCEDURE EJERCICIO9 (PARTICULO VARCHAR2,


PCOD_FABRICANTE NUMBER, PPESO NUMBER, PCATEGORIA VARCHAR2)
AS

PROCEDURE FACTURACION (PARTICULO VARCHAR2, PCOD_FABRICANTE NUMBER,


PPESO NUMBER, PCATEGORIA VARCHAR2)
AS
V_FACTURACION NUMBER(7,2);
BEGIN
SELECT SUM(UNIDADES_PEDIDAS*PRECIO_VENTA) INTO V_FACTURACION FROM
ARTICULOS A, PEDIDOS P WHERE A.ARTICULO=PARTICULO AND
A.COD_FABRICANTE=PCOD_FABRICANTE AND A.PESO=PPESO AND
A.CATEGORIA=PCATEGORIA AND A.ARTICULO=P.ARTICULO AND
A.COD_FABRICANTE=P.COD_FABRICANTE AND A.PESO=P.PESO AND
A.CATEGORIA=P.CATEGORIA;
DBMS_OUTPUT.PUT_LINE(V_FACTURACION);
END FACTURACION;

PROCEDURE PEDIDOS (PARTICULO VARCHAR2, PCOD_FABRICANTE NUMBER, PPESO


NUMBER, PCATEGORIA VARCHAR2)
AS
V_NUMERO_PEDIDOS NUMBER(3);
BEGIN
SELECT COUNT(UNIDADES_PEDIDAS) INTO V_NUMERO_PEDIDOS FROM PEDIDOS WHERE
ARTICULO=PARTICULO AND COD_FABRICANTE=PCOD_FABRICANTE AND PESO=PPESO
AND CATEGORIA=PCATEGORIA;
DBMS_OUTPUT.PUT_LINE(V_NUMERO_PEDIDOS);
END PEDIDOS;

BEGIN

FACTURACION(PARTICULO, PCOD_FABRICANTE, PPESO, PCATEGORIA);


PEDIDOS(PARTICULO, PCOD_FABRICANTE, PPESO, PCATEGORIA);

END EJERCICIO9;
/
Ejercicio 10

CREATE OR REPLACE PROCEDURE EJERCICIO10 (PDEPT_NO NUMBER)


AS

V_NUMERO_EMPLEADOS NUMBER(3);
V_SUMA_SALARIOS NUMBER(5);

FUNCTION EMPLEADOS (PDEPT_NO NUMBER)


RETURN NUMBER
AS
V_EMPLEADOS NUMBER(3);
BEGIN
SELECT COUNT(EMP_NO) INTO V_EMPLEADOS FROM EMPLE WHERE
DEPT_NO=PDEPT_NO;
RETURN V_EMPLEADOS;
END EMPLEADOS;

FUNCTION SALARIO (PDEPT_NO NUMBER)


RETURN NUMBER
AS
V_SALARIO NUMBER(5);
BEGIN
SELECT SUM(SALARIO) INTO V_SALARIO FROM EMPLE WHERE DEPT_NO=PDEPT_NO;
RETURN V_SALARIO;
END SALARIO;

BEGIN

V_NUMERO_EMPLEADOS:=EMPLEADOS(PDEPT_NO);
V_SUMA_SALARIOS:=SALARIO(PDEPT_NO);

DBMS_OUTPUT.PUT_LINE('EL DEPARTAMENTO '||PDEPT_NO||' TIENE


'||V_NUMERO_EMPLEADOS||' EMPLEADOS');
DBMS_OUTPUT.PUT_LINE('EL DEPARTAMENTO '||PDEPT_NO||' GASTA EN SALARIOS
'||V_SUMA_SALARIOS||' EUROS');

END EJERCICIO10;
/
Ejemplo 1

CREATE OR REPLACE PROCEDURE EJEMPLO1


AS
CURSOR CURL1 IS SELECT DNOMBRE, LOC FROM DEPART;
V_DNOMBRE VARCHAR2(15);
V_LOC VARCHAR2(15);

BEGIN
OPEN CURL1;
FETCH CURL1 INTO V_DNOMBRE, V_LOC;
WHILE CURL1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE (V_DNOMBRE ||'*'||V_LOC);

FETCH CURL1 INTO V_DNOMBRE, V_LOC;


END LOOP;
CLOSE CURL1;
END;
/

CREATE OR REPLACE PROCEDURE EJEMPLO1


AS
CURSOR CURL1 IS SELECT DNOMBRE, LOC FROM DEPART;

V_REG CURL1%ROWTYPE;

BEGIN
OPEN CURL1;
FETCH CURL1 INTO V_REG.DNOMBRE, V_REG.LOC;
WHILE CURL1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE (V_REG.DNOMBRE ||'*'||V_REG.LOC);

FETCH CURL1 INTO V_REG.DNOMBRE, V_REG.LOC;


END LOOP;
CLOSE CURL1;
END;
Ejemplo 2

CREATE OR REPLACE PROCEDURE EJEMPLO2


AS
CURSOR CURL1 IS SELECT ARTICULO, COD_FABRICANTE, PESO, CATEGORIA FROM
ARTICULOS;

V_REG CURL1%ROWTYPE;

BEGIN
OPEN CURL1;
FETCH CURL1 INTO V_REG.ARTICULO, V_REG.COD_FABRICANTE, V_REG.PESO,
V_REG.CATEGORIA;
WHILE CURL1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE
(RPAD(V_REG.ARTICULO,20)||RPAD(V_REG.COD_FABRICANTE,5)||
RPAD(V_REG.PESO,5)||RPAD(V_REG.CATEGORIA,11));

FETCH CURL1 INTO V_REG.ARTICULO, V_REG.COD_FABRICANTE, V_REG.PESO,


V_REG.CATEGORIA;
END LOOP;
CLOSE CURL1;
END EJEMPLO2;
/
Ejemplo 3

CREATE OR REPLACE PROCEDURE EJEMPLO3 (PDEPT_NO VARCHAR2)


AS
V_DEPT_NO NUMBER(2);

CURSOR CURL1 IS SELECT DEPT_NO, DNOMBRE, LOC FROM DEPART WHERE


DEPT_NO=V_DEPT_NO;

V_REG CURL1%ROWTYPE;

BEGIN
V_DEPT_NO :=PDEPT_NO;

OPEN CURL1;
FETCH CURL1 INTO V_REG.DEPT_NO, V_REG.DNOMBRE, V_REG.LOC;
WHILE CURL1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE (V_REG.DEPT_NO||' '||V_REG.DNOMBRE||' '||V_REG.LOC);

FETCH CURL1 INTO V_REG.DEPT_NO, V_REG.DNOMBRE, V_REG.LOC;


END LOOP;
CLOSE CURL1;
END EJEMPLO3;
Ejemplo 1A

CREATE OR REPLACE PROCEDURE EJEMPLO1 (PDEPT_NO NUMBER)


AS
CURSOR C1 (PDEPT NUMBER) IS SELECT APELLIDO, DEPT_NO FROM EMPLE WHERE
DEPT_NO=PDEPT;
BEGIN
FOR V_REG IN C1(PDEPT_NO) LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(V_REG.APELLIDO,15)||' '||V_REG.DEPT_NO);
END LOOP;
END EJEMPLO1;
/
Ejemplo 1B

CREATE OR REPLACE PROCEDURE EJEMPLO1 (PDEPT_NO NUMBER)


AS
CURSOR C1 (PDEPT NUMBER) IS SELECT APELLIDO, DEPT_NO FROM EMPLE WHERE
DEPT_NO=PDEPT;
V_REG C1%ROWTYPE;

BEGIN
OPEN C1(PDEPT_NO);
FETCH C1 INTO V_REG.APELLIDO, V_REG.DEPT_NO;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(V_REG.APELLIDO||' '||V_REG.DEPT_NO);
FETCH C1 INTO V_REG.APELLIDO, V_REG.DEPT_NO;
END LOOP;
CLOSE C1;
END;
/

Ejemplo 2A

CREATE OR REPLACE PROCEDURE EJEMPLO2 (PCOD_FABRICANTE NUMBER)


AS
CURSOR C1 (PCOD NUMBER) IS SELECT ARTICULO, COD_FABRICANTE, PESO, CATEGORIA
FROM ARTICULOS WHERE COD_FABRICANTE=PCOD;
BEGIN
FOR V_REG IN C1 (PCOD_FABRICANTE) LOOP
DBMS_OUTPUT.PUT_LINE('EL ARTICULO '||V_REG.ARTICULO||' CON CODIGO DE
FABRICANTE '||V_REG.COD_FABRICANTE||' CON UN PESO DE '||V_REG.PESO||' Y DE
CATEGORIA '||V_REG.CATEGORIA);
END LOOP;
END EJEMPLO2;
/

Ejemplo 2B

CREATE OR REPLACE PROCEDURE EJEMPLO2 (PCOD_FABRICANTE NUMBER)


AS
CURSOR C1 (PCOD NUMBER) IS SELECT ARTICULO, COD_FABRICANTE, PESO, CATEGORIA FROM
ARTICULOS WHERE COD_FABRICANTE=PCOD;
V_REG C1%ROWTYPE;

BEGIN
OPEN C1(PCOD_FABRICANTE);
FETCH C1 INTO V_REG.ARTICULO, V_REG.COD_FABRICANTE, V_REG.PESO, V_REG.CATEGORIA;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE('EL ARTICULO '||V_REG.ARTICULO||' CON CODIGO DE FABRICANTE
'||V_REG.COD_FABRICANTE||' CON UN PESO DE '||V_REG.PESO||' Y DE CATEGORIA
'||V_REG.CATEGORIA);
FETCH C1 INTO V_REG.ARTICULO, V_REG.COD_FABRICANTE, V_REG.PESO, V_REG.CATEGORIA;
END LOOP;
CLOSE C1;
END EJEMPLO2;
/
Ejemplo 1

CREATE OR REPLACE PROCEDURE EJERCICIO6 (PDEPT_NO NUMBER, PIMPORTE NUMBER,


PPORCENTAJE NUMBER)
AS
CURSOR C1 IS SELECT SALARIO FROM EMPLE WHERE DEPT_NO=PDEPT_NO FOR UPDATE;
V_SALARIO NUMBER(5);
V_SUBIDA NUMBER(5);

BEGIN
OPEN C1;
FETCH C1 INTO V_SALARIO;
WHILE C1%FOUND LOOP
V_SUBIDA:=GREATEST((V_SALARIO/100)*PPORCENTAJE,PIMPORTE);

UPDATE EMPLE SET SALARIO=SALARIO+V_SUBIDA WHERE CURRENT OF C1;

FETCH C1 INTO V_SALARIO;


END LOOP;
CLOSE C1;

EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END EJERCICIO6;
/
EJEMPLO

CREATE OR REPLACE PROCEDURE EJEMPLO_EXCEPCION (PEMP_NO NUMBER,


PAPELLIDO VARCHAR2, PSALARIO NUMBER, PCOMISION NUMBER, PDEPT_NO NUMBER)
AS
V_COMISION_NEGATIVA EXCEPTION;
BEGIN
IF PCOMISION <=0 THEN RAISE V_COMISION_NEGATIVA; END IF;

INSERT INTO EMPLE (EMP_NO, APELLIDO, SALARIO, COMISION, DEPT_NO) VALUES


(PEMP_NO, PAPELLIDO, PSALARIO, PCOMISION, PDEPT_NO);
DBMS_OUTPUT.PUT_LINE('EMPLEADO INSERTADO');

EXCEPTION

WHEN V_COMISION_NEGATIVA
THEN DBMS_OUTPUT.PUT_LINE('LA COMISION NO PUEDE SER NEGATIVA');

END;
/
FOR EACH ROW una vez por cada fila afectada por la acción que disparo el disparador.

DESABILITAR UN TRIGGER ALTER TRIGGER NOMBRE DISABLE


CREA UN TRIGGER SOBRE LA TABLA VENTAS TAL QUE CUANDO SE INSERTA UNA
VENTA, SE RESTAN LAS UNIDADES VENDIDAS DE LAS EXISTENCIAS DE LA TABLA
ARTICULOS

INSERT INTO VENTAS VALUES('5555-B', 'Macarrones', 20, 1, 'Primera', SYSDATE, 50);

CREATE OR REPLACE TRIGGER EJEMPLO1


BEFORE INSERT ON VENTAS
FOR EACH ROW

BEGIN

UPDATE ARTICULOS SET EXISTENCIAS=EXISTENCIAS-:NEW.UNIDADES_VENDIDAS


WHERE ARTICULO=:NEW.ARTICULO AND COD_FABRICANTE=:NEW.COD_FABRICANTE
AND PESO=:NEW.PESO AND CATEGORIA=:NEW.CATEGORIA;
END EJEMPLO1;
EJERCICIO 4

Escribe un paquete para gestionar los departamentos.


Se llamará gest_depart e incluirá, al menos, los siguientes subprogramas:

-insertar_nuevo_depart: inserta un departamento nuevo. Recibe el nombre y la localidad del nuevo


departamento. Creará el nuevo departamento comprobando
que el nombre no se duplique y le asignará como número de departamento la decena siguiente al
último número de departamento utilizado.

– borrar_depart: borra un departamento. Recibirá dos números de departamento: el primero


corresponde
al departamento que queremos borrar y el segundo, al departamento al que pasarán los empleados
del departamento
que se va a eliminar. El procedimiento se encargará de realizar los cambios oportunos en los
números de departamento de los empleados correspondientes

CREATE OR REPLACE PACKAGE PAQUETE_EJERCICIO4


AS
PROCEDURE PROCE4_1(PDNOMBRE VARCHAR2, PLOC VARCHAR2);
PROCEDURE PROCE4_2(PDEPT_NO1 NUMBER, PDEPT_NO2 NUMBER);
END PAQUETE_EJERCICIO4;
/
CREATE OR REPLACE PACKAGE BODY PAQUETE_EJERCICIO4
AS

PROCEDURE PROCE4_1(PDNOMBRE VARCHAR2, PLOC VARCHAR2)


AS
V_MAX_DEPARTAMENTO NUMBER(4);
V_DNOMBRE NUMBER(1);
BEGIN
SELECT TRUNC(MAX(DEPT_NO),1)+10 INTO V_MAX_DEPARTAMENTO FROM DEPART;
SELECT COUNT(DNOMBRE) INTO V_DNOMBRE FROM DEPART WHERE
DNOMBRE=PDNOMBRE;
IF V_DNOMBRE=0 THEN
INSERT INTO DEPART VALUES(V_MAX_DEPARTAMENTO, PDNOMBRE, PLOC);
DBMS_OUTPUT.PUT_LINE('SE HA INSERTADO EL DEPARTAMENTO
'||V_MAX_DEPARTAMENTO||' DE NOMBRE '||PDNOMBRE||' Y SITUADO EN '||PLOC);
ELSE DBMS_OUTPUT.PUT_LINE('NO PUEDE HABER DEPARTAMENTOS CON EL MISMO
NOMBRE'); END IF;
EXCEPTION
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR');
END PROCE4_1;

PROCEDURE PROCE4_2(PDEPT_NO1 NUMBER, PDEPT_NO2 NUMBER)


AS
BEGIN
UPDATE EMPLE SET DEPT_NO=PDEPT_NO2 WHERE DEPT_NO=PDEPT_NO1;
DELETE FROM DEPART WHERE DEPT_NO=PDEPT_NO1;
DBMS_OUTPUT.PUT_LINE('LOS EMPLEADOS DEL DEPARTAMENTO '||PDEPT_NO1||' HAN
SIDO TRASLADADOS AL DEPARTAMENTO '||PDEPT_NO2||
' Y EL DEPARTAMENTO '||PDEPT_NO1||' HA SIDO BORRADO');
END PROCE4_2;

END PAQUETE_EJERCICIO4;
/
EJEMPLO TABLA

CREATE OR REPLACE PROCEDURE EJEMPLO_TABLA_INDEXADA


AS
TYPE T_TABLA_CENTROS IS TABLE OF CENTROS%ROWTYPE INDEX BY
BINARY_INTEGER;
TAB_CENTROS T_TABLA_CENTROS;
CURSOR C1 IS SELECT * FROM CENTROS;
BEGIN
FOR V_REG IN C1 LOOP
TAB_CENTROS(V_REG.COD_CENTRO):=V_REG;
DBMS_OUTPUT.PUT_LINE(TAB_CENTROS(V_REG.COD_CENTRO).NOMBRE||'
'||TAB_CENTROS(V_REG.COD_CENTRO).DIRECCION);
END LOOP;
END EJEMPLO_TABLA_INDEXADA;

EJEMPLO 2 TABLA INDEXADA--------------------------------------------------------------------------


CREATE OR REPLACE VIEW SAL_MED_DEPART AS SELECT DEPT_NO,DNOMBRE,
TRUNC(AVG(SALARIO)) MEDIA
FROM EMPLE E NATURAL JOIN DEPART GROUP BY DEPT_NO, DNOMBRE;

CREATE OR REPLACE PROCEDURE EJEMPLO_TABLA_INDEXADA_2


AS
TYPE T_TABLA_VIEW IS TABLE OF SAL_MED_DEPART%ROWTYPE INDEX BY
BINARY_INTEGER;
V_TABLA_VIEW T_TABLA_VIEW;
CURSOR C1 IS SELECT * FROM SAL_MED_DEPART;
BEGIN
FOR V_REG IN C1 LOOP
V_TABLA_VIEW(V_REG.DEPT_NO):=V_REG;
DBMS_OUTPUT.PUT_LINE(RPAD(V_TABLA_VIEW(V_REG.DEPT_NO).DNOMBRE,10)||'
'||RPAD(V_TABLA_VIEW(V_REG.DEPT_NO).MEDIA, 10));
END LOOP;
END EJEMPLO_TABLA_INDEXADA_2;
/

También podría gustarte