100% encontró este documento útil (1 voto)
251 vistas39 páginas

PLSQL Esquema HR

Este documento presenta varios ejemplos de código PL/SQL que muestran el uso de bloques anónimos, variables y funciones. Los ejemplos incluyen la visualización de nombres y apellidos separados y concatenados, la creación y uso de variables numéricas y de tipo fecha, y el cálculo de sumas, iniciales y días de la semana de nacimiento usando funciones.

Cargado por

Lara HTML5
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
100% encontró este documento útil (1 voto)
251 vistas39 páginas

PLSQL Esquema HR

Este documento presenta varios ejemplos de código PL/SQL que muestran el uso de bloques anónimos, variables y funciones. Los ejemplos incluyen la visualización de nombres y apellidos separados y concatenados, la creación y uso de variables numéricas y de tipo fecha, y el cálculo de sumas, iniciales y días de la semana de nacimiento usando funciones.

Cargado por

Lara HTML5
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 39

C/Maestro Pedro Pérez Abadía, 2

Instituto de Enseñanza 30100 ESPINARDO (MURCIA)


Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

Práctica bloques anónimos y variables


1-Visualizar el nombre y apellidos. Primero separados y luego concatenados con el ope-
rador ||

SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE('PEPE');
DBMS_OUTPUT.PUT_LINE('RAMÍREZ');
DBMS_OUTPUT.PUT_LINE('PEPE'||' '||'RAMÍREZ');
END;
/

2.Determinar que bloques PL/SQL son correctos.

A/ BEGIN
END;
B/ DECLARE x INTEGER(10);
END;
C/ DECLARE
BEGIN
END;
D/ DECLARE
X INTEGER(10);
BEGIN
DBMS_OUTPUT.PUT_LINE(x);
END;
La solución es el 4, ya que es el único que tiene todos los
componentes. Un bloque BEGIN END debe tener al menos un
comando.

P á g i n a 1 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

3-Crear dos variables de tipo numérico y visualizar su suma

DECLARE
A NUMBER;
B NUMBER;
RESULTADO NUMBER;
BEGIN
A:=10;
B:=20;
RESULTADO:=A+B;
DBMS_OUTPUT.PUT_LINE('RESULTADO:'||RESULTADO);
END;
/

4-Modificar el ejemplo anterior y ponemos null como valor de una de las variables. ¿Qué
resultado arroja? Volvemos a ponerla un valor numérico

DECLARE
A NUMBER;
B NUMBER;
RESULTADO NUMBER;
BEGIN
A:=10;
B:=NULL;
RESULTADO:=A+B;
DBMS_OUTPUT.PUT_LINE('RESULTADO:'||RESULTADO);
END;
/

5-Añadir una constante al ejercicio. Sumamos las 2 variables y las constantes. Intentar
modificar la constante. ¿Es posible?

-- SI INTENTAMOS CAMBIAR UNA CONSTANTE DEBE ARROJAR UN ERROR.


PROBAR INTENTANDO CAMBIAR LA VARIABLE C EN ESTE CASO
DECLARE
A NUMBER;

P á g i n a 2 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

B NUMBER;
C CONSTANT NUMBER :=40;
RESULTADO NUMBER;
BEGIN
A:=10;
B:=20;
RESULTADO:=A+B+C;
DBMS_OUTPUT.PUT_LINE('RESULTADO:'||RESULTADO);
END;
/

6-Crear un bloque anónimo que tenga una variable de tipo VARCHAR2 con nuestro nom-
bre, otra numérica con la edad y una tercera con la fecha de nacimiento. Visualizarlas
por separado y luego intentar concatenarlas. ¿es posible?

-- Visualizarlas por separado y luego intentar


concatenarlas. ¿es posible?
DECLARE
NOMBRE VARCHAR(50):='APASOFT';
EDAD NUMBER:=45;
FECHA_NAC DATE:='16-06-1975';
BEGIN
DBMS_OUTPUT.PUT_LINE(NOMBRE||' '||EDAD||'
'||FECHA_NAC);
END;
/

P á g i n a 3 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

Práctica ámbito de Variables/Bloques


anidados
• Queremos calcular el impuesto de un producto el impuesto del 21% lo ponemos
en una constante creamos una variable de tipo number (5,2) para poner el precio
del producto creamos otra variable para el resultado. le decimos que es del
mismo tipo (type) que la anterior hacemos el cálculo y visualizamos el resultado.

DECLARE
impuesto CONSTANT NUMBER := 21;
precio NUMBER(5, 2);
resultado precio%TYPE;
BEGIN
precio := 100.50;
resultado := precio * impuesto / 100;
dbms_output.put_line(resultado);
END;

Indicar que valores visualiza X en los 3 casos de este ejemplo?

SET SERVEROUTPUT ON
DECLARE X NUMBER:=10;
BEGIN
DBMS_OUTPUT.PUT_LINE(X);
DECLARE X NUMBER:=20;
BEGIN
DBMS_OUTPUT.PUT_LINE(X);
END;
DBMS_OUTPUT.PUT_LINE(X);
END;
/
Solución:10 20 10

P á g i n a 4 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

¿Es este bloque correcto? Si no es así ¿por qué falla?


BEGIN
DBMS_OUTPUT.PUT_LINE(X);
DECLARE
X NUMBER:=20;
BEGIN
DBMS_OUTPUT.PUT_LINE(X);
END;
DBMS_OUTPUT.PUT_LINE(X);
END;/

Sol:
Falla porque la variable X está solo en el bloque anidado y
por tanto no puede ser vista desde el bloque principal.

P á g i n a 5 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

Prácticas funciones PL/SQL


Práctica 1- Iniciales
Crea un bloque PL/SQL con tres variables VARCHAR2: nombre, apellido1, apellido2
Debes visualizar las iniciales separadas por puntos. Además, siempre en mayúscula
Por ejemplo, Alberto Pérez García --> A.P.G
DECLARE
NOMBRE VARCHAR2(20);
APELLIDO1 VARCHAR2(20);
APELLIDO2 VARCHAR2(20);
INICIALES VARCHAR2(6);
BEGIN
NOMBRE:='pedro';
APELLIDO1:='garcia';
APELLIDO2:='Rodrigiuez';

INICIALES:=SUBSTR(NOMBRE,1,1)||'.'||SUBSTR(APELLIDO1,1,1)||
'.'||SUBSTR(APELLIDO2,1,1)||'.';
DBMS_OUTPUT.PUT_LINE(UPPER(INICIALES));
END;
/
Práctica 2- Averiguar el nombre del día que naciste, por ejemplo "Martes"

PISTA (Función TO_CHAR)

DECLARE
FEC_NAC DATE;
DIA_SEMANA VARCHAR2(100);
BEGIN
FEC_NAC:=TO_DATE('10/10/1965');
DIA_SEMANA:=TO_CHAR(FEC_NAC,'DAY');
DBMS_OUTPUT.PUT_LINE(DIA_SEMANA);

P á g i n a 6 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

END;
/

Práctica Comando IF
PRÁCTICA 1
Debemos hacer un bloque PL/SQL anónimo, donde declaramos una variable NUMBER y
la ponemos algún valor.
Debe indicar si el número es PAR o IMPAR. Es decir, debemos usar IF…. ELSE para hacer
el ejercicio.
Como pista, recuerda que hay una función en SQL denominada MOD, que permite
averiguar el resto de una división.
Por ejemplo, MOD (10,4) nos devuelve el resto de dividir 10 por 4.
DECLARE
VALOR NUMBER;
RESULTADO NUMBER;
BEGIN
VALOR :=10;
RESULTADO := MOD(VALOR, 2);
IF RESULTADO = 0 THEN
DBMS_OUTPUT.PUT_LINE('PAR');
ELSE
DBMS_OUTPUT.PUT_LINE('IMPAR');
END IF;
END;
/

PRÁCTICA 2
Crear una variable CHAR(1) denominada TIPO_PRODUCTO.
Poner un valor entre "A" Y "E".
Visualizar el siguiente resultado según el tipo de producto.

P á g i n a 7 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

'A' --> Electronica


'B' --> Informática
'C' --> Ropa
'D' --> Música
'E' --> Libros
Cualquier otro valor debe visualizar "El código es incorrecto".
SET SERVEROUTPUT ON
DECLARE
TIPO_PRODUCTO CHAR(1);
BEGIN
TIPO_PRODUCTO:=UPPER('A');
IF TIPO_PRODUCTO='A' THEN
DBMS_OUTPUT.PUT_LINE('ELECTRÓNICA');
ELSIF TIPO_PRODUCTO='B' THEN
DBMS_OUTPUT.PUT_LINE('INFORMÁTICA');
ELSIF TIPO_PRODUCTO='C' THEN
DBMS_OUTPUT.PUT_LINE('ROPA');
ELSIF TIPO_PRODUCTO='D' THEN
DBMS_OUTPUT.PUT_LINE('MÚSICA');
ELSIF TIPO_PRODUCTO='E' THEN
DBMS_OUTPUT.PUT_LINE('LIBRO');
ELSE
DBMS_OUTPUT.PUT_LINE('EL CÓDIGO ES INCORRECTO');
END IF;
END;

Práctica con CASE


Vamos a crear una variable denominada "usuario", de tipo VARCHAR2(40).
Vamos a poner dentro el nombre del usuario que somos, usando la función USER de
Oracle que devuelve el nombre del usuario con el que estamos conectados (Recuerda
que en Oracle no hace falta poner paréntesis si una función no tiene argumentos).
usuario:= user;

P á g i n a 8 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

Luego hacermos un CASE para que nos pinte un mensaje del estilo:.

• Si el usuario es SYS ponemos el mensaje "Eres superadministrador".


• Si el usuario es SYSTEM ponemos el mensaje "Eres un administrador normal".
• Si el usuario es HR ponemos el mensaje "Eres de Recursos humanos".
• Cualquier otro usuario ponemos "usuario no autorizado.
SET SERVEROUTPUT ON

DECLARE
USUARIO VARCHAR2(30);
BEGIN
USUARIO:=USER;
CASE USUARIO
WHEN 'SYS' THEN DBMS_OUTPUT.PUT_LINE('ERES
SUPERADMINISTRADOR');
WHEN 'SYSTEM' THEN DBMS_OUTPUT.PUT_LINE('ERES
ADMINISTRADOR NORMAL');
WHEN 'HR' THEN DBMS_OUTPUT.PUT_LINE('ERES DE RECURSOS
HUMANOS');
ELSE DBMS_OUTPUT.PUT_LINE('USUARIO NO AUTORIZADO');
END CASE;
END;

Práctica con Bucles


Práctica 1
Vamos a crear la tabla de multiplicar del 1 al 10, con los tres tipos de bucles: LOOP,
WHILE y FOR.
DECLARE
X NUMBER;
Z NUMBER;
BEGIN
X:=1;
Z:=1;
P á g i n a 9 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

LOOP
EXIT WHEN X=11;
DBMS_OUTPUT.PUT_LINE('Tabla de multiplicar del :'||x);
LOOP
EXIT WHEN Z=11;
DBMS_OUTPUT.PUT_LINE(X*Z);
Z:=Z+1;
END LOOP;
Z:=0;
X:=X+1;
END LOOP;
END;
/

DECLARE
X NUMBER;
Z NUMBER;
BEGIN
X:=1;
Z:=1;
WHILE X<11 LOOP
DBMS_OUTPUT.PUT_LINE('Tabla de multiplicar del :'||x);
WHILE Z<11 LOOP
DBMS_OUTPUT.PUT_LINE(X*Z);
Z:=Z+1;
END LOOP;
Z:=0;
X:=X+1;
END LOOP;
END;
/

BEGIN
P á g i n a 10 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

FOR X IN 1..10 LOOP


DBMS_OUTPUT.PUT_LINE('Tabla de multiplicar del :'||x);
FOR Z IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE(X*Z);
END LOOP;
END LOOP;
END;
/
Práctica 2-
Crear una variable llamada TEXTO de tipo VARCHAR2(100).
Poner alguna frase. Mediante un bucle, escribir la frase al revés, Usamos el bucle WHILE.
DECLARE
FRASE VARCHAR2(100);
LIMITE NUMBER;
CONTADOR NUMBER;
FRASE_AL_REVES VARCHAR2(100);
BEGIN
FRASE:='ESTO ES UNA PRUEBA DE FRSE';
LIMITE:=LENGTH(FRASE);
WHILE LIMITE>0 LOOP

FRASE_AL_REVES:=FRASE_AL_REVES||SUBSTR(FRASE,LIMITE,1);
LIMITE:=LIMITE-1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(FRASE_AL_REVES);
END;
/
Práctica 3
Usando la práctica anterior, si en el texto aparece el carácter "x" debe salir del bucle. Es
igual en mayúsculas o minúsculas. Debemos usar la cláusula EXIT.
DECLARE
FRASE VARCHAR2(100);
LIMITE NUMBER;
P á g i n a 11 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

CONTADOR NUMBER;
FRASE_AL_REVES VARCHAR2(100);
BEGIN
FRASE:='ESTO ES UNA PRUEBA DE XRSE';
LIMITE:=LENGTH(FRASE);
WHILE LIMITE>0 LOOP
EXIT WHEN UPPER((SUBSTR(FRASE,LIMITE,1)))='X';

FRASE_AL_REVES:=FRASE_AL_REVES||SUBSTR(FRASE,LIMITE,1);
LIMITE:=LIMITE-1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(FRASE_AL_REVES);
END;
/

Práctica 4
Debemos crear una variable llamada NOMBRE
Debemos pintar tantos asteriscos como letras tenga el nombre. Usamos un bucle FOR
Por ejemplo, Alberto --> *******
DECLARE
NOMBRE VARCHAR2(100);
ASTERISCOS VARCHAR2(100);
BEGIN
NOMBRE:='ALBERTO';
FOR I IN 1..LENGTH(NOMBRE) LOOP
ASTERISCOS:=ASTERISCOS||'*';

END LOOP;
DBMS_OUTPUT.PUT_LINE(NOMBRE ||'-->'||ASTERISCOS);
END;
/

P á g i n a 12 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

Práctica 5
Creamos dos variables numéricas, "inicio y fin"
Las inicializamos con algún valor:
Debemos sacar los números que sean múltiplos de 4 de ese rango.
DECLARE
INICIO NUMBER;
FINAL NUMBER;
BEGIN
INICIO:=10;
FINAL:=200;
FOR I IN INICIO..FINAL LOOP
IF MOD(I,4)=0 THEN
DBMS_OUTPUT.PUT_LINE(I);
END IF;
END LOOP;
END;
/

Práctica con SELECT INTO


Realiza los siguientes ejemplos. Usa %ROWTYPE y %TYPE
PRÁCTICA 1
Crear un bloque PL/SQL que devuelva al salario máximo del departamento 100 y lo deje
en una variable denominada salario_maximo y la visualice
SET SERVEROUTPUT ON
DECLARE
salario_maximo EMPLOYEES.SALARY%TYPE;
BEGIN
SELECT MAX(SALARY) INTO salario_maximo
FROM EMPLOYEES
WHERE DEPARTMENT_ID=100;
DBMS_OUTPUT.PUT_LINE('el salario máximo de ese departamento
es:'||salario_maximo);

P á g i n a 13 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

END;
PRÁCTICA2
Visualizar el tipo de trabajo del empleado número 100
set serveroutput on
DECLARE
TIPO_TRABAJO employees.JOB_ID%TYPE;
BEGIN
select job_id into tipo_trabajo from employees
where employee_id=100;
dbms_output.put_line('El tipo de trabajo del
empleado 100 es:'||tipo_trabajo);
end;
/
PRÁCTICA 3
Crear una variable de tipo DEPARTMENT_ID y ponerla algún valor, por ejemplo 10.
Visualizar el nombre de ese departamento y el número de empleados que tiene,
poniendo. Crear dos variables para albergar los valores.
set serveroutput on
DECLARE
COD_DEPARTAMENTO DEPARTMENTS.DEPARTMENT_ID%TYPE:=10;
NOM_DEPARTAMENTO DEPARTMENTS.DEPARTMENT_NAME%TYPE;
NUM_EMPLE NUMBER;
BEGIN
--RECUPERAR EL NOMBRE DEL DEPARTAMENTO
SELECT DEPARTMENT_NAME INTO NOM_DEPARTAMENTO FROM
DEPARTMENTS WHERE DEPARTMENT_ID=COD_DEPARTAMENTO;
--RECUPERAR EL NÚMERO DE EMLEADOS DEL DEPARTAMENTO
SELECT COUNT(*) INTO NUM_EMPLE FROM EMPLOYEES WHERE
DEPARTMENT_ID=COD_DEPARTAMENTO;
DBMS_OUTPUT.PUT_LINE('EL DEPARTAMENTO
'||NOM_DEPARTAMENTO||' TIENE '||NUM_EMPLE||' EMPLEADOS');
END;
/
P á g i n a 14 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

PRÁCTICA 4
Mediante dos consultas recuperar el salario máximo y el salario mínimo de la empresa e
indicar su diferencia
DECLARE
MAXIMO NUMBER;
MINIMO NUMBER;
DIFERENCIA NUMBER;
BEGIN
SELECT MAX(SALARY),MIN(SALARY) INTO MAXIMO,MINIMO
FROM EMPLOYEES;
DBMS_OUTPUT.PUT_LINE('EL SALARIO MÁXIMO ES:'||MAXIMO);
DBMS_OUTPUT.PUT_LINE('EL SALARIO MÍNIMO ES:'||MINIMO);
DIFERENCIA:=MAXIMO-MINIMO;
DBMS_OUTPUT.PUT_LINE('LA DIFERENCIA ES:'||DIFERENCIA);
END;
/

Práctica con inserts, updates y deletes


1- Crear un bloque que inserte un nuevo departamento en la tabla DEPARTMENTS. Para
saber el DEPARTMENT_ID que debemos asignar al nuevo departamento primero
debemos averiguar el valor mayor que hay en la tabla DEPARTMENTS y sumarle uno
para la nueva clave.
• Location_id debe ser 1000
• Manager_id debe ser 100
• Department_name debe ser “INFORMATICA”
NOTA: en PL/SQL debemos usar COMMIT y ROLLBACK de la misma forma que lo
hacemos en SQL. Por tanto, para validar definitivamente un cambio debemos usar
COMMIT.
DECLARE
MAX_ID NUMBER;
BEGIN
SELECT MAX(DEPARTMENT_ID) INTO MAX_ID FROM DEPARTMENTS;
MAX_ID:=MAX_ID+1;

P á g i n a 15 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

INSERT INTO departments (department_id, department_name,


manager_id, location_id)
VALUES (MAX_ID,'INFORMATICA',100,1000);
COMMIT;
END;

2-Crear un bloque PL/SQL que modifique la LOCATION_ID del nuevo departamento a


1700. En este caso usemos el COMMIT dentro del bloque PL/SQL.
BEGIN
UPDATE DEPARTMENTS SET LOCATION_ID=1700
WHERE DEPARTMENT_NAME='INFORMATICA';
COMMIT;
END;
3.- Por último, hacer otro bloque PL/SQL que elimine ese departamento nuevo.
BEGIN
DELETE DEPARTMENTS
WHERE DEPARTMENT_NAME='INFORMATICA';
COMMIT;
END;

PRÁCTICAS CON EXCEPCIONES


1- Crear una SELECT (no un cursor explícito) que devuelva el nombre de un empleado
pasándole el EMPLOYEE_ID en el WHERE.

• Comprobar en primer lugar que funciona pasando un empleado existente.


• Pasar un empleado inexistente y comprobar que genera un error.
• Crear una zona de EXCEPTION controlando el NO_DATA_FOUND para que pinte
un mensaje como “Empleado inexistente”.

DECLARE
nombre_empleado employees.first_name%TYPE;
BEGIN
SELECT first_name INTO nombre_empleado FROM employees

P á g i n a 16 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

WHERE employee_id=1000; --EMPLEADO INEXISTENTE


DBMS_OUTPUT.PUT_LINE(nombre_empleado);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No existe el empleado.');
END;
/
2-Modificar la SELECT para que devuelva más de un empleado, por ejemplo, poniendo
EMPLOYEE_ID> 100. Debe generar un error. Controlar la excepción para que genere un
mensaje como “Demasiados empleados en la consulta”.
DECLARE
nombre_empleado employees.first_name%TYPE;
BEGIN
SELECT first_name INTO nombre_empleado FROM employees
WHERE employee_id=1000;
DBMS_OUTPUT.PUT_LINE(nombre_empleado);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No existe el empleado.');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Empleado duplicado.');
END;
/
3-Modificar la consulta para que devuelva un error de división por CERO, por ejemplo,
vamos a devolver el salario en vez del nombre y lo dividimos por 0. En este caso, en vez
de controlar la excepción directamente, creamos una sección WHEN OTHERS y pintamos
el error con SQLCODE y SQLERR.
DECLARE
nombre_empleado employees.first_name%TYPE;
salario number;
BEGIN
SELECT salary iNTO salario
FROM
employees

P á g i n a 17 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

WHERE
employee_id = 100;
salario:=salario/0;
dbms_output.put_line(salario);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No existe el empleado.');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Empleado duplicado.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('CODIGO:'||SQLCODE);
DBMS_OUTPUT.PUT_LINE('MENSAJE:'||SQLERRM);
END;
/
4-El error -00001 es clave primaria duplicada. Aunque ya existe una predefinida
(DUP_VAL_ON_INDEX) vamos a crear una excepción no -predefinida que haga lo mismo.
o Vamos a usar la tabla REGIONS para hacerlo más fácil o Usamos PRAGMA
EXCEPTION_INIT y creamos una excepción denominada “duplicado”. Cuando se genere
ese error debemos pintar “Clave duplicada, intente otra”. o Insertamos una fila en la
tabla REGIONS que esté duplicada y vemos que se controla el error.
set serveroutput on
DECLARE
duplicado EXCEPTION;
PRAGMA EXCEPTION_INIT(duplicado,-00001);
BEGIN
INSERT INTO REGIONS VALUES (1,'PRUEBA');
COMMIT;
EXCEPTION
when duplicado then
dbms_output.put_line('Registro duplicado');
End;

P á g i n a 18 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

PRÁCTICA CON EXCEPCIONES DE


USUARIO
Crear una Excepción personalizada denominada CONTROL_REGIONES.
• Debe dispararse cuando al insertar o modificar una región queramos poner una
clave superior a 200. Por ejemplo, usando una variable con ese valor.

• En ese caso debe generar un texto indicando algo así como “Código no
permitido. Debe ser inferior a 200”
• Recordemos que las excepciones personalizadas deben dispararse de forma
manual con el RAISE.
SET SERVEROUTPUT ON
DECLARE
CONTROL_REGIONES EXCEPTION;
CODIGO NUMBER:=201;
BEGIN
if codigo > 200 then
raise control_regiones;
else
INSERT INTO REGIONS VALUES (CODIGO,'PRUEBA');
end if;
exception
when control_regiones then
dbms_output.put_line('El codigo debe ser inferior a 200');
when others then
dbms_output.put_line(SQLcode);
dbms_output.put_line(SQLERRM);
END;
/

P á g i n a 19 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

PRÁCTICAS DE COLECCIONES Y
RECORDS
Creamos un TYPE RECORD que tenga las siguientes columnas

NAME VARCHAR2(100),
SAL EMPLOYEES.SALARY%TYPE,
COD_DEPT EMPLOYEES.DEPARTMENT_ID%TYPE);
Creamos un TYPE TABLE basado en el RECORD anterior
Mediante un bucle cargamos en la colección los empleados. El campo NAME debe
contener FIRST_NAME y LAST_NAME concatenado.
Para cargar las filas y siguiendo un ejemplo parecido que hemos visto en el vídeo usamos
el EMPLOYEE_ID que va de 100 a 206
A partir de este momento y ya con la colección cargada, hacemos las siguientes
operaciones, usando métodos de la colección.
• Visualizamos toda la colección.
• Visualizamos el primer empleado.
• Visualizamos el último empleado.
• Visualizamos el número de empleados.
• Borramos los empleados que ganan menos de 7000 y visualizamos de nuevo la
colección.
• Volvemos a visualizar el número de empleados para ver cuantos se han borrado.

SET SERVEROUTPUT ON
DECLARE
TYPE EMPL_RECORD IS RECORD
(
NAME VARCHAR2(100),
SAL EMPLOYEES.SALARY%TYPE,
COD_DEPT EMPLOYEES.DEPARTMENT_ID%TYPE);

P á g i n a 20 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

TYPE EMPL_TABLE IS TABLE OF


EMPL_RECORD
INDEX BY PLS_INTEGER;

EMPL EMPL_TABLE;
BEGIN
FOR I in 100..206 LOOP
SELECT FIRST_NAME||' '||LAST_NAME, SALARY, DEPARTMENT_ID
INTO EMPL(I) FROM EMPLOYEES
WHERE EMPLOYEE_ID=I;
END LOOP;

FOR I IN EMPL.FIRST..EMPL.LAST LOOP


DBMS_OUTPUT.PUT_LINE(EMPL(I).NAME||' '||EMPL(I).SAL||'
'||EMPL(I).COD_DEPT);
END LOOP;
DBMS_OUTPUT.PUT_LINE('EL PRIMERO');
DBMS_OUTPUT.PUT_LINE(EMPL(EMPL.FIRST).NAME);
DBMS_OUTPUT.PUT_LINE('EL ÚLTIMO');
DBMS_OUTPUT.PUT_LINE(EMPL(EMPL.LAST).NAME);
DBMS_OUTPUT.PUT_LINE('BORRAMOS LOS EMPLEADOS QUE GANEN MENOS
DE 7000');
DBMS_OUTPUT.PUT_LINE('ANTES');
DBMS_OUTPUT.PUT_LINE(EMPL.COUNT);
FOR I IN EMPL.FIRST..EMPL.LAST LOOP
IF EMPL(I).SAL < 7000 THEN
EMPL.DELETE(I) ;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('DESPUES');
DBMS_OUTPUT.PUT_LINE(EMPL.COUNT);

END;
P á g i n a 21 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

PRÁCTICAS CON CURSORES


1-Hacer un programa que tenga un cursor que vaya visualizando los salarios de los em-
pleados. Si en el cursor aparece el jefe (Steven King) se debe generar un RAISE_APPLI-
CATION_ERROR indicando que el sueldo del jefe no se puede ver.

DECLARE
CURSOR C1
IS SELECT first_name,last_name,salary from EMPLOYEES;
BEGIN
for i IN C1
LOOP
IF i.first_name='Steven' AND i.last_name='King'
THEN
raise_application_error(-20300,'El salario del jefe no puede
ser visto');
ELSE
DBMS_OUTPUT.PUT_LINE(i.first_name ||' ' || i.last_name || ':
'|| i.salary || 'DLS');
END IF;
END LOOP;
END;

2-Hacemos un bloque con dos cursores. (Esto se puede hacer fácilmente con una sola
SELECT, pero vamos a hacerlo de esta manera para probar parámetros en cursores).

• el primero de empleados
• El segundo de departamentos que tenga como parámetro el MANAGER_ID
• Por cada fila del primero, abrimos el segundo curso pasando el ID del MANAGER
• Debemos pintar el Nombre del departamento y el nombre del MANAGER_ID
• Si el empleado no es MANAGER de ningún departamento debemos poner “No
es jefe de nada”
SET SERVEROUTPUT ON
DECLARE
P á g i n a 22 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

DEPARTAMENTO DEPARTMENTS%ROWTYPE;
jefe DEPARTMENTS.MANAGER_ID%TYPE;
CURSOR C1 IS SELECT * FROM EMployees;
CURSOR C2(j DEPARTMENTS.MANAGER_ID%TYPE)
IS SELECT * FROM DEPARTMENTS WHERE MANAGER_ID=j;
begin
for EMPLEADO in c1 loop
open c2(EMPLEADO.employee_id) ;
FETCH C2 into departamento;
if c2%NOTFOUND then
DBMS_OUTPUT.PUT_LINE(EMPLEADO.FIRST_NAME ||' No es JEFE de
NADA');
ELSE
DBMS_OUTPUT.PUT_LINE(EMPLEADO.FIRST_NAME || 'ES JEFE DEL
DEPARTAMENTO '|| DEPARTAMENTO.DEPARTMENT_NAME);
END IF;
CLOSE C2;
END LOOP;
END;
3-Crear un cursor con parámetros que pasando el número de departamento visualice el
número de empleados de ese departamento.
SET SERVEROUTPUT ON
DECLARE
CODIGO DEPARTMENTS.DEPARTMENT_ID%TYPE;
CURSOR C1(COD DEPARTMENTS.DEPARTMENT_ID%TYPE ) IS SELECT
COUNT(*) FROM employeeS
WHERE DEPARTMENT_ID=COD;
NUM_EMPLE NUMBER;
BEGIN
CODIGO:=10;
OPEN C1(CODIGO);
FETCH C1 INTO NUM_EMPLE;

P á g i n a 23 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

DBMS_OUTPUT.PUT_LINE('numero de empleados de ' ||codigo||'


es '||num_emple);
end;
4-Crear un bucle FOR donde declaramos una subconsulta que nos devuelva el nombre
de los empleados que sean ST_CLERCK. Es decir, no declaramos el cursor, sino que lo
indicamos directamente en el FOR.
BEGIN
FOR EMPLE IN(SELECT * FROM EMPLOYEES WHERE
JOB_ID='ST_CLERK') LOOP
DBMS_OUTPUT.PUT_LINE(EMPLE.FIRST_NAME);
END LOOP;
END;

5-Creamos un bloque que tenga un cursor para empleados. Debemos crearlo con FOR
UPDATE.
• Por cada fila recuperada, si el salario es mayor de 8000 incrementamos el salario
un 2%
• Si es menor de 800 lo hacemos en un 3%
• Debemos modificarlo con la cláusula CURRENT OF
• Comprobar que los salarios se han modificado correctamente.
SET SERVEROUTPUT ON
DECLARE
CURSOR C1 IS SELECT * FROM EMployees for update;
begin
for EMPLEADO IN C1 LOOP
IF EMPLEADO.SALARY > 8000 THEN
UPDATE EMPLOYEES SET SALARY=SALARY*1.02
WHERE CURRENT OF C1;
ELSE
UPDATE EMPLOYEES SET SALARY=SALARY*1.03
WHERE CURRENT OF C1;
END IF;
END LOOP;

P á g i n a 24 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

COMMIT;
END ;

PRÁCTICAS CON PROCEDIMIENTOS Y


PARÁMETROS
1- Crear un procedimiento llamado visualizar que visualice el nombre y salario de
todos los empleados.
CREATE OR REPLACE PROCEDURE visualizar IS
CURSOR C1 IS SELECT first_name,salary FROM EMPLOYEES;
v_nombre employees.first_name%TYPE;
v_salario employees.salary%TYPE;
BEGIN
FOR i IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(i.first_name || ' ' || i.salary);
END LOOP;
END;
/
EXECUTE visualizar;
2- Modificar el programa anterior para incluir un parámetro que pase el número de
departamento para que visualice solo los empleados de ese departamento
• Debe devolver el número de empleados en una variable de tipo OUT
create or replace PROCEDURE visualizar(departamento NUMBER,
numero OUT NUMBER) IS
CURSOR C1 IS SELECT first_name,salary FROM EMPLOYEES WHERE
department_id=departamento;
v_nombre employees.first_name%TYPE;
v_salario employees.salary%TYPE;
BEGIN
NUMERO:=0;
FOR i IN C1

P á g i n a 25 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

LOOP
DBMS_OUTPUT.PUT_LINE(i.first_name || ' ' || i.salary);
NUMERO:=NUMERO+1;
END LOOP;

END;

DECLARE
x NUMBER;
BEGIN
visualizar(60,x);
DBMS_OUTPUT.PUT_LINE('El número de empleados es:'||x);
END;
/
3- crear un bloque por el cual se de formato a un nº de cuenta suministrado por
completo, por ej , 11111111111111111111

• Formateado a: 1111-1111-11-1111111111
• Debemos usar un parámetro de tipo IN-OUT
CREATE OR REPLACE PROCEDURE formateo_cuenta (numero IN OUT
VARCHAR2)
IS
guardar1 VARCHAR2(20);
guardar2 VARCHAR2(20);
guardar3 VARCHAR2(20);
guardar4 VARCHAR2(20);
BEGIN
guardar1:=substr(numero,1,4);
guardar2:=substr(numero,5,4);
guardar3:=substr(numero,9,2);
guardar4:=substr(numero,10);

P á g i n a 26 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

numero:=guardar1 || '-' || guardar2 || '-' || guardar3 || '-


' || guardar4;
END;
/

DECLARE
x varchar2(30):='15210457901111111111';
BEGIN
formateo_cuenta(x);
dbms_output.put_line(x);
END;

P á g i n a 27 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

PRACTICA DE FUNCIONES
1-Crear una función que tenga como parámetro un número de departamento y que
devuelve la suma de los salarios de dicho departamento. La imprimimos por pantalla.

• Si el departamento no existe debemos generar una excepción con dicho mensaje


create or replace FUNCTION salarios_dept(dep_id NUMBER)
RETURN NUMBER
IS
TOTAL_SAL NUMBER;
dept DEPARTMENTS.department_id%TYPE;
BEGIN
--COMPROBAR QUE EL DEPARTAMENTO EXISTE. SI NO EXISTE SE
DISPARA LA EXCEPCIÓN
SELECT DEPARTMENT_ID INTO DEPT FROM DEPARTMENTS WHERE
DEPARTMENT_ID=DEP_ID;
--SI EL DEPARTAMENTO EXISTE CALCULAR EL TOTAL
SELECT sum(salary) INTO TOTAL_SAL from employees where
department_id=dep_id group by department_id;
RETURN TOTAL_SAL;
EXCEPTION
WHEN NO_DATA_FOUND THEN
--SI EL DEPARTAMENTO NO EXISTE DEVUELVE ERROR
RAISE_APPLICATION_ERROR(-20001,'ERROR, DEPARTAMENTO
'||DEP_ID|| ' NO EXISTE');
END;

--PROBAR LA FUNCIÓN
SET SERVEROUTPUT ON
DECLARE
SAL NUMBER;
DEPT NUMBER:=100;
BEGIN
SAL:=salarios_dept(DEPT);
P á g i n a 28 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

DBMS_OUTPUT.PUT_LINE('El salario total del departamento ' ||


DEPT || ' es: ' || SAL);
END;
/
2-Modificar el programa anterior para incluir un parámetro de tipo OUT por el que vaya
el número de empleados afectados por la query. Debe ser visualizada en el programa
que llama a la función. De esta forma vemos que se puede usar este tipo de parámetros
también en una función
CREATE OR REPLACE FUNCTION salarios_dept1(dep_id NUMBER,
n_empleados OUT NUMBER) RETURN NUMBER
IS
sal NUMBER;
BEGIN
--COMPROBAR QUE EL DEPARTAMENTO EXISTE. SI NO EXISTE
SE DISPARA LA EXCEPCIÓN
SELECT DEPARTMENT_ID INTO DEPT FROM DEPARTMENTS WHERE
DEPARTMENT_ID=DEP_ID;
--SI EL DEPARTAMENTO EXISTE CALCULAR TOTALES
SELECT sum(salary),count(salary) INTO SAL,n_empleados
from employees where department_id=dep_id group by
department_id;
RETURN sal;
END;
/

--PROBAR LA FUNCIÓN
set serveroutput on
declare
TOTAL_SAL NUMBER;
NUM_EMPLE NUMBER;
DEPT NUMBER:=110;
BEGIN
TOTAL_SAL:=salarios_dept1(DEPT,NUM_EMPLE);

P á g i n a 29 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

DBMS_OUTPUT.PUT_LINE('El salario total del departamento ' ||


DEPT || ' es: ' || TOTAL_SAL);
DBMS_OUTPUT.PUT_LINE('El número total de empleados recabados
es : ' || NUM_EMPLE);
END;

3-Crear una función llamada CREAR_REGION


• A la función se le debe pasar como parámetro un nombre de región y debe
devolver un número, que es el código de región que calculamos dentro de la
función
• Se debe crear una nueva fila con el nombre de esa REGION
• El código de la región se debe calcular de forma automática. Para ello se debe
averiguar cuál es el código de región más alto que tenemos en la tabla en ese
momento, le sumamos 1 y el resultado lo ponemos como el código para la nueva
región que estamos creando.
• Si tenemos algún problema debemos generar un error
• La función debe devolver el número que ha asignado a la región

create or replace FUNCTION CREAR_REGION (nombre varchar2)


RETURN NUMBER IS
regiones NUMBER;
NOM_REGION VARCHAR2(100);
BEGIN
--AVERIGUAR SI EXISTE LA REGIÓN. SI YA EXISTE DAMOS
ERROR. SI NO EXISTE PASAMOS A EXCEPTION Y SEGUIMOS CON EL
PROGRAMA
SELECT REGION_NAME INTO NOM_REGION FROM REGIONS WHERE
REGION_NAME=UPPER(NOMBRE);
raise_application_error(-20321,'Esta región ya
existe!');
EXCEPTION
-- SI LA REGION NO EXISTE LA INSERTAMOS. ES UN EJEMPLO
DE COMO PODEMOS USAR LA EXCEPCION PARA HACER ALGO CORRECTO

P á g i n a 30 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

WHEN NO_DATA_FOUND THEN


SELECT MAX(REGION_ID)+1 INTO REGIONES from REGIONS;
INSERT INTO REGIONS (region_id,region_name) VALUES
(regiones,upper(nombre));
RETURN REGIONES;
END;
/

--PROBAR LA FUNCIÓN

DECLARE
N_REGION NUMBER;
BEGIN
N_REGION:=crear_region('NORMANDIA');
DBMS_OUTPUT.PUT_LINE('EL NUMERO ASIGNADO ES:'||N_REGION);
END;
/

PRÁCTICA CON PAQUETES


1- Crear un paquete denominado REGIONES que tenga los siguientes componentes:

• PROCEDIMIENTOS:
- ALTA_REGION, con parámetro de código y nombre Región. Debe devolver un
error si la región ya existe. Inserta una nueva región en la tabla. Debe llamar a la función
EXISTE_REGION para controlarlo.
- BAJA_REGION, con parámetro de código de región y que debe borrar una región.
Debe generar un error si la región no existe, Debe llamar a la función EXISTE_REGION
para controlarlo
- MOD_REGION: se le pasa un código y el nuevo nombre de la región Debe modificar
el nombre de una región ya existente. Debe generar un error si la región no existe, Debe
llamar a la función EXISTE_REGION para controlarlo
• FUNCIONES
o CON_REGION. Se le pasa un código de región y devuelve el nombre

P á g i n a 31 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

o EXISTE_REGION. Devuelve verdadero si la región existe. Se usa en los


procedimientos y por tanto es PRIVADA, no debe aparecer en la
especificación del paquete.
--PACKAGE HEAD
CREATE OR REPLACE PACKAGE regiones IS
PROCEDURE alta_region ( codigo NUMBER,nombre VARCHAR2 );
PROCEDURE baja_region ( id NUMBER );
PROCEDURE mod_region ( id NUMBER,nombre VARCHAR2 );
FUNCTION con_regiom ( codigo NUMBER ) RETURN VARCHAR2;
END regiones;
/

--BODY / PROCEDURE ALTA REGIÓN


CREATE OR REPLACE PACKAGE BODY regiones IS
--FUNCIÓN EXISTE_REGION
FUNCTION existe_region ( id NUMBER,nombre VARCHAR2 ) RETURN
BOOLEAN IS
CURSOR c1 IS
SELECT region_name,region_id FROM regions;
y VARCHAR2(20);
BEGIN
FOR i IN c1 LOOP
IF i.region_name = nombre AND i.region_id = id THEN
RETURN true;
END IF;
END LOOP;
RETURN false;
END;

PROCEDURE alta_region ( codigo NUMBER,nombre VARCHAR2 ) IS


devuelto BOOLEAN;
BEGIN
devuelto := existe_region(codigo,nombre);

P á g i n a 32 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

IF devuelto = false THEN


INSERT INTO regions ( region_id,region_name ) VALUES (
codigo,nombre );
dbms_output.put_line('Inserción correcta');
ELSE
dbms_output.put_line('La región ya existe.');
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('La ID YA EXISTE (duplicada)');
END;

--PROCEDURE BAJA_REGION
PROCEDURE baja_region ( id NUMBER ) IS
devuelto BOOLEAN;
otro VARCHAR2(20);
BEGIN
SELECT region_name INTO otro FROM regions
WHERE region_id = id;
devuelto := existe_region(id,otro);
IF devuelto = true THEN
DELETE FROM regions WHERE region_id = id;
dbms_output.put_line('Región con ID ' || id || ' borrada');
END IF;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('La región no existe!');
END;

--PROCEDURE MOD_REGION
PROCEDURE mod_region ( id NUMBER,nombre VARCHAR2 ) IS
devuelto BOOLEAN;
BEGIN
P á g i n a 33 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

devuelto := existe_region(id,nombre);
IF devuelto = true THEN
UPDATE regions
SET region_name = nombre
WHERE region_id = id;
dbms_output.put_line('La región ha sido actualizada.');
ELSE
dbms_output.put_line('La región no existe.');
END IF;
END;

--FUNCIÓN CON_REGIOM
FUNCTION con_regiom ( codigo NUMBER ) RETURN VARCHAR2 IS
nombre_devolver VARCHAR2(20);
BEGIN
SELECT region_name INTO nombre_devolver FROM regions
WHERE region_id = codigo;
RETURN nombre_devolver;
END;
END regiones;
/

EXECUTE mod_region(7,'pikachutotal');
EXECUTE regiones.baja_region(10);
EXECUTE regiones.alta_region(10,'Prueba');
SELECT * FROM regions;
DELETE FROM regions WHERE
region_id > 4;
ROLLBACK;
2-Crear un paquete denominado NOMINA que tenga sobrecargado la función
CALCULAR_NOMINA de la siguiente forma:

• CALCULAR_NOMINA(NUMBER): se calcula el salario del empleado restando un


15% de IRPF.

P á g i n a 34 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

• CALCULAR_NOMINA(NUMBER,NUMBER): el segundo parámetro es el


porcentaje a aplicar. Se calcula el salario del empleado restando ese porcentaje
al salario
• CALCULAR_NOMINA(NUMBER,NUMBER,CHAR): el segundo parámetro es el
porcentaje a aplicar, el tercero vale ‘V’ . Se calcula el salario del empleado
aumentando la comisión que le pertenece y restando ese porcentaje al salario
siempre y cuando el empleado tenga comisión.
CREATE OR REPLACE PACKAGE NOMINA IS
function calcular_nomina(id number) RETURN NUMBER;
function calcular_nomina(id number,porcentaje varchar)
RETURN NUMBER;
function calcular_nomina(id number,porcentaje number,
tercero varchar2:='V') RETURN NUMBER;
END NOMINA;
/

CREATE OR REPLACE PACKAGE BODY NOMINA IS


--PRIMERA FUNCION

FUNCTION calcular_nomina ( id NUMBER ) RETURN NUMBER IS


salario_final NUMBER;
salario NUMBER;
BEGIN
SELECT salary INTO salario from employees where
employee_id=id;
salario_final := salario - ( salario * 0.15 );
RETURN salario_final;
END;
--SEGUNDA FUNCION
FUNCTION calcular_nomina ( id NUMBER,porcentaje varchar )
RETURN NUMBER IS
salario_final NUMBER;
salario NUMBER;
BEGIN

P á g i n a 35 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

SELECT salary INTO salario from employees where


employee_id=id;
salario_final := salario - ( salario *
(to_number(porcentaje) / 100 ));
RETURN salario_final;
END;

--TERCERA FUNCION
FUNCTION calcular_nomina ( id NUMBER, porcentaje NUMBER,
tercero VARCHAR2 := 'V') RETURN NUMBER IS
salario_final NUMBER;
comision NUMBER;
salario NUMBER;
BEGIN
SELECT salary into salario from employees where
employee_id=id;
SELECT commission_pct into comision from employees where
employee_id=id;
salario_final := salario - ( salario * (porcentaje/100 )) +
(salario*comision);
RETURN salario_final;
END;
END NOMINA;
/

declare
x number;
BEGIN
x:=NOMINA.CALCULAR_NOMINA(150,'8');
DBMS_OUTPUT.PUT_LINE(x);
END;
/
P á g i n a 36 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

desc nomina;

PRÁCTICAS CON TRIGGERS


1- Crear un TRIGGER BEFORE DELETE sobre la tabla EMPLOYEES que impida borrar un
registro si su JOB_ID es algo relacionado con CLERK
CREATE OR REPLACE TRIGGER t1 BEFORE
DELETE ON employees FOR EACH ROW
BEGIN
IF
:old.job_id LIKE ( '%CLERK' )
THEN
raise_application_error(-20320,'NADA');
END IF;
END;
/
select * from employees;
delete from employees where job_id LIKE ('%CLERK');
2- Crear una tabla denominada AUDITORIA con las siguientes columnas:
CREATE TABLE AUDITORIA (USUARIO VARCHAR(50),FECHA
DATE,SALARIO_ANTIGUO NUMBER,SALARIO_NUEVO NUMBER);

3-Crear un TRIGGER BEFORE INSERT de tipo STATEMENT, de forma que cada vez que se
haga un INSERT en la tabla REGIONS guarde una fila en la tabla AUDITORIA con el usuario
y la fecha en la que se ha hecho el INSERT

CREATE TRIGGER T2 BEFORE INSERT ON REGIONS


BEGIN
INSERT INTO AUDITORIA (usuario, fecha)
VALUES (user,sysdate);
END;
/
INSERT INTO REGIONS VALUES (20,'Prueba');
P á g i n a 37 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

SELECT USER FROM DUAL;


select * from auditoria;

4- Realizar otro trigger BEFORE UPDATE de la columna SALARY de tipo EACH ROW. Si la
modificación supone rebajar el salario el TRIGGER debe disparar un
RAISE_APPLICATION_FAILURE “no se puede bajar un salario”. Si el salario es mayor
debemos dejar el salario antiguo y el salario nuevo en la tabla AUDITORIA.
create or replace TRIGGER TRIGGER_salario
BEFORE UPDATE ON EMPLOYEES
FOR EACH ROW
BEGIN
IF :NEW.SALARY< :OLD.SALARY THEN
RAISE_APPLICATION_ERROR(-20000,'NO SE PUEDE BAJAR EL
SALARIO');
END IF;
IF :NEW.SALARY> :OLD.SALARY THEN
INSERT INTO AUDITORIA VALUES
(USER,SYSDATE,:OLD.SALARY,:NEW.SALARY);
END IF;
END;

5-Crear un TRIGGER BEFORE INSERT en la tabla DEPARTMENTS que al insertar un


departamento compruebe que el código no esté repetido y luego que si el LOCATION_ID
es NULL le ponga 1700 y si el MANAGER_ID es NULL le ponga 200.
CREATE OR REPLACE TRIGGER TRIGGER1
BEFORE INSERT ON DEPARTMENTS
FOR EACH ROW
declare
deptno number;
BEGIN
select department_id into deptno from departments where
department_id=:new.department_id;
RAISE_APPLICATION_ERROR(-20000,'Departamento ya existe');

P á g i n a 38 | 39
C/Maestro Pedro Pérez Abadía, 2
Instituto de Enseñanza 30100 ESPINARDO (MURCIA)
Región de Murcia Telf: 968 83 46 90
Secundaria
Consejería de Educación y 968 83 46 05
Fax: 968 83 46 07
Cultura José Planes e-mail: [email protected]
www.iesjoseplanes.es

EXCEPTION
WHEN NO_DATA_FOUND THEN
if :new.location_id is null then
:new.location_id:=1700;
end if;
if :new.manager_id is null then
:new.manager_id:=200;
end if;
END;

P á g i n a 39 | 39

También podría gustarte