Procedimientos Funciones
Procedimientos Funciones
set linesize120;
-----------------------
procedi
--------------------
create or replace procedure nombrep ()
as
v_nombre varchar2(20);
begin
select dnombre into v_nombre from depart where dept_no=dep;
dbms_output.put_line(''||);
exception
when no_data_found then
bbms;
when to_many_rows then
dbms;
when others then
dbms;
end nombrep;
/
execute nombrep();
-----------------
funcion
--------------------
create or replace function nombrefunctio()
return number
as
v_nombre number(2);
begin
select dnombre into v_nombre where.....;
return v_nombre;
end nombrefuctio;
/
begin dbms(nombrefuncti());end;/
--------------ejercicios--------------
2.- Pasando el Dept_no como par�metro calcula para cada oficio el n�mero de
empleados que tiene, puede salir 0. Observaci�n: Dado que s�lo tenemos cursores
impl�citos no podemos tener mas de una respuesta por cada consulta -->
necesitamos una consulta distinta para contar cada uno de los oficios.
Gestiona tambi�n las excepciones.
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
end ejer_ref_8_2;
begin
ejer_ref_8_2(30);
end;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR GENERAL');
END EJERCICIO4;
5. Crea 1 tabla con los mismos datos de fabricantes y con 2 columnas m�s:
a. Facturaci�n.
b. N�mero_unidades.
Cada vez que se recibe un pedido (estos son los par�metros del procedure)
el programa recalcula la facturaci�n y el n�mero de unidades de ese fabricante,
y actualiza en la tabla nueva esos datos.
(Observaci�n: cuando crees la tabla ten presente que la necesitas con los datos.)
EXCEPTION
/* tratamiento de la excepcion */
WHEN NOEXISTE THEN
DBMS_OUTPUT.PUT_LINE('No existe alg�n registro padre');
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No hay datos');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error');
END EJERCICIO5;
ELSE
DBMS_OUTPUT.PUT_LINE('EL DEPARTAMENTO NO EXISTE o la comision es negativa');
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('EL DEPARTAMENTO NO EXISTE');
END EJERCICIO7;
exception
when no_data_found then
DBMS_OUTPUT.PUT_LINE('No existe '||p_nombre);
when others then
DBMS_OUTPUT.PUT_LINE('Error general');
END EJERCICIO_8;
EJERCICIO_8(V_NOMBRE_BANC);
ELSE
DBMS_OUTPUT.PUT_LINE('No existe banco/sucursal, no se inserta la cta.');
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error general.');
END EJERCICIO_9;
/
10. Crea un procedimiento que a partir del nombre de un banco elimina ese banco
y todo lo relativo a �l.
if v_existe = 1 then
SELECT COD_BANCO INTO V_COD_BANCO from bancos
WHERE NOMBRE_BANC = P_NOMBRE_BANC;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error general');
END EJERCICIO_10;
15. Crea un procedimiento que elimina los art�culos que no tienen ni pedidos ni
ventas en los �ltimos 2 a�os.
(utiliza sysdate) Si no ha eliminado ninguno, avisa por pantalla. Si se han
eliminado filas no indica nada.
IF (SQL%ROWCOUNT=0) THEN
{dbms_output.put_line('0 articulos eliminados');}
ELSE
{dbms_output.put_line(sql%rowcount ||' articulos eliminados');}
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('error');
END EJER_REF_8_15;
/
12. Crea un procedimiento que recibe los datos de un empleado.
Si el salario es mayor que la media de su departamento le asigna
exactamente la media del salario de su departamento. Los dem�s
datos se mantienen. La comisi�n es por defecto 0.
IF (sql%rowcount=1) THEN
dbms_output.put_line('empleado insertado');
ELSE
dbms_output.put_line('empleado no insertado');
END IF;
EXCEPTION
when no_data_found then
dbms_output.put_line('no hay datos');
when others then
dbms_output.put_line('error');
END EJER_REF_8_12;
-------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-----------------------------------------
ELSE
DBMS_OUTPUT.PUT_LINE('EL SALARIO ES NEGATIVO O CERO');
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END EJERCICIO_9_2;
INSERT INTO EMPLE VALUES (EMP, APE, OFI, D, FECHA, SAL, COM, DEP);
DBMS_OUTPUT.PUT_LINE('EMPLEADO INSERTADO');
SELECT SUM(SALARIO) INTO V_SUM_SAL FROM EMPLE WHERE DEPT_NO=DEP GROUP BY DEPT_NO;
DBMS_OUTPUT.PUT_LINE('EL GASTO EN SALARIO DEL DEPARTAMENTO '||DEP||' ES '||
V_SUM_SAL);
ELSE
DBMS_OUTPUT.PUT_LINE('EL JEFE O EL DEPARTAMENTO NO EXISTEN o el salario es
negativo');
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END EJERCICIO_9_2;
-----------------------------------------------------------------------------------
-------------------------------------------------------------
3.Crea un procedimiento que recibe los datos de un pedido y realiza las siguientes
acciones:
a. Comprueba que el art culo existe en la tabla padre.
b. Comprueba que la tienda existe.
c. Si las unidades del pedido es superior que las existencias, s lo asigna al
pedido
el 20% de las existencias.
d. La fecha de pedido es la actual.
e. Una vez insertado el pedido resta las unidades pedidas a las existencias del
art culo.
-----------------------------------------------------------------------------------
----------------------------------------------------------------
4. Crea un procedimiento que al recibir los datos de una venta realiza las
siguientes acciones:
a. Muestra la facturaci n de la tienda (en ventas) antes de insertarse la venta.
b. Se comprueba que todos los datos de la venta son correctos, como en el
ejercicio 3.
c. Se inserta la venta.
d. Vuelve a mostrar la facturaci n de la tienda una vez insertada la venta.
e. Gestiona las posibles excepciones.
CREATE OR REPLACE PROCEDURE EJERCICIO_9_4(N VARCHAR2, ART VARCHAR2, COD NUMBER, PES
NUMBER, CAT VARCHAR2, UNID NUMBER)
AS
V_ART NUMBER(2);
V_NIF NUMBER(2);
V_EXIST NUMBER(4);
V_UNI NUMBER(3);
V_FACT NUMBER(8,2);
BEGIN
SELECT COUNT(*) INTO V_ART FROM ARTICULOS
WHERE ARTICULO=ART AND PESO=PES AND COD_FABRICANTE = COD AND CATEGORIA=CAT;
SELECT COUNT(*) INTO V_NIF FROM TIENDAS WHERE NIF=N;
DBMS_OUTPUT.PUT_LINE(V_FACT);
INSERT INTO VENTAS VALUES (N, ART, COD, PES, CAT, SYSDATE, V_UNI);
-----------------------------------------------------------------------------------
---------------------------------------------------------------
5. Crea un procedimiento que recibe 2 fechas, y muestra la facturaci n de la
venta
y los pedidos de todas las tiendas entre esas dos fechas.
CREATE OR REPLACE PROCEDURE FACT(F1 DATE, F2 DATE)
AS
FACT_PEDIDOS NUMBER(8,2);
FACT_VENTAS NUMBER(8,2);
BEGIN
SELECT nvl(SUM(UNIDADES_PEDIDAS*PRECIO_VENTA),0) INTO FACT_PEDIDOS
FROM ARTICULOS A, PEDIDOS P
WHERE A.ARTICULO=P.ARTICULO AND A.COD_FABRICANTE=P.COD_FABRICANTE
AND A.PESO=P.PESO
AND A.CATEGORIA=P.CATEGORIA AND FECHA_PEDIDO BETWEEN F1 AND F2;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END FACT;
6.- Crea una funci n que recibe como par metro el n mero de departamento
y nos devuelve
el n mero de empleados que existen en ese departamento.
Despu s crea un procedimiento que realiza una llamada a esa funci n.
---------------funci n--------------------------------------------------
CREATE OR REPLACE FUNCTION EJER_6(N_DEPT NUMBER)
RETURN NUMBER
AS
V_NUM NUMBER(2);
BEGIN
SELECT COUNT(*) INTO V_NUM FROM EMPLE WHERE DEPT_NO=N_DEPT;
RETURN V_NUM;
END EJER_6;
BEGIN
EJER_6_PROC(10);
END;
------------------llamada a la funci n desde bloque anonimo--------------
BEGIN
DBMS_OUTPUT.PUT_LINE(EJER_6(10));
END;
-----------------------------------------------------------------------------------
--------------------------------------------------------------------
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('SIN DATOS');
END EJER_7;
BEGIN
DBMS_OUTPUT.PUT_LINE(EJER_7('Macarrones',20,1,'Primera'));
END;
-----------------------------------------------------------------------------------
---------------------------------
8. Crea un procedimiento que actualiza las existencias de un art culo que
recibe como par metro,
restando a las existencias la suma de unidades pedidas de ese art culo.
Utiliza la funci n del ejercicio anterior.
CREATE OR REPLACE PROCEDURE EJER_8(ART VARCHAR2, COD NUMBER, PES NUMBER, CAT
VARCHAR2)
AS
V_UNI_PED NUMBER(4);
BEGIN
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NO HAY DATOS');
END EJER_8;
-----------------------------------------------------------------------------------
-----------------------------------
9. Crea un programa que recibe los datos de un art culo. Este programa tiene las
siguientes funcionalidades:
a. Tiene un procedimiento local almacenado que recibe los
datos del art culo y devuelve por pantalla su facturaci n.
b. Tiene un procedimiento almacenado local que calcula
el n mero de pedidos de ese art culo y lo muestra por pantalla.
c. Finalmente el procedimiento principal realiza una llamada a cada uno de los
procedimientos locales.
-----------------------------------------------------------------------------------
---------------------------------------
BEGIN
V_SUM_SALARIO:=SUM_SALARIO(DEPT);
V_NUM_EMPLE:= NUM_EMPLE(DEPT);
DBMS_OUTPUT.PUT_LINE(V_SUM_SALARIO);
DBMS_OUTPUT.PUT_LINE(V_NUM_EMPLE);
END EJER_10;
EJERCICIO 10bis: Crea una funci n que devuelve la facturaci n de un fabricante que
se pasa como par metro.
V_FACT NUMBER(8,2);
BEGIN
RETURN V_FACT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR GENERAL');
END FACT_FABRICANTE;
BEGIN
DBMS_OUTPUT.PUT_LINE(FACT_FABRICANTE(15));
END;
/
V_FACTURACION := FACT_FABRICANTE(V_COD_FACT);
DBMS_OUTPUT.PUT_LINE(P_NOMBRE||' factura '||v_facturacion);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('no hay registros');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('demasiadas filas');
WHEN others THEN
DBMS_OUTPUT.PUT_LINE('demasiadas filas');
END FACT_FAB;
BEGIN
CONTAR(P_NOMBRE, P_ESPECIALIDAD);
V:=CONTAR_POR_ESPECIALIDAD(P_ESPECIALIDAD);
DBMS_OUTPUT.PUT_LINE(V);
END EJER_REF9_11;
12. Crea un procedimiento que recibe los datos de un pedido con las siguientes
identificaciones:
a. Crea una funci n local que devuelve las Existencias de ese art culo.
b. Si existencias es menor que unidades_pedidas, las unidades pedidas ser n de
las existencias (Par metro de E/S).
c. Inserta el pedido y actualiza las unidades pedidas.
d. Se vuelve a llamar a la funci n para que muestre las existencias actuales.
13. Crea un procedimiento que recibe todos los datos de un pedido (Sim trico con
ventas)
que pedir :
a. Si en la llamada los recibe todos o no, har lo siguiente:
i. Si no recibe todos, inserta un articulo.
ii. Si recibe todos pregunta al usuario si quiere insertar un pedido o una venta.
iii. Una vez insertado, actualiza el stock del art culo. (S lo si es pedido) y
en la tabla T_FABRICANTES suma las unidades pedidas totales de los art
culos de
ese fabricante.
iv. Si es una venta en la tabla T_VENTAS incrementa las unidades vendidas de esa
tienda.
T_FABRICANTES (cod_fabricante, nombre, cantidad)
T_TIENDAS (Nif, Nombre, Cantidad)
CREATE OR REPLACE PROCEDURE EJER_REF_9_13(ART VARCHAR2, COD NUMBER, PES NUMBER,
CAT VARCHAR2, TIPO
VARCHAR2,
N VARCHAR2 DEFAULT 0, UNI NUMBER DEFAULT
0)
AS
BEGIN
IF (N = 0) THEN
INSERT INTO ARTICULOS (ARTICULO, COD_FABRICANTE, PESO, CATEGORIA)
VALUES
(ART, COD, PES, CAT);
ELSE
IF (TIPO = 'V') THEN
INSERT INTO VENTAS VALUES (N, ART, COD, PES, CAT, SYSDATE, UNI);
UPDATE T_TIENDAS
SET CANTIDAD = CANTIDAD + UNI
WHERE NIF = N;
ELSE
INSERT INTO PEDIDOS VALUES (N, ART, COD, PES, CAT, SYSDATE, UNI);
UPDATE ARTICULOS SET EXISTENCIAS = EXISTENCIAS + UNI
WHERE ARTICULO=ART AND COD_FABRICANTE=COD AND PESO=PES AND CATEGORIA=CAT;
UPDATE T_FABRICANTES
SET CANTIDAD = CANTIDAD + UNI
WHERE COD_FABRICANTE = COD;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('error');
END EJER_REF_9_13;
-----------------------------------------------------------------------------------
------------------
MAS EJERCICIOS
-----------------------------------------------------------------------------------
-----
--Ejercicio 1
--Haz una funci�n llamada DevolverCodDept que reciba el nombre de un departamento y
devuelva su c�digo.
create or replace function DevolverCodDept (p_nombre dept.dname%type)
return dept.deptno%type
is
v_codigo dept.deptno%type;
begin
select deptno into v_codigo
from dept
where dname=p_nombre;
return v_codigo;
exception
when NO_DATA_FOUND then
dbms_output.put_line('Departamento '||p_nombre||' no existe');
return -1;
when TOO_MANY_ROWS then
dbms_output.put_line('Departamento '||p_nombre||' repetido');
return -2;
end DevolverCodDept;
--Ejercicio 2
--Realiza un procedimiento llamado HallarNumEmp que recibiendo un nombre de
departamento,
--muestre en pantalla el n�mero de empleados de dicho departamento. Puedes utilizar
la funci�n creada en el ejercicio 1.
--Si el departamento no tiene empleados deber� mostrar un mensaje informando de
ello.
--Si el departamento no existe se tratar� la excepci�n correspondiente.
create or replace procedure HallarNumEmp (p_nombre dept.dname%type)
is
v_codigo dept.deptno%type;
v_numempleados number(4);
begin
v_codigo:=DevolverCodDept(p_nombre);
if v_codigo>=0 then
select count(*) into v_numempleados
from emp
where deptno=v_codigo;
if v_numempleados!=0 then
dbms_output.put_line('El departamento '||p_nombre||' tiene '||
v_numempleados||' empleados');
else
dbms_output.put_line('El departamento '||p_nombre||'no tiene
empleados');
end if;
end if;
end HallarNumEmp;
--Ejercicio 3
--Realiza una funci�n llamada CalcularCosteSalarial que reciba un nombre de
departamento y devuelva la suma de los
--salarios y comisiones de los empleados de dicho departamento. Trata las
excepciones que consideres necesarias.
create or replace function CalcularCosteSalarial (p_nombre dept.dname%type)
return NUMBER
is
v_codigo dept.deptno%type;
v_costetotal number(8);
begin
v_codigo:=DevolverCodDept(p_nombre);
if v_codigo>=0 then
select nvl(sum(sal+nvl(comm,0)),0) into v_costetotal
from emp
where deptno=v_codigo;
return v_costetotal;
else
return v_codigo; -- devuelvo el error de DevolverCodDept
end if;
end CalcularCosteSalarial;
--Ejercicio 4
--Realiza un procedimiento MostrarCostesSalariales que muestre los nombres de todos
los departamentos y el coste salarial
--de cada uno de ellos. Puedes usar la funci�n del ejercicio 3.
create or replace procedure MostrarCostesSalariales
is
cursor c_dept
is
select dname
from dept;
v_coste number(9);
begin
for v_nombres in c_dept loop
v_coste:=CalcularCosteSalarial(v_nombres.dname);
if v_coste>=0 then
dbms_output.put_line(v_nombres.dname||' '||v_coste);
end if;
end loop;
end MostrarCostesSalariales;
--Ejercicio 5
--Realiza un procedimiento MostrarAbreviaturas que muestre las tres primeras letras
del nombre de cada empleado.
create or replace procedure MostrarAbreviaturas
is
cursor c_emp is
select substr(ename, 1, 3) as abreviatura
from emp;
begin
for v_emp in c_emp loop
dbms_output.put_line(v_emp.abreviatura);
end loop;
end MostrarAbreviaturas;
--Ejercicio 6
--Realiza un procedimiento MostrarMasAntiguos que muestre el nombre del empleado
m�s antiguo de cada departamento
--junto con el nombre del departamento. Trata las excepciones que consideres
necesarias.
create or replace procedure MostrarMasAntiguos
is
cursor c_dept
is
select deptno, dname
from dept;
v_nomemp emp.ename%type;
begin
for v_dept in c_dept loop
v_nomemp:=BuscarMasAntiguo(v_dept.deptno);
dbms_output.put_line('Departamento: '||v_dept.dname||' Emp: '||v_nomemp);
end loop;
end MostrarMasAntiguos;
--Ejercicio 7
--Realiza un procedimiento MostrarJefes que reciba el nombre de un departamento y
muestre los nombres de los empleados
--de ese departamento que son jefes de otros empleados.Trata las excepciones que
consideres necesarias.
create or replace procedure MostrarJefes (p_nombre dept.dname%type)
is
cursor c_emp
is
select ename
from emp
where deptno = (select deptno
from dept
where dname=p_nombre)
and empno in (select mgr
from emp);
v_ind number:=0;
begin
for v_emp in c_emp loop
dbms_output.put_line(v_emp.ename);
v_ind:=1;
end loop;
if v_ind=0 then
dbms_output.put_line('Ning�n empleado de '||p_nombre||' es jefe');
end if;
end MostrarJefes;
--Ejercicio 8
--Realiza un procedimiento MostrarMejoresVendedores que muestre los nombres de los
dos vendedores con m�s comisiones.
--Trata las excepciones que consideres necesarias.
create or replace procedure MostrarMejoresVendedores
is
cursor c_vend
is
select ename
from emp
order by comm desc;
v_vend c_vend%rowtype;
begin
open c_vend;
fetch c_vend into v_vend;
while c_vend%FOUND and c_vend%ROWCOUNT<=3 loop
dbms_output.put_line(v_vend.ename);
fetch c_vend into v_vend;
end loop;
if c_vend%ROWCOUNT<2 then
raise_application_error(-20001,'Hay menos de dos vendedores con comisi�n');
end if;
close c_vend;
end MostrarMejoresVendedores;
--Ejercicio 9
--Realiza un procedimiento MostrarsodaelpmE que reciba el nombre de un departamento
al rev�s y muestre los nombres
--de los empleados de ese departamento. Trata las excepciones que consideres
necesarias.
Create or replace procedure MostrarsodaelpmE (p_nombre dept.dname%type)
is
v_nombredept dept.dname%type;
begin
v_nombredept:=DevolverCadalReves(p_nombre);
MostrarEmpleados(v_nombredept);
end MostrarsodaelpmE;
--Ejercicio 10
--Realiza un procedimiento RecortarSueldos que recorte el sueldo un 20% a los
empleados cuyo nombre empiece por la letra
--que recibe como par�metro. Trata las excepciones que consideres necesarias.
create or replace procedure RecortarSueldos (p_letra VARCHAR2)
is
begin
update emp
set sal = sal � 0.2*sal
where substr(ename, 1, 1)=p_letra;
if SQL%NOTFOUND then
dbms_output.put_line('Ningun empleado actualizado');
else
dbms_output.put_line(SQL%ROWCOUNT||'empleados actualizados');
end if;
end RecortarSueldos;
--Ejercicio 11
--Realiza un procedimiento BorrarBecarios que borre a los dos empleados m�s nuevos
de cada departamento.
--Trata las excepciones que consideres necesarias.
Create or replace procedure BorrarBecarios
is
cursor c_dept
is
select deptno
from dept;
begin
for v_dept in c_dept loop
BorrarDosMasNuevos(v_dept.deptno);
end loop;
end BorrarBecarios;