Libro Ejercicios SQL PLSQ Completo
Libro Ejercicios SQL PLSQ Completo
Libro Ejercicios SQL PLSQ Completo
EJER CICIO S
2.- Selecionar los empleados con salario superior a 2000 y con el trabajo de DIRECTOR
SELECT APELLIDO FROM EMPLE WHERE SALARIO > 2000 AND OFICIO LIKE ‘DIRECTOR’;
4.- Selecionar todos los empleados del departamento nº 20 y ademas debe de estar
ordenado por el apellido y tienen que aparecer en la consulta el nº del empleado, el
apellido, el oficio y el nº de departamento.
5.- Empleados cuyo oficio sea analista, ordenado por el número del empleado.
SELECT APELLIDO FROM EMPLE WHERE OFICIO LIKE ‘ANALISTA’ ORDER BY EMP_NO;
6.- Seleccionar las filas del departamento 10 cuyo oficio sea analista. La consulta debe
de estar ordenada descendentemente por el apellido y tambien descendentemente por
el nº empleado.
SELECT DEPT_NO FROM EMPLE WHERE (OFICIO LIKE 'ANALISTA' AND ORDER BY
EMP_NO DESC , ORDER BY APELLIDO DESC);
8.- Seleccionar los nombres de los alumnos y su nota de la tabla notas_alumnos siendo
scott el propietario de la tabla.
10.- Seleccionar los alumnos que de la nota1 hayan sacado un 7 y que la media de las 3
notas sea mayor que 6
11.- Seleccionar los nombres de los alumnos y su nota siendo esta mayor o igual a 5 y
su curso primero.
SELECT APELLIDO FROM EMPLE WHERE OFICIO LIKE 'VENDEDOR' OR OFICIO LIKE
'ANALISTA' OR OFICIO LIKE 'EMPLEADO';
SELECT APELLIDO, SALARIO, DEPT_NO FROM EMPLE WHERE SALARIO > 125000 AND
DEPT_NO IN (10,20);
SELECT ... FROM WHERE...
16.- Seleccionar la lista de empleados indicando para cada uno su apellido, oficio, fecha
de alta y el salario con un aumento del 16%.
SELECT DNOME FROM DEPART WHERE LOC LIKE NOT 'MADRID',LOC LIKE NOT 'BILBAO');
25.- Seleccionar los empleados cuya fecha de alta este entre entre el 8/9/61 y el
27/2/82.
SELECT APELLIDO FROM EMPLE WHERE FECHA_ALT BETWEEN '8/9/61' AND '27/2/82');
26.- seleccionar los departamentos que terminen en n y tengan una o en su interior.
SELECT DNOMBRE FROM DEPART WHERE DNOMBRE LIKE '%O%N' OR DNOMBRE LIKE 'O%N';
27.- Seleccionar los empleados que tengan una A en el apellido y una V en su oficio en
la posicion que sea.
SELECT APELLIDO FROM EMPLE WHERE APELLIDO LIKE '%A%' AND POBLACION LIKE '%V%';
28.- seleccionar los empelados cuyo salario sea mayor de 20000 y menor que 50000.
SELECT APELLIDO FROM EMPLE WHERE SALARIO>20000 AND SALARIO < 50000;
SELECT APELLIDO FROM EMPLE WHERE DEPT_NO IN (SELECT DEPT_NO FROM DEPART
WHERE LOC IN ('MADRID','BARCELONA'));
2.- Seleccionar el apellido y el oficio de todos los empleados del departamento 20 cuyo
trabajo sea identico al de los empleados del departamento ventas.
SELECT APELLIDO,OFICIO FROM EMPLE WHERE DEPT_NO=20 AND OFICIO IN( SELECT
OFICIO FROM EMPLE WHERE DEPT_NO =(SELECT DEPT_NO FROM DEPART WHERE
DNOMBRE='VENTAS'));
3.- Obtener el departamento de los empleados con el mismo oficio y el salario de 'Gil'.
1.- seleccionar de la tabla emple aquellas filas cuyo apellido empiece por A y el oficio
tenga una e en cualquier posición.
SELECT APELLIDO,OFICIO FROM EMPLE WHERE APELLIDO LIKE '%A' OR OFICIO LIKE '%E%';
3.- Mostrar los empleados (nombre, oficio, salario y fecha de alta) que desempeñen el
mismo oficio que JIMENEZ o que tengan el salario mayor o igual a FERNANDEZ.
4.- Mostar por pantalla el nombre, el oficio y el salario de los empleados del
departamento de FERNANDEZ que tengan su mismo salario.
5.- Presentar los nombres y oficios de los empleados que tienen el mismo trabajo que
JIMENEZ.
SELECT APELLIDO,OFICIO FROM EMPLE WHERE = (SELECT OFICIO FROM EMPLE WHERE
APELLIDO = 'JIMENEZ');
TABLA LIBRERÍA
7.- Visualizar las columnas tema, estante y ejemplares de las filas cuyo estante no este
comprendido entre la B y la D.
SELECT * FROM LIBRERIA WHERE ESTANTE NOT BETWEEN 'B' AND 'D';
8.- Visualizar con una sola orden select todos los temas de libreria cuyo numero de
ejemplares sea inferior a los que hay en medicina.
9.- Visualizar los temas de libreria cuyos numeros de ejemplares no este entre 15 y 20,
ambos incluidos.
SELECT TEMA FROM LIBRERIA WHERE EJEMPLARES NOT BETWEEN (15) AND (20);
10.- Visualizar todas las asignaturas que contengan en su interior tres letras 'o' y
tengan alumnos matriculados en madrid.
11.- Visualizar los nombres de los alumnos que tengan una nota entre 7 y 8 en la
asignatura de FOL.
SELECT NOMBRE FROM ASIGNATURAS, NOTAS WHERE NOTA BETWEEN 5 AND 10;
13.- Visualizar los nombres de alumnos de madrid que tengan alguna asignatura
suspendida.
14.- Mostrar los nombres de alumnos que tengan la misma nota que tiene "Díaz
Fernández, María" en FOL en alguna asignatura.
SELECT APENOM FROM ALUMNOS WHERE DNI IN (SELECT DNI FROM NOTAS
WHERE NOTA =
(SELECT NOTA FROM NOTAS WHERE DNI = (SELECT DNI FROM ALUMNOS WHERE
APENOM = 'DÍAZ FERNÁNDEZ. MARÍA') AND COD = (SELECT COD FROM ASIGNATURAS
WHERE NOMBRE = 'FOL')));
SELECT ... FROM ...GROUP BY...HAVING...
1) Visualizar los departamentos en los que el salario medio es mayor o igual que la
media de todos los salarios;
SELECT COUNT(*) FROM EMPLE WHERE DEPT_NO = (SELECT DEPT_NO FROM DEPART
WHERE DNOMBRE ='VENTAS' AND OFICIO = 'VENDEDOR');
3) Partiendo de la tabla EMPLE, visualizar por cada oficio de los empleados del
departamento 'VENTAS' la suma de salarios.
4) seleccionar aquellos pedidos de la tabla EMPLE cuyo salario sea igual a la media de
su salario en su departamento.
SELECT DEPT_NO,COUNT(*) FROM EMPLE WHERE OFICIO LIKE 'EMPLEADO' GROUP BY DEPT_NO;
6) Desde la tabla EMPLE, visualizar el departamento que tenga más empleados cuyo
oficio sea 'EMPLEADO'
SELECT DEPT_NO, COUNT(*) FROM EMPLE WHERE OFICIO LIKE 'EMPLEADO' GROUP BY
DEPT_NO HAVING COUNT(*)=(SELECT MAX(COUNT(*)) FROM EMPLE WHERE OFICIO
LIKE 'EMPLEADO'GROUP BY DEPT_NO);
9) Dada la tabla LIBRERIA, visualizar por cada estante la suma de los ejemplares.
11) Visualizar los nombres de los alumnos de la tabla ALUM que aparezcan en alguna
de estas tablas: NUEVOS y ANTIGUOS.
SELECT NOMBRE FROM ALUM INTERSECT (SELECT NOMBRE FROM NUEVOS UNION
SELECT NOMBRE FROM ANTIGUOS);
12) Escribir las distintas formas en que se puede poner la consulta anterior llegando al
mismo resultado
SELECT NOMBRE FROM ALUM WHERE NOMBRE IN(SELECT NOMBRE FROM NUEVO)
UNION SELECT NOMBRE FROM ANTIGUO);
SELECT NOMBRE FROM ALUM WHERE NOMBRE IN (SELECT NOMBRE FROM NUEVO)
OR NOMBRE IN (SELECT NOMBRE FROM ANTIGUO);
13) Visualizar los nombres de los alumnos de la tabla alum que aparezcan en estas dos
tablas: antiguos y nuevos
14) Escribir las distintas formas en que se puede poner la consulta anterior llegando al
mismo resultado.
SELECT NOMBRE FROM ALUM MINUS SELECT NOMBRE FROM ANTIGUOS MINUS
SELECT NOMBRE FROM NUEVOS;
16) Realizar una consulta en la que aparezca por cada centro y en cada especialidad el
numero de profesores. Si el centro no tiene profesores debe aparecer un 0 en la
columna de profesores.
1.- mostrar el oficio y media de salarios de aquellos empleados cuya media de salario
sea mayor que 200000
2.- mostrar el nombre y la comision de aquellos empleados que tengan una comision
mayor que la de sanchez
5.- mostrar el número de directores de la tabla emple que sean dep departamento
producción
2.- A partir de la tabla emple, visualizar cuantos apellidos de los empleados empiezan
por la letra ‘A’
3.- Dada la tabla emple, obtener el sueldo medio, el número de comisiones no nulas , el
máximo sueldo y el minimo sueldo de los empleados del departamento 30.Emplear el
formato adecuado para la salida y las cantidades adecuadas.
4.- Contar las filas de librería cuyo tema tenga por lo menos una ‘A’.
5.- Visualizar los temas con mayor número de ejemplares de la tabla librería y que
tengan al menos una ‘E’ (pueden ser un tema o varios).
SELECT COUNT (DISTINCT ESTANTE ) FROM LIBRERIA WHERE TEMA LIKE (‘%E%’);
8.- ¿Qué sentencia select se debe ejecutar para tener el siguiente resultado?
9.- Visualizar los titulos de la tabla MISTEXTOS sin los caracteres punto y comillas, y en
minusculas de dos formas conocidas.
10.- Escribir una sentencia select que visualice dos columnas, una con el autor y otra
con el apellido del autor.
11.- Escribir la sentencia select que visualice las columnas de autor y otra columna con
el nombre del autor (sin el apellido) de la tabla libros.
12.- A partir de la tabla libros, realizar una sentencia select que visualice en una
columna, primero el nombre del autor y luego el apellido.
13.- A partir de la tabla libros , realizar una sentecia select que visualice los titulos
ordenados por su numero de caracteres.
18.- A partir de la tabla emple, obtener el apellido de los empleados que lleven más de
19 años trabajando.
19.- Seleccionar el apellido de los empleados de la tabla emple que lleven mas de 18
años trabajando en el en el departamento ‘ventas’.
1.- visualizar los departamentos con mayor número de empleados y que tengan un
salario mayor que 20000.
SELECT DNOMBRE FROM DEPART WHERE DEPT_NO = (SELECT DEPT_NO FROM EMPLE
WHERE EMP_NO = (SELECT MAX(EMP_NO) FROM EMPLE WHERE SALARIO = (SELECT
SALARIO FROM EMPLE WHERE SALARIO > 20000 )));
2.- visualizar los titulos de la tabla libros entre los caracteres * y en minuscula.Ejemplo:
*la colmena*
3.- visualizar los libros que comiencen por 'L' y sean de la editorial 'Planeta'.
SELECT TITULO FROM LIBROS WHERE TITULO LIKE 'L%' AND EDITORIAL = 'PLANETA';
4.- Si hoy es 22/03/2010 del lunes que dia sera el lunes de la semana que viene
6.- a partir de la tabla mis textos realizar una select para que aparezcan los autores
ordenados por el numero de caracteres de la columna titulo.
7.- seleccionar los empleados que hayan trabajado más de 5 años y sumarles 10000 pts
a su salario.
8.- obtener la fecha de hoy con el siguiente formato (en mayusculas) hoy es veintidós
de marzo de dosmil diez.
SELECT TO_CHAR (SYSDATE, "HOY ES" DAY, DD "DE" MONTHS "DE" YEAR) FROM DUAL;
9.- escribir una consultilla que visualice en una sola columna el nombre y apellido de las
personas de la tabla nacimiento y la fecha de nacimiento en un formato específico.
3.- Obtener de la tabla emple el último dia del mes para cada uno de las fechas de alta.
4.- Obtener la diferencia de meses que hay entre la fecha 5/5/200 y la fecha 1/1/2000.
6.- Si hoy es domingo 25 de julio de 1999 (fecha del sistema "sysdate"). ¿Qué fecha será
el proximo jueves?
8.- A partir de la tabla emple, obtener la fecha de lata de forma que aparezca el
nombre del mes con tres letras (month), el numero del dia del año (ddd), el ultimo
digito del año(y)y los tres digitos ultimos del año(yyy).
SELECT TO_CHAR(SYSDATE,'"HOY ES " DAY "," DD "DE" MONTH "DE" YYYY') FROM DUAL;
10.- Visualizar la suma de salarios de la tabla emple de manera formateada, tal que
aparezca el simbolo de la moneda local, el punto para los miles y la coma para los
decimales.
12.- Obtener el nombre del mes a partir de la cadena '01012001'. Antes hay que
convertir la cadena a tipo fecha.
13.- Obtener el nombre del dia, el nombre del me, el dia y el año en ingles a partir de la
fecha '12121997'
CREATE TABLE...
COMMIT;
CREATE TABLE...
commit;
CREATE TABLE...
COMMIT;
REM ********** TABLA MISTEXTOS: *************
COMMIT;
COMMIT;
CREATE TABLE...
COMMIT;
COMMIT;
commit;
COMMIT;
commit;
1- Dadas las tablas ALUM y NUEVOS, insertar en la tabla ALUM los nuevos alumnos.
INSERT INTO ALUM (SELECT * FROM NUEVOS MINUS SELECT * FROM ALUM);
UPDATE EMPLE SET DEPT_NO = (SELECT DEPT_NO FROM EMPLE WHERE OFICIO LIKE
'EMPLEADO' GROUP BY DEPT_NO HAVING COUNT (*)
= (SELECT MAX(COUNT(*)) FROM EMPLE WHERE OFICIO LIKE 'EMPLEADO' GROUP BY
DEPT_NO)) WHERE APELLIDO LIKE 'SAAVEDRA';
5- Borrar todos los departamentos de la tabla DEPART para los cuales no existan
empleados en emple.
DELETE FROM DEPART WHERE DEPT_NO IN (SELECT DEPT_NO FROM DEPART MINUS
SELECT DEPT_NO FROM EMPLE);
6- Modificar el número de plazas con un valor igual a la mitad en aquellos centros con
menos de dos profesores.
9- Borrar al personal que esté en centros de menos de 300 plazas y con menos de dos
profesores.
10- Borrar a los profesores que estén en la tabla PROFESORES y que no estén en la
tabal PERSONAL.
11- Dar de alta un artículo de 'Primera' categoría para los fabricantes de 'Francia' y
abastecer con 5 unidades de ese artículo a todas las tiendas y en la fecha de hoy.
12- Insertar un pedido de 20 unidades en la tienda '111-A' con el artículo que mayor
número de ventas haya realizado.
13- Dar de alta una tienda en la provincia de 'MADRID' y abasteerla con 20 unidades de
cada uno de los artículos existentes.
INSERT INTO TIENDAS VALUES ('1010-C', 'LA CESTA', 'C/JUAN MAZO 30',
'ALCALA','MADRID',28809);
15- Realizar una venta para todas las tiendas de 'TOLEDO' de 10 unidades en los
artículos de 'Primera' categoría.
16- Para aquellos artículos de los que se hayan vendido más de 30 unidades, realizar un
pedido de 10 unidades para la tienda
con NIF '5555-B' con la fecha actual.
17- Cambiar los datos de la tienda con NIF '1111-A' igualandolos a los de la tienda NIF
'2222-A'.
UPDATE TIENDAS
SET(NOMBRE,DIRECCIÓN,POBLACIÓN,PROVINCIA,CODPOSTAL)=(SELECT
NOMBRE,DIRECCIÓN,POBLACIÓN,PROVINCIA,
CODPOSTAL FROM TIENDAS WHERE PAIS='ITALIA');
18- Cambiar todos los artículos de 'Primera' categoria a 'Segunda' categoria del pais
'ITALIA'.
UPDATE PEDIDOS P
SET UNIDADES_PEDIDAS=
(SELECT EXISTENCIAS*0.2 FROM ARTICULOS WHERE
ARTICULO=P. ARTICULO AND
COD_FABRICANTE=P. COD_FABRICANTE AND
PESO=P. PESO AND
CATEGORIA=P. CATEGORIA )
WHERE UNIDADES_PEDIDAS >
(SELECT EXISTENCIAS FROM ARTICULOS WHERE
ARTICULO=P. ARTICULO AND
COD_FABRICANTE=P. COD_FABRICANTE AND
PESO=P. PESO AND
CATEGORIA=P. CATEGORIA);
DELETE TIENDAS
WHERE NIF NOT IN (SELECT DISTINCT NIF FROM VENTAS);
DELETE ARTICULOS
WHERE (ARTICULO, COD_FABRICANTE, PESO, CATEGORIA)
NOT IN (SELECT DISTINCT ARTICULO, COD_FABRICANTE, PESO,
CATEGORIA FROM VENTAS)
AND (ARTICULO, COD_FABRICANTE, PESO, CATEGORIA)
NOT IN (SELECT DISTINCT ARTICULO, COD_FABRICANTE, PESO,
CATEGORIA FROM PEDIDOS);
22- Borrar los pedidos de 'Primera' categoria cuyo pais de procedencia sea 'BELGICA'.
DELETE PEDIDOS
WHERE (ARTICULO, COD_FABRICANTE, PESO, CATEGORIA)
IN
(SELECT ARTICULO, COD_FABRICANTE, PESO, CATEGORIA
FROM ARTICULOS WHERE COD_FABRICANTE=
(SELECT COD_FABRICANTE FROM FABRICANTES WHERE PAIS ='BELGICA'))
AND CATEGORIA='Primera';
6. Añadir una restricción a la tabla tiendas para que el nombre de la tienda sea de tipo
título
8. Modificar las columnas de las tablas pedidos y ventas para que las unidades
vendidas y las unidades pedidas puedan almacenar cantidades numericas de 6 dígitos.
10. Añadir a las tablas pedidos y ventas una nueva columna para que almacenen el pvp
del artículo.
11. Añadir a la tabla profesores una columna llamada cod_asig con dos posiciones
numéricas.
12. Crear la tabla tasig con las siguientes columnas: cod_asig numerico, 2 posiciones y
nom_asig cadena de 20 caracteres.
15. Visualizar los nombres de las constraint y las columnas afectadas de las tablas tasig
y profesores.
CREATE VIEW...AS...
1º) Crear una vista que se llame conserjes que contenga el nombre del centro y el
nombre de sus conserjes.
CREATE VIEW...AS...
1º) Crear una vista que se llame dep30 que contiene el apellido, oficio y el salario de los
empleados de la tabla emple del departamento 30.
CREATE VIEW DEP30 AS SELECT APELLIDO, OFICIO ,SALARIO FROM EMPLE WHERE
DEPT_NO=30;
DESC DEP30;
CREATE OR REPLACE VIEW DEP30 (APE, OFI , SAL) AS SELECT APELLIDO, OFICIO
,SALARIO FROM EMPLE WHERE DEPT_NO=30;
5º) Hacer una consulta de las vistas creadas junto con sus textos:
DROP VIEW...UPDATE...SELECT...
LISTADOS
A partir de las tablas emple y depart, hacer un listado en el que se produzca una suma
de salarios por localidad y dentro de la localidad una suma de salarios por oficios.
- el titulo superios de la lista es: LISTADO DE LOS EMPLEADOS DE LA TABLA EMPLE
- El titulo inferior del listado es:Con ruptura por departamento y por oficio calculando
totales
- La cabecera estara formada por los siguientes titulos: Localidad, apellidos, Nº de
empleado, oficio, salario y comisión.
SET LINESIZE 79
SET PAGESIZE 45
SET NEWPAGE 0
SPOOL LISTADO3.LST
SELECT LOC, APELLIDO, EMP_NO, OFICIO, SALARIO, COMISION
FROM EMPLE, DEPART
WHERE EMPLE.DEPT_NO=DEPART.DEPT_NO
ORDER BY LOC, OFICIO;
TTITLE OFF
BTITLE OFF
CLEAR BREAKS
CLEAR COMPUTES
CLEAR COLUMNS
SPOOL OFF
FORMATEAR LISTADOS
SET HEADSEP |
TTITLE CENTER 'RESUMEN DEPARTAMENTAL' skip 2
SET LINESIZE 79
SET PAGESIZE 60
SET NEWPAGE 0
SPOOL LISTADO5.LST
ACCEPT...PROMPT
SET HEADSEP |
TTITLE CENTER 'RESUMEN DEPARTAMENTAL' skip 2
TTITLE OFF
BTITLE OFF
CLEAR COMPUTES
CLEAR COLUMNS
SPOOL OFF
Hacer el mismo informe que se pide en el ejercicio 2, con la diferencia
que nos pida introducir por teclado el nombre del departamento que se va a listar.
No se han de obtener los calculos por report ni imprimir el titulo inferior.
TTITLE OFF
BTITLE OFF
CLEAR BREAKS
CLEAR COMPUTES
CLEAR COLUMNS
SPOOL OFF
CREATE TABLESPACE...
CREATE USER...
3º) Crear un rol que tenga los siguientes privilegios, insert select
en depart y emple, create session, create database link, create table
y create view.
CONNECT ADMINISTRADOR@DAINT
- Conceder al usuario USU5 cuatro privilegios del sistema, dos de ellos, con la opción de
poder concederselos a otros usuarios.
- Quitar a los usuarios USU3 y USU4 todos los privilegios q tenían asignados.
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE('HOLA');
3 END;
4/
SAVE...
2.- Escribir un bloque PL/SQL que cuente el número de filas que hay en la tabla
productos, deposita el resultado en la variable v_num, y visualiza su contenido.
SQL>DECLARE
2 v_num NUMBER;
3 BEGIN
4 SELECT count(*) INTO v_num
5 FROM productos;
6 DBMS_OUTPUT.PUT_LINE(v_num);
7 END;
8/
START...,GET...,RUN
O bien:
SQL> GET A:\PROG01.SQL
SQL> RUN
CREATE OR REPLACE PROCEDURE...
3) Escribir una función que reciba una fecha y devuelva el año, en número,
correspondiente a esa fecha.
DECLARE
n NUMBER(4);
BEGIN
n := anio(SYSDATE);
DBMS_OUTPUT.PUT_LINE('AÑO : '|| n);
END;
Indicar cuáles de las siguientes llamadas son correctas y cuáles incorrectas, en este
último caso escribir la llamada correcta usando la notación posicional (en los casos que
se pueda):
1º. crear_depart;
2º. crear_depart(50);
3º. crear_depart('COMPRAS');
4º. crear_depart(50,'COMPRAS');
5º. crear_depart('COMPRAS', 50);
6º. crear_depart('COMPRAS', 'VALENCIA');
7º. crear_depart(50, 'COMPRAS', 'VALENCIA');
8º. crear_depart('COMPRAS', 50, 'VALENCIA');
9º. crear_depart('VALENCIA', ‘COMPRAS’);
10º. crear_depart('VALENCIA', 50);
2º Correcta.
4º Correcta.
5º Incorrecta: los argumentos están en orden inverso. Solución:
crear_depart(50, 'COMPRAS');
7º Correcta.
6) Desarrollar una función que devuelva el número de años completos que hay entre
dos fechas que se pasan como argumentos.
7) Escribir una función que, haciendo uso de la función anterior devuelva los trienios
que hay entre dos fechas. (Un trienio son tres años completos).
CREATE OR REPLACE
PROCEDURE modificar_localidad(
num_depart NUMBER,
localidad VARCHAR2)
AS
BEGIN
UPDATE depart SET loc = localidad
WHERE dept_no = num_depart;
END modificar_localidad;
Nota: Lo indicado en la nota del ejercicio anterior se puede aplicar también a este.
13) Visualizar todos los procedimientos y funciones del usuario almacenados en la base
de datos y su situación (valid o invalid).
4) Escribir un programa que visualice el apellido y el salario de los cinco empleados que
tienen el salario más alto.
5) Codificar un programa que visualice los dos empleados que ganan menos de cada
oficio.
/* Líneas de detalle */
DBMS_OUTPUT.PUT_LINE(RPAD(vr_emp.apellido,10)|| ' * '
||LPAD(TO_CHAR(vr_emp.salario,'9,999,999'),12));
/* Incrementar y acumular */
cont_emple := cont_emple + 1;
sum_sal:=sum_sal + vr_emp.salario;
8) Escribir un procedimiento que reciba todos los datos de un nuevo empleado procese
la transacción de alta, gestionando posibles errores.
EXCEPTION
WHEN NO_DATA_FOUND THEN IF
v_dummy_dep IS NULL THEN
RAISE_APPLICATION_ERROR(-20005,
'Err. Departamento inexistente');
ELSIF v_dummy_jef IS NULL THEN
RAISE_APPLICATION_ERROR(-20005,
'Err. No existe el jefe');
ELSE
RAISE_APPLICATION_ERROR(-20005,
'Err. Datos no encontrados(*)');
END IF;
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE
('Err.numero de empleado duplicado');
RAISE;
END alta_emp;
WHILE...FOUND...LOOP...
/* Actualizar */
UPDATE EMPLE SET SALARIO=SALARIO + v_imp_pct
WHERE ROWID = vr_sal.rowid;
10) Escribir un procedimiento que suba el sueldo de todos los empleados que ganen
menos que el salario medio de su oficio. La subida será del 50% de la diferencia entre el
salario del empleado y la media de su oficio. Se deberá asegurar que la transacción no
se quede a medias, y se gestionarán los posibles errores.
vr_ofi_sal c_ofi_sal%ROWTYPE;
vr_emp_sal c_emp_sal%ROWTYPE;
v_incremento emple.salario%TYPE;
BEGIN
COMMIT;
OPEN c_emp_sal;
FETCH c_emp_sal INTO vr_emp_sal;
OPEN c_ofi_sal;
FETCH c_ofi_sal INTO vr_ofi_sal;
WHILE c_ofi_sal%FOUND AND c_emp_sal%FOUND LOOP
/* calcular incremento */
v_incremento :=
(vr_ofi_sal.salario - vr_emp_sal.salario) / 2;
/* actualizar */
UPDATE emple SET salario = salario + v_incremento
WHERE CURRENT OF c_emp_sal;
/* siguiente empleado */
FETCH c_emp_sal INTO vr_emp_sal;
**********************************************************************
Liquidación del empleado:...................(1)
Dpto:.................(2) Oficio:...........(3)
Salario : ............(4)
Trienios :.............(5)
Comp. Responsabil :.............(6)
Comisión :.............(7)
------------
Total :.............(8)
**********************************************************************
Donde:
CURSOR c_emp IS
SELECT APELLIDO, EMP_NO, OFICIO, (EMP_CARGO *
10000) COM_RESPONSABILIDAD, SALARIO,
NVL(COMISION, 0) COMISION, DEPT_NO,
TRIENIOS(FECHA_ALT, SYSDATE) * 5000 TOT_TRIENIOS
FROM EMPLE,(SELECT DIR,COUNT(*) EMP_CARGO FROM EMPLE
GROUP BY DIR) DIREC
WHERE EMPLE.EMP_NO = DIREC.DIR(+)
ORDER BY APELLIDO;
12) Crear la tabla T_liquidacion con las columnas apellido, departamento, oficio,
salario, trienios, comp_responsabilidad, comisión y total; y modificar la aplicación
anterior para que en lugar de realizar el listado directamente en pantalla, guarde los
datos en la tabla. Se controlarán todas las posibles incidencias que puedan ocurrir
durante el proceso.
1.- Construir un disparador de base de datos que permita auditar las operaciones de
inserción o borrado de datos que se realicen en la tabla emple según las siguientes
especificaciones:
- En primer lugar se creará desde SQL*Plus la tabla auditaremple con la columna col1
VARCHAR2(200).
- Cuando se produzca cualquier manipulación se insertará una fila en dicha tabla que
contendrá:
- Fecha y hora
- Número de empleado
- Apellido
- La operación de actualización INSERCIÓN o BORRADO
2.- Escribir un trigger de base de datos un que permita auditar las modificaciones en la
tabla empleados insertado en la tabla auditaremple los siguientes datos:
- Fecha y hora
- Número de empleado
- Apellido
- La operación de actualización: MODIFICACIÓN.
- El valor anterior y el valor nuevo de cada columna modificada. (solo las columnas
modificadas)
3.- Escribir un disparador de base de datos que haga fallar cualquier operación de
modificación del apellido o del número de un empleado, o que suponga una subida de
sueldo superior al 10%.
PROCEDURE insert_depart(
v_nom_dep VARCHAR2,
v_loc VARCHAR2)
AS
ultimo_dep DEPART.DEPT_NO%TYPE;
nombre_repetido EXCEPTION;
BEGIN
PROCEDURE visualizar_datos_depart
(v_num_dep NUMBER)
AS
vr_dep depart%ROWTYPE;
v_num_empleados NUMBER(4);
BEGIN
SELECT * INTO vr_dep FROM depart
WHERE DEPT_NO=v_num_dep;
SELECT COUNT(*) INTO v_num_empleados FROM
EMPLE WHERE DEPT_NO=v_num_dep;
DBMS_OUTPUT.PUT_LINE
('Número de departamento: '||vr_dep.dept_no);
DBMS_OUTPUT.PUT_LINE
('Nombre del departamento: '||vr_dep.dnombre);
DBMS_OUTPUT.PUT_LINE
('Localidad : '||vr_dep.loc);
DBMS_OUTPUT.PUT_LINE
('Numero de empleados : '||v_num_empleados);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Err departamento no encontrado');
END visualizar_datos_depart;
/*************************************************************/
DBMS_OUTPUT.PUT_LINE
('Número de departamento: '||vr_dep.dept_no);
DBMS_OUTPUT.PUT_LINE
('Nombre del departamento: '||vr_dep.dnombre);
DBMS_OUTPUT.PUT_LINE
('Localidad : '||vr_dep.loc);
DBMS_OUTPUT.PUT_LINE
('Numero de empleados : '||v_num_empleados);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Err departamento no encontrado');
END visualizar_datos_depart;
/*************************************************************/
FUNCTION buscar_depart_por_nombre
(v_nom_dep VARCHAR2)
RETURN NUMBER
AS
v_num_dep depart.dept_no%TYPE;
BEGIN
SELECT dept_no INTO v_num_dep FROM depart
WHERE DNOMBRE = v_nom_dep;
RETURN v_num_dep;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Err departamento no encontrado');
END buscar_depart_por_nombre;
/*************************************************************/
PROCEDURE cambiar_localidad(
v_num_dep NUMBER,
v_loc VARCHAR2)
AS
BEGIN
UPDATE depart
SET LOC=v_loc
WHERE dept_no=v_num_dep;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Err departamento no encontrado');
END cambiar_localidad;
END gest_depart;
CREATE OR REPLACE PACKAGE BODY....
- insertar_nuevo_emple
- borrar_emple. Cuando se borra un empleado todos los empleados que dependían de
él pasarán a depender del director del empleado borrado.
- modificar_oficio_emple
- modificar_dept_emple
- modificar_dir_emple
- modificar_salario_emple
- modificar_comision_emple
- visualizar_datos_emple. También se incluirá una versión sobrecargada del
procedimiento que recibirá el nombre del empleado.
- buscar_emple_por_nombre. Función local que recibe el nombre y devuelve el
número.
Todos los procedimientos recibirán el número del empleado seguido de los demás
datos necesarios. También se incluirán en el paquete cursores y declaraciones de tipo
registro, así como siguientes procedimientos que afectarán a todos los empleados:
PROCEDURE insertar_nuevo_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_apell EMPLE.APELLIDO%TYPE,
v_oficio EMPLE.OFICIO%TYPE,
v_dir EMPLE.DIR%TYPE,
v_fecha_al EMPLE.FECHA_ALT%TYPE,
v_sal EMPLE.SALARIO%TYPE,
v_comision EMPLE.COMISION%TYPE DEFAULT NULL,
v_num_dep EMPLE.DEPT_NO%TYPE);
PROCEDURE borrar_emple(
v_num_emple NUMBER);
PROCEDURE modificar_oficio_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_oficio EMPLE.OFICIO%TYPE);
PROCEDURE modificar_dept_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_dept EMPLE.DEPT_NO%TYPE);
PROCEDURE modificar_dir_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_direccion EMPLE.DIR%TYPE);
PROCEDURE modificar_salario_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_salario EMPLE.SALARIO%TYPE);
PROCEDURE modificar_comision_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_comis EMPLE.COMISION%TYPE);
PROCEDURE visualizar_datos_emple(
v_num_emp EMPLE.EMP_NO%TYPE);
PROCEDURE visualizar_datos_emple(
v_nombre_emp EMPLE.APELLIDO%TYPE);
PROCEDURE subida_salario_pct(
v_pct_subida NUMBER);
PROCEDURE subida_salario_imp(
v_imp_subida NUMBER);
END gest_emple;
FUNCTION buscar_emple_por_nombre
(n_emp VARCHAR2)
RETURN NUMBER;
/*************************************************************/
PROCEDURE insertar_nuevo_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_apell EMPLE.APELLIDO%TYPE,
v_oficio EMPLE.OFICIO%TYPE,
v_dir EMPLE.DIR%TYPE,
v_fecha_al EMPLE.FECHA_ALT%TYPE,
v_sal EMPLE.SALARIO%TYPE,
v_comision EMPLE.COMISION%TYPE DEFAULT NULL,
v_num_dep EMPLE.DEPT_NO%TYPE)
IS
dir_no_existe EXCEPTION;
BEGIN
DECLARE
v_num_emple EMPLE.EMP_NO%TYPE;
BEGIN
SELECT EMP_NO INTO v_num_emple FROM EMPLE
WHERE EMP_NO=v_dir;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE insertar_nuevo_emple.dir_no_existe;
END;
INSERT INTO EMPLE VALUES (v_num_emp, v_apell, v_oficio,
v_dir, v_fecha_al, v_sal, v_comision, v_num_dep);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Err. Número de empleado duplicado');
WHEN dir_no_existe THEN
DBMS_OUTPUT.PUT_LINE('Err. No existe el director');
END insertar_nuevo_emple;
/*************************************************************/
PROCEDURE borrar_emple(
v_num_emple NUMBER)
IS
emp_dir EMPLE.DIR%TYPE;
BEGIN
SELECT DIR INTO emp_dir FROM EMPLE
WHERE EMP_NO = v_num_emple;
DELETE FROM EMPLE WHERE EMP_NO = v_num_emple;
UPDATE EMPLE SET DIR = emp_dir WHERE DIR = v_num_emple;
END borrar_emple;
/*************************************************************/
DESARROLLO DE APLICACIONES EN ENTORNOS DE 4ª GENERACIÓN Y CON HERRAMIENTAS CASE
PROCEDURE modificar_oficio_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_oficio EMPLE.OFICIO%TYPE)
IS
BEGIN
UPDATE EMPLE SET OFICIO = v_oficio
WHERE EMP_NO = v_num_emp;
END modificar_oficio_emple;
/*************************************************************/
PROCEDURE modificar_dept_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_dept EMPLE.DEPT_NO%TYPE)
IS
BEGIN
UPDATE EMPLE SET DEPT_NO = v_dept WHERE EMP_NO = v_num_emp;
END modificar_dept_emple;
/*************************************************************/
PROCEDURE modificar_dir_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_direccion EMPLE.DIR%TYPE)
IS
BEGIN
UPDATE EMPLE SET DIR = v_direccion WHERE EMP_NO = v_num_emp;
END modificar_dir_emple;
/*************************************************************/
PROCEDURE modificar_salario_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_salario EMPLE.SALARIO%TYPE)
IS
BEGIN
UPDATE EMPLE SET SALARIO = v_salario WHERE EMP_NO = v_num_emp;
END modificar_salario_emple;
/*************************************************************/
PROCEDURE modificar_comision_emple(
v_num_emp EMPLE.EMP_NO%TYPE,
v_comis EMPLE.COMISION%TYPE)
IS
BEGIN
UPDATE EMPLE SET COMISION = v_comis WHERE EMP_NO = v_num_emp;
END modificar_comision_emple;
/*************************************************************/
DESARROLLO DE APLICACIONES EN ENTORNOS DE 4ª GENERACIÓN Y CON HERRAMIENTAS CASE
PROCEDURE visualizar_datos_emple(
v_num_emp EMPLE.EMP_NO%TYPE)
IS
reg_emple EMPLE%ROWTYPE;
BEGIN
SELECT * INTO reg_emple FROM EMPLE WHERE EMP_NO = v_num_emp;
DBMS_OUTPUT.PUT_LINE('NUMERO EMPLEADO: '||reg_emple.EMP_NO);
DBMS_OUTPUT.PUT_LINE('APELLIDO: '||reg_emple.APELLIDO);
DBMS_OUTPUT.PUT_LINE('OFICIO: '||reg_emple.OFICIO);
DBMS_OUTPUT.PUT_LINE('DIRECTOR: '||reg_emple.DIR);
DBMS_OUTPUT.PUT_LINE('FECHA ALTA): '||reg_emple.FECHA_ALT);
DBMS_OUTPUT.PUT_LINE('SALARIO: '||reg_emple.SALARIO);
DBMS_OUTPUT.PUT_LINE('COMISION: '||reg_emple.COMISION);
DBMS_OUTPUT.PUT_LINE('NUMERO DEPARTAMENTO: '||reg_emple.DEPT_NO);
END visualizar_datos_emple;
/*************************************************************/
PROCEDURE visualizar_datos_emple(
v_nombre_emp EMPLE.APELLIDO%TYPE)
IS
v_num_emp EMPLE.EMP_NO%TYPE;
reg_emple EMPLE%ROWTYPE; BEGIN
v_num_emp:=buscar_emple_por_nombre(v_nombre_emp);
SELECT * INTO reg_emple FROM EMPLE WHERE EMP_NO = v_num_emp;
DBMS_OUTPUT.PUT_LINE('NUMERO EMPLEADO: '||reg_emple.EMP_NO);
DBMS_OUTPUT.PUT_LINE('APELLIDO : '||reg_emple.APELLIDO);
DBMS_OUTPUT.PUT_LINE('OFICIO : '||reg_emple.OFICIO);
DBMS_OUTPUT.PUT_LINE('DIRECTOR : '||reg_emple.DIR);
DBMS_OUTPUT.PUT_LINE('FECHA ALTA: '||reg_emple.FECHA_ALT);
DBMS_OUTPUT.PUT_LINE('SALARIO : '||reg_emple.SALARIO);
DBMS_OUTPUT.PUT_LINE('COMISION : '||reg_emple.COMISION);
DBMS_OUTPUT.PUT_LINE('NUM DEPART: '||reg_emple.DEPT_NO);
END visualizar_datos_emple;
/*************************************************************/
FUNCTION buscar_emple_por_nombre(
n_emp VARCHAR2)
RETURN NUMBER
IS
numero EMPLE.EMP_NO%TYPE;
BEGIN
SELECT EMP_NO INTO numero FROM EMPLE WHERE APELLIDO = n_emp;
RETURN numero;
END buscar_emple_por_nombre;
/*************************************************************/
DESARROLLO DE APLICACIONES EN ENTORNOS DE 4ª GENERACIÓN Y CON HERRAMIENTAS CASE
PROCEDURE subida_salario_pct(
v_pct_subida NUMBER)
IS
subida_mayor EXCEPTION;
BEGIN
IF v_pct_subida > 25 THEN
RAISE subida_mayor;
END IF;
FOR vr_c_sal IN c_sal LOOP
UPDATE EMPLE SET SALARIO = SALARIO +
(SALARIO * v_pct_subida / 100)
WHERE EMP_NO = vr_c_sal.emp_no;
END LOOP;
EXCEPTION
WHEN subida_mayor THEN
DBMS_OUTPUT.PUT_LINE('Subida superior a la permitida');
END subida_salario_pct;
/*************************************************************/
PROCEDURE subida_salario_imp(
v_imp_subida NUMBER)
IS
subida_mayor EXCEPTION;
sueldo_medio NUMBER(10);
BEGIN
SELECT AVG(SALARIO) INTO sueldo_medio FROM EMPLE;
IF v_imp_subida>sueldo_medio THEN
RAISE subida_mayor;
END IF;
FOR vr_c_sal in c_sal LOOP
UPDATE EMPLE SET SALARIO = SALARIO + v_imp_subida
WHERE EMP_NO = vr_c_sal.emp_no;
END LOOP;
EXCEPTION
WHEN subida_mayor THEN
DBMS_OUTPUT.PUT_LINE('Subida superior a la permitida');
END subida_salario_imp;
END gest_emple;
DESARROLLO DE APLICACIONES EN ENTORNOS DE 4ª GENERACIÓN Y CON HERRAMIENTAS CASE
1.- Crear un procedimiento que permita consultar todos los datos de la tabla depart a
partir de una condición que se indicará en la llamada al procedimiento.