Actividades Clase CURSORES

22
CURSORES IMPLICITOS .- A partir de les taules PERSONAL, PROFESORES i CENTROS. 1.- Escriu un bloc pl/sql que visualitzi el llinatge, l’especialitat i el nom del centre del professor amb dni 4123005. --select select p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" from profesores p, centros c where p.cod_centro=c.cod_centro and dni in(select dni from personal where dni= 4123005); --bloque anonimo declare v_apellidos profesores.apellidos%type; v_especialidad profesores.especialidad%type; v_nombre centros.nombre%type; begin select p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" into v_apellidos, v_especialidad, v_nombre from profesores p, centros c where p.cod_centro=c.cod_centro and dni in(select dni from personal where dni=4123005); dbms_output.put_line('apellido: '||v_apellidos); dbms_output.put_line('especialidad: '||v_especialidad); dbms_output.put_line('centro: '||v_nombre); exception when no_data_found then dbms_output.put_line('no se encuentra el dni: 4123005'); end; / show errors; --especificando por consola el dni declare v_apellidos profesores.apellidos%type; v_especialidad profesores.especialidad%type; v_nombre centros.nombre%type; begin select p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" into v_apellidos, v_especialidad, v_nombre from profesores p, centros c where p.cod_centro=c.cod_centro and p.dni =&var; dbms_output.put_line('apellido: '||v_apellidos); dbms_output.put_line('especialidad: '||v_especialidad); dbms_output.put_line('centro: '||v_nombre); exception -- no_data_found: si no encuentra ninguna fila (no funciona DML ) when no_data_found then dbms_output.put_line('el dni no existe '); /*no se puede obtener mas de una fila porque los bloques anonimos solo devuelven una fila; asi que no es necesario when too_many_rows */ When other then Error_message;

Transcript of Actividades Clase CURSORES

Page 1: Actividades Clase CURSORES

CURSORES IMPLICITOS

.- A partir de les taules PERSONAL, PROFESORES i CENTROS.

1.- Escriu un bloc pl/sql que visualitzi el llinatge, l’especialitat i el nom del centre del professor amb dni 4123005.--selectselect p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" from profesores p, centros c where p.cod_centro=c.cod_centroand dni in(select dni from personal where dni= 4123005);

--bloque anonimodeclarev_apellidos profesores.apellidos%type;v_especialidad profesores.especialidad%type;v_nombre centros.nombre%type;beginselect p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" into v_apellidos, v_especialidad, v_nombre from profesores p, centros c where p.cod_centro=c.cod_centroand dni in(select dni from personal where dni=4123005);dbms_output.put_line('apellido: '||v_apellidos);dbms_output.put_line('especialidad: '||v_especialidad);dbms_output.put_line('centro: '||v_nombre);exceptionwhen no_data_found then dbms_output.put_line('no se encuentra el dni: 4123005');end;/show errors;

--especificando por consola el dnideclare v_apellidos profesores.apellidos%type;v_especialidad profesores.especialidad%type;v_nombre centros.nombre%type;beginselect p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" into v_apellidos, v_especialidad, v_nombre from profesores p, centros c where p.cod_centro=c.cod_centroand p.dni =&var;dbms_output.put_line('apellido: '||v_apellidos);dbms_output.put_line('especialidad: '||v_especialidad);dbms_output.put_line('centro: '||v_nombre);exception

-- no_data_found: si no encuentra ninguna fila (no funciona DML )when no_data_found thendbms_output.put_line('el dni no existe ');

/*no se puede obtener mas de una fila porque los bloques anonimos solo devuelven una fila; asi que no es necesario when too_many_rows */

When other thenError_message; end;/show errors;

--para que te salte una excepcion --por no existir el profesor si no se encuentra la variable

Page 2: Actividades Clase CURSORES

declare v_apellidos profesores.apellidos%type;v_especialidad profesores.especialidad%type;v_nombre centros.nombre%type;--si no funciona la sentencia DMLno_profe excepcion; begin

select p.apellidos, p.especialidad, c.nombre as "NOMBRE CENTRO" into v_apellidos, v_especialidad, v_nombre from profesores p, centros c where p.cod_centro=c.cod_centroand p.dni =&var;

--justamente despues de la select para que salte la excepcionIfSql%notfound then raise no_profe;End if;

dbms_output.put_line('apellido: '||v_apellidos);dbms_output.put_line('especialidad: '||v_especialidad);dbms_output.put_line('centro: '||v_nombre);

exception-- no_data_found: si no encuentra la variablewhen no_data_found thendbms_output.put_line('el dni no existe ');

--no se pyuede obtener mas de una fila porque los bloques anonimos solo devuelven una fila; asi que no es necesario when too_many_rows When no_profe thendbms_output.put_line('el profesor no existe');

When other thenError_message;

end;/

Show errors;

2.- Escriu un procediment pl/sql que, passant-li com a paràmetre el dni d’un professor, visualitzi el codi de centre, el nom i llinatges i l’especialitat d’aquest professor;

Create or replace procedure ver_profe (v_dni number)as v_profe profesores%rowtype;beginselect * into v_profe from profesores where dni=v_dni;dbms_output.put_line (v_profe.cod_centro||' * '||v_profe.apellidos||' * '||v_profe.especialidad);exceptionwhen no_data_found then dbms_output.put_line('no se encuentra el dni especeficado ');end;/show errors;

execute ver_profe (9800990);

3.- Escriu un procediment pl/sql que elimini un professor, passant-li com a paràmetre el dni.

Page 3: Actividades Clase CURSORES

Create or replace procedure delete_profe (v_dni number)as v_profe profesores%rowtype;begin--primero lo seleccionoselect * into v_profe from profesores where dni=v_dni;--luego lo borrodelete from profesores where dni=v_dni;dbms_output.put_line('PROFESOR ELIMINADO');dbms_output.put_line (v_profe.cod_centro||' * '||v_profe.apellidos||' * '||v_profe.especialidad);exceptionwhen no_data_found then dbms_output.put_line('no se encuentra el dni especeficado ');end delete_profe;/show errors;--borrar profesorExecute delete_profe(***);Rollback;

--con una excepcion propia declarada y lanzadaCreate or replace procedure delete_profe (v_dni number)No_profe exceptionv_profe profesores%rowtype;begin--primero lo seleccionoselect * into v_profe from profesores where dni=v_dni;--compruebo si existe el profesor con una excepcionIfSql%notfound then raise no_profe;End if;--luego lo borrodelete from profesores where dni=v_dni;dbms_output.put_line('PROFESOR ELIMINADO');dbms_output.put_line (v_profe.cod_centro||' * '||v_profe.apellidos||' * '||v_profe.especialidad);exceptionwhen no_profe then dbms_output.put_line('no se encuentra el dni especeficado ');end delete_profe;/show errors;--borrar profesorExecute delete_profe(***);Rollback;

4.- Escriu una funció pl/sql que, passant-li com a paràmetre el dni d’un professor, retorni l’import a retenir d’irpf aplicant un 20% sobre el salari d’aquest professor.--As/is: depende del la version del motor de base de datos;

Set serveroutput on;create or replace function retener_irpf(v_dni profesores.dni%type)return numberas

Page 4: Actividades Clase CURSORES

v_irpf number;v_salario personal.salario%type;begin--cursor implicito (una sola fila)select salario into v_salario from personal where dni=v_dni and funcion='PROFESOR';--controlar la consulta devuelta por el cursor (si existe)--aplicar el irpf al salariov_irpf:=v_salario*0.2; return(v_irpf);--validamos le el tipo de variable (pero no si es verdadeo el dni)exceptionwhen no_data_found then dbms_output.put_line('El professor con dni: '||v_dni||' no se encuentra');

end retener_irpf;/show errors;

--comprobar la retencion de irpf sobre un profesorselect apellidos, salario, retener_irpf(9800990) as "RETENCION" from personal where dni=9800990;

1.- Escriu una funció pl/sql que, passant-li com a paràmetres una llista de 5 nombres, retorni la suma.

Set serveroutput on;Create or replace function suma5numeros(num1 number,num2 number,num3 number,num4 number,num5 number)return numberasSuma number(10);BeginSuma:=num1+num2+num3+num4+num5;Return suma;End suma5numeros;/Show errors;

select suma5numeros(1,2,3,4,5) from dual;

.- A partir de les taula EMPLE.

2.- Escriu un procediment pl/sql que mos digui si l’empleat amb el nombre passat per paràmetre és ANALISTA ò no. S’han de contemplar i processar els possibles errors.

set serveroutput on;select * from emple order by emp_no;create or replace procedure checkAnalista(num_emple emple.emp_no%type)asv_oficio emple.oficio%type;v_ape emple.apellido%type;begin

Page 5: Actividades Clase CURSORES

select oficio, apellido into v_oficio, v_ape from emple where emp_no=num_emple; if (v_oficio='ANALISTA') then dbms_output.put_line(v_ape||' es '||v_oficio);else dbms_output.put_line(v_ape||' no es ANALISTA; es '||v_oficio);end if;exception when no_data_found thendbms_output.put_line('No existe empleado con el numero: '||num_emple);when too_many_rows then dbms_output.put_line('Existe mas de un empleado con el numero: '||num_emple);end checkAnalista;/show errors;

execute checkAnalista(7788);GIL es ANALISTAexecute checkAnalista(7876);ALONSO no es ANALISTA; es EMPLEADOexecute checkAnalista(7998);No existe empleado con el numero: 7998

3.- Escriu un procediment pl/sql que, si l’empleat amb el nombre passat per paràmetre té un salari inferior a 1.500, l’incrementi amb un 10%. i visualitzi el resultat. S’han de contemplar i processar els possibles errors.

Set serveroutput on;select * from emple order by emp_no;Create or replace procedure aumentarSalario(num_emple emple.emp_no%type)AsV_salario emple.salario%type;V_ape emple.apellido%type;BeginSelect apellido, salario into v_ape, v_salario from emple where emp_no=num_emple;

If (v_salario<1500) then v_salario:=v_salario*1.1;Update emple set salario=v_salario where emp_no=num_emple;dbms_output.put_line

Page 6: Actividades Clase CURSORES

('Ha aumentado el salario de '||v_ape||' en '||v_salario);

Else dbms_output.put_line('El salario de '||v_ape||' no ha cambiado: '||v_salario);

end if;Exceptionwhen no_data_found thendbms_output.put_line('No existe empleado con el numero: '||num_emple);End aumentarSalario;/Show errors;execute aumentarSalario (7844);select * from emple;Rollback;

execute aumentarSalario (7844);--aumentaHa aumentado el salario de TOVAR en 1485execute aumentarSalario (7698);--no aumentaEl salario de NEGRO no ha cambiado: 3005execute aumentarSalario (7998);--excepcionNo existe empleado con el numero: 7998

CURSORES IMPLICITOS

ACTIVITAT_12_01visualizar los apellidos de los empleados pertenecientes al departamento 20numerandolos secuencialmente

bucle LOOP...EXIT WHEN

set serveroutput on;declare cursor c1 isselect apellido from emple where dept_no=20;v_c1 c1%rowtype;beginopen c1;loopfetch c1 into v_c1;exit when c1%notfound;dbms_output.put_line(v_c1.apellido);end loop;close c1;end;

Page 7: Actividades Clase CURSORES

bucle bucle WHILE c1%FOUND

set serveroutput on;declare cursor c1 isselect apellido from emple where dept_no=20;v_c1 c1%rowtype;beginopen c1;fetch c1 into v_c1;while c1%FOUND loopdbms_output.put_line(v_c1.apellido);fetch c1 into v_c1;end loop;close c1;end;/ show errors;

ACTIVITAT_12_02_1visualizar los apellidos de los empleados pertenecientes al departamento 20crea un procedimiento al que le pases el departamento como argumento

set serveroutput on;create or replace procedure showDept20(numDept varchar2)ascursor c1 is select apellido from emple where dept_no=numDept;v_c1 c1%rowtype;--variable del cursor del mismo tipo q el cursorbeginopen c1;loopfetch c1 into v_c1;exit when c1%notfound;dbms_output.put_line(v_c1.apellido);end loop;close c1;end showDept20;/show errors;

execute showDept20(30);

ACTIVITAT_12_02_2Escribe un procedimiento que reciba una cadena y visualice el apellido y el numero de empleado de todos los empleades cuyo apellido contenga la cadena especificada. Al finalitzar, visualiza el numero de empleades mostrado.El procedimiento empleara variables de acoplamiento para:

1 la seleccion de files2 los atributos del cursor estudiados en el ejercicio anterior

*******************************formato LOOP...EXIT WHENset serveroutput on;create or replace procedure showEmpleados(cadena varchar2)ascursor c1 isselect apellido, emp_no from emple where apellido like '%’||cadena||’%';v_c1 c1%rowtype;beginopen c1;loopfetch c1 into v_c1;

if (c1%notfound) thendbms_output.put_line('numero de empleados: '||c1%rowcount);end if;

Page 8: Actividades Clase CURSORES

exit when c1%notfound;dbms_output.put_line(v_c1.apellido||', '||v_c1.emp_no);end loop;close c1;end showEmpleados;/ show errors;

execute showEmpleados('EZ');

ACTIVITAT_12_03*******************************formato FOR....LOOPSe necesitan ‘variables de acoplammiento’ para almacenar un patron pasado por parametro y hacia el cursor

select * from emple;set serveroutput on;create or replace procedure showEmpleados(cadena varchar2)asv_cadena varchar2(10);cursor c1 isselect apellido, emp_no from emple where apellido like v_cadena;v_count number;beginv_cadena:='%'||cadena||'%';for v_c1 in c1 loop

/* el bucle for cierra el cursor antes de que capture c1%rowcount*//*hay que capturar rowcount en una variable: v_count */v_count:=c1%rowcount;dbms_output.put_line(v_c1.apellido||', '||v_c1.emp_no);end loop;dbms_output.put_line('numero de empleados: '||v_count);end showEmpleados;/ show errors;

execute showEmpleados('EZ');

ACTIVITAT_12_04_1RUPTURAS DE CONTROL

************************************************************************************RUPTURAS POR DEPARTAMENTOCrear un procedimiento que liste los empleades y susb salarios por departamento y que muestre tanto la suma de los salarios como el numero de emopleados por departamento, y su total (al final del programa) de la tabla ‘emple’.

*******************************formato LOOP...EXIT WHENset serveroutput on;create or replace procedure listarEmpleadosascursor c1 is select apellido, salario, dept_no from emple order by dept_no, apellido;v_c1 c1%rowtype; --variable del cursorref_dept emple.dept_no%type default 0; --referencia al gtrupo de departamento

--contadores de grupos de departamentos iniciados a 0cont_emple number(2) default 0;suma_salario emple.salario%type default 0;

--contadores total de departamentos iniciados a 0total_emple number(2) default 0;total_salario emple.salario%type default 0;

beginopen c1;loopfetch c1 into v_c1;

Page 9: Actividades Clase CURSORES

/*capturo el departamento en el q se agrupan los empleados*/if (c1%rowcount=1) thenref_dept:=v_c1.dept_no;end if;

/*en el momento en el que cambiamos el grupo de departamento (o ya no capturemos nuevas registros)...imprimiremos datos del grupo*/IF (ref_dept<>v_c1.dept_no OR c1%notfound) THEN dbms_output.put_line('*** DEPTO: ' ||ref_dept||' NUM. EMPLEADOS: ' ||cont_emple||' SUM. SALARIOS: ' ||suma_salario);

--asignamos a la referencia del grupo el nuevo departamentoref_dept:=v_c1.dept_no;

--le añadimos al total del salario a la suma de los salarios parciales--y el total de empleados al el conador de empleados total_salario:=total_salario+suma_salario;total_emple:=total_emple+cont_emple;

--reiniciamos los contadores parciales de gruposuma_salario:=0;cont_emple:=0;END IF;

--primero salir del bucle y luegio imprimirexit when c1%notfound;

/*empleados y salario; el contador de empleados por grupo y la suma de sus salarios*/DBMS_OUTPUT.PUT_LINE(v_c1.apellido||' * '||v_c1.salario);cont_emple:=cont_emple+1;suma_salario:=suma_salario+v_c1.salario;

end loop;close c1;

/*numero total de empleados*/dbms_output.put_line('****** NUMERO TOTAL EMPLEADOS: '|| total_emple || ' TOTAL SALARIOS: ' || total_salario);

end listarEmpleados;/show errors;ACTIVITAT_12_04_2*******************************formato FOR cursor LOOPset serveroutput on;create or replace procedure listarEmpleadosascursor c1 is select apellido, salario, dept_no from emple order by dept_no, apellido;ref_dept emple.dept_no%type default 0; --referencia al grupo de departamento

--contadores de grupos de departamentos iniciados a 0cont_emple number(2) default 0;suma_salario emple.salario%type default 0;

--contadores total de departamentos iniciados a 0total_emple number(2) default 0;total_salario emple.salario%type default 0;

--contador final de gruposv_final emple.dept_no%type;

begin

for v_c1 in c1 loop

/*capturo el departamento en el q se agrupan los empleados*/if (c1%rowcount=1) thenref_dept:=v_c1.dept_no;end if;

/*en el momento en el que cambiamos el grupo de departamento (o ya no capturemos nuevas registros)...imprimiremos datos del grupo*/IF (ref_dept<>v_c1.dept_no OR c1%notfound) THEN dbms_output.put_line('*** DEPTO: ' ||ref_dept||' NUM. EMPLEADOS: ' ||cont_emple||

Page 10: Actividades Clase CURSORES

' SUM. SALARIOS: ' ||suma_salario);

--asignamos a la referencia del grupo el nuevo departamentoref_dept:=v_c1.dept_no;

--le añadimos al total del salario a la suma de los salarios parciales--y el total de empleados al el conador de empleados total_salario:=total_salario+suma_salario;total_emple:=total_emple+cont_emple;

--reiniciamos los contadores parciales de gruposuma_salario:=0;cont_emple:=0;END IF;

v_final:=v_c1.dept_no;--ultimo departamento

--primero salir del bucle y luegio imprimirexit when c1%notfound;

/*empleados y salario; el contador de empleados por grupo y la suma de sus salarios*/DBMS_OUTPUT.PUT_LINE(v_c1.apellido||' * '||v_c1.salario);cont_emple:=cont_emple+1;suma_salario:=suma_salario+v_c1.salario;

end loop;

/**/

dbms_output.put_line('*** DEPTO: ' ||v_final||' NUM. EMPLEADOS: ' ||cont_emple||' SUM. SALARIOS: ' ||suma_salario);

--le añadimos al total del salario a la suma de los salarios parciales--y el total de empleados al el conador de empleados total_salario:=total_salario+suma_salario;total_emple:=total_emple+cont_emple;

/**/

/*numero total de empleados*/dbms_output.put_line('****** NUMERO TOTAL EMPLEADOS: '|| total_emple || ' TOTAL SALARIOS: ' || total_salario);

end listarEmpleados;/show errors;execute listarEmpleados;

ACTIVITAT_12_04_2************************************************************************************RUPTURAS POR OFICIO + RUPTURAS POR DEPARTAMENTOIndica, en este caso, unicamente el nombre del oficioy elnumero de empleades que tiene. Se entiende que se mantienen las “Rupturas por departamento y sus subtotales”; y dentro de cada departamento se haran ruptures por departamento

**aquí necesitamos 3 atributos de la tabla que recol·lectaran los cursores plsql:Oficio, salario, dept_no*******************************formato FOR cursor LOOPSet serveroutput on;Create or replace procedure listarEmpleados2AsCursor c1 is Select oficio, sum(salario) as sal_oficio, dept_no from emple group by oficio, dept_no order by dept_no, oficio;

/*variable referencia a departamentp*/ref_dept emple.dept_no%type default 0;

/*variables para contar por departamento: nºempleados, salarios*/cont_emple number(2) default 0;suma_salario emple.salario%type default 0;

/*variables para contar el total de empleados, salarios*/total_emple number(2) default 0;total_salario emple.salario%type default 0;

Page 11: Actividades Clase CURSORES

/*contador para el ultimo grupo de departamento: bug for...loop*/v_final emple.dept_no%type;

BEGINfor v_c1 in c1 loop

/*iniciamos la referencia al departamento: ‘ruptura de control’*/IF (c1%rowcount=1) thenref_dept:=v_c1.dept_no;END IF;

/*como la select esta ordenado por departamentos, modificamos la referencia al departamento cuando ell cursor capture un nuevo grupo de departamento*/IF(ref_dept<>v_c1.dept_no OR c1%NOTFOUND) thendbms_output.put_line('*** DEPTO: ' ||ref_dept||' NUM.OFICIOS: ' ||cont_emple||' SUM. SALARIOS: ' ||suma_salario);

ref_dept:=v_c1.dept_no;

total_salario:=total_salario+suma_salario;total_emple:=total_emple+cont_emple;

suma_salario:=0;cont_emple:=0;END IF;

/*asdignamos el ultimo departamento antes de que se cierre el bucle */V_final:=v_c1.dept_no;

/*primero salir del bucle y luegio imprimir*/exit when c1%notfound;

DBMS_OUTPUT.PUT_LINE(v_c1.oficio ||' * '||v_c1.sal_oficio);cont_emple:=cont_emple+1;suma_salario:=suma_salario+v_c1.sal_oficio;

END LOOP;

/*salida para el ultimo departamento*/dbms_output.put_line('*** DEPTO: ' ||v_final||' NUM. OFICIOS: ' ||cont_emple||' SUM. SALARIOS: ' ||suma_salario);total_salario:=total_salario+suma_salario;total_emple:=total_emple+cont_emple;

/*numero total de empleados*/dbms_output.put_line('****** NUMERO TOTAL OFICIOS: '|| total_emple || ' TOTAL SALARIOS: ' || total_salario);

END listarEmpleados2;/ show errors;execute listarEmpleados2;

ACTIVITAT_12_05Incrementar el salario de los empleados de un determinado departamentoprocedure(numDept, aumneto);el segundo parametro es la cantidads en euros que se aumenta a los salariosEl programa debera informar del numero de fiilas afectadas por la actualizacionse utilizara rowid;

set serveroutput on;select * from emple order by dept_no;create or replace procedure subirSalario (numDept number, aumento number)ascursor c1 is select salario, rowid from emple where dept_no=numDept;/*no hacemos el update por select...for upadte*/v_c1 c1%rowtype;v_numAumentos number(2) default 0;

Page 12: Actividades Clase CURSORES

beginopen c1;fetch c1 into v_c1;while c1%found loop

update empleset salario=salario+ aumentowhere rowid=v_c1.rowid;

fetch c1 into v_c1;end loop;dbms_output.put_line(c1%rowcount||' empleados del departamento '||numDept||' con aumneto de salario = '||aumento||' euros');

close c1;end subirSalario;/show errors;

execute subirSalario(20, 200);select * from emple order by dept_no;rollback;

ACTIVITAT_12_06_1Si el empleado no tiene comision, o no tiene salario, no se le aumenta el salarioutiliza RAISE_APPLICATION_ERROR() para levantar la COMISION_NULA************************************************************************************select * from emple order by dept_no;set serveroutput on;create or replace procedure aumentoSalario(numEmple number, aumento number)ascursor c1 is select salario, comision from emple where emp_no=numEmple;

beginfor v_c1 in c1 loop

if(v_c1.comision = 0 or v_c1.salario is null) thenRAISE_APPLICATION_ERROR (-20100, 'El empleado '||numEmple||' no tiene salario o comision'); end if;

UPDATE empleset salario=salario+aumentowhere emp_no=numEmple;

end loop;end aumentoSalario;/show errors;

execute aumentoSalario(7369, 500); ***aumento 500€ a SANCHEZexecute aumentoSalario(7521, 500); ***RAISE_APPLICATION_ERRORexecute aumentoSalario(7844, 500); ***RAISE_APPLICATION_ERROR

select * from emple order by dept_no;rollback;

Page 13: Actividades Clase CURSORES

ACTIVITAT_12_06_2***************ERRORProcedimientonque reciba todos los datos de un nuevo empleado y procese la transaccion de alta, gestionando possibles errores. El procedimiento debera gestionar:-no existe departamento -–NO_EXISTE_DEPT-no existe director --NO_EXISTE_DIRECTOR-numero empleado duplicado /*CURSOR*/ --EMPLE_DUPLICADO-Salario nulo: --RAISE_APPLICATION_ERROR(-20010, ‘salario nulo’)-posibles errores de oracle visualizando mensaje de error

--DUP_VAL_ON_INDEX (-1)--INVALID_NUMBER (-1722)--VALUE_ERROR (-6502)

select * from emple;set serveroutput on;Create or replace procedure altaCliente(V_EMP_NO NUMBER,V_APELLIDO VARCHAR2,V_OFICIO VARCHAR2,V_DIR NUMBER,V_FECHA_ALT DATE, --dd/mm/yyV_SALARIO NUMBER,V_COMISION NUMBER,V_DEPT_NO NUMBER)As/* atributos erroneos*/Err_dept_no emple.dept_no%type;Err_dir emple.dir %type;Err_emp_no emple.emp_no%type;

/*errors*/NO_EXISTE_DEPT exception;NO_EXISTE_DIRECTOR exception;EMPLE_DUPLICADO exception;

begin/*error si NO esta el departamento*/select dept_no into err_dept_no from emple where dept_no=v_dept_no;if sql%notfound then raise NO_EXISTE_DEPT;end if;

/*error NO esta el director */select dir into err_dir from emple where dir = v_dir;if sql%notFound then raise NO_EXISTE_DIRECTOR;end if;

/*error SI se repite el numero de empleado*/select emp_no into err_emp_no from emple where emp_no=v_emp_no;

Page 14: Actividades Clase CURSORES

if sql%found then raise EMPLE_DUPLICADO;end if;

if(v_salario = 0 ) thenRAISE_APPLICATION_ERROR (-20100, 'Se debe añadir un salario al nuevo empleado'); end if;

/*una vez hemos comprobado todas las restricciones, damos de alta al nuevo empleado*/Insert into emple values(EMP_NO, APELLIDO, OFICIO, DIR, FECHA_ALT, SALARIO, COMISION, DEPT_NO);

EXCEPTIONWhen NO_EXISTE_DEPT thenDbms_output.put_line('no existe departamento '||err_dept_no||' en la empresa');When NO_EXISTE_DIRECTOR thenDbms_output.put_line('no existe director '||err_dir||' asociado en la empresa');When EMPLE_DUPLICADO thenDbms_output.put_line('Ya existe empleado con el numero'||err_emp_no);When DUP_VAL_ON_INDEX thenDbms_output.put_line('Se ha creado un duplicado en una –primary key- o en una atributo con una restriccion -unique-');When INVALID_NUMBER thenDbms_output.put_line('Error por interpretar tipus de variable incompatibles');When VALUE_ERROR thenDbms_output.put_line('error aritmetico');

end altaCliente;/show errors;

/*DAR DE ALTA*/execute altaCliente(7903, 'PERIQUITO', 'EMPOLLON', 7788,sysdate, 2000, 100, 30);select * from emple;rollback;

/* NO_EXISTE_DEPT */execute altaCliente(7903, 'PERIQUITO', 'EMPOLLON', 7788,sysdate, 2000, 100, 60);select * from emple;rollback;

/* NO_EXISTE_DIRECTOR */execute altaCliente(7903, 'PERIQUITO', 'EMPOLLON', 8888,sysdate, 2000, 100, 30);select * from emple;rollback;

/* EMPLE_DUPLICADO */execute altaCliente(7369, 'PERIQUITO', 'EMPOLLON', 7788,sysdate, 2000, 100, 30);select * from emple;rollback;

Page 15: Actividades Clase CURSORES

.- A partir de les taules EMPLE i DEPART.

1.- Escriu un programa que visualitzi el llinatge i el salari dels 5 empleats que tenen el salari més alt.

set serveroutput on;declarecursor c1 is select apellido, salario from emple order by salario desc;v_c1 c1%rowtype;contador number:=0;

beginopen c1;loop fetch c1 into v_c1;exit when contador=5;

if (v_c1.salario<>0) thendbms_output.put_line(v_c1.apellido||' * '||v_c1.salario);contador := contador+1;end if;

end loop;close c1;end;/ show errors;

Page 16: Actividades Clase CURSORES

2.- Escriu un programa que augmenti el salari dels empleats que el tenguin inferior al salari mitjà del seu ofici i al final visualitzi el nombre, el nou salari i l’ofici de tots els empleats.

.- L’increment del salari serà el 50% de la diferència entre el seu salari i el de la mitja dels salaris del seu ofici.

Set serveroutput on;Create or replace procedure aumentarSalarioOficio(par_oficio varchar2)AsCursor c1 is select apellido, emp_no, salario, oficio from emple where (salario is null or salario<(select avg(salario) from emple where oficio=par_oficio group by oficio) )and oficio=par_oficio for update;

v_aumento emple.salario%type;v_media emple.salario%type;

begin

/*cursor implicito para almacenar el aumento */select avg(salario) into v_media from emple where oficio = par_oficio;

for v_c1 in c1 loop

/*tengo que cubrir la posibilidad de: null+valor=null*/if(v_c1.salario is null) thenv_aumento:=0;v_c1.salario:=0;else v_aumento := (0.5) * ( v_media - v_c1.salario);end if;

update emple set salario=salario+v_aumentowhere current of c1;

dbms_output.put_line(v_c1.apellido||' * n° '||v_c1.emp_no||' * '||(v_c1.salario+v_aumento)||' euros * '||v_c1.oficio);

end loop;end aumentarSalarioOficio;/ show errors;

Page 17: Actividades Clase CURSORES

execute aumentarSalarioOficio('VENDEDOR');select * from emple order by oficio;rollback;

.- A partir de les taules PEDIDOS08, CLIENTES08 i PRODUCTOS08.3.- Escriu un programa que permeti insertar nous pedidos tenint en compta què:.- Les columnes PEDIDO_NO, PRODUCTO_NO, CLIENTE_NO i UNIDADES rebran els valors amb paràmetres..- La columna FECHA_PEDIDO serà la data del sistema..- A més d’insertar el pedido, s’ha d’actualitzar la columna DEBE del client sumant’li el producte de UNIDADES*PRECIO_ACTUAL i, també, actualitzar les unitats disponibles del producte..-S’han de verificar els valors dels pa ràmetres (Nº pedido ja hi és, Nº producto i/ò Nº client no hi és, etc..) així com les unitats disponibles del producte i el límit de crèdit del client visualitzant el missatge d’error corresponent.

/*en un comando SELECT...INTO..., siempe salta NO_DATA_FOUND*//*controlar siempre la excepcion que provoca un SQL%NOTFOUND, en INSERT, UPDATE, DELETE*//*constraint primary key se controlan con: DUP_VAL_ON_INDEX */

set serveroutput on;CREATE OR REPLACE PROCEDURE pedidoNuevo(par_pedido_no number, par_producto_no number, par_cliente_no number, par_unidades number)

ASv_precio_actual productos08.precio_actual%type;bool boolean:=true;

BEGIN

/*error si se repite el numero de pedido*/DECLAREerr_pedido_no pedidos08.pedido_no%type;PEDIDO_DUPLICADO exception;BEGINselect pedido_no into err_pedido_no from pedidos08 where pedido_no=par_pedido_no;if sql%found then raise PEDIDO_DUPLICADO;end if;EXCEPTIONwhen PEDIDO_DUPLICADO thenDbms_output.put_line('ERROR: Ya existe el pedido con el numero: '|| err_pedido_no);when NO_DATA_FOUND thenDbms_output.put_line('numero de pedido: '|| par_pedido_no);rollback; /*despues pasara el control al programa principal */END;

Page 18: Actividades Clase CURSORES

/*precio del pedido: cursor implicito*/DECLAREBEGINSelect precio_actual into v_precio_actual from productos08Where producto_no = par_producto_no;EXCEPTIONwhen no_data_found then null;END;

/*error si no se encuentra PRODUCTO_NO*/DECLAREMOSTRAR_PRODUCTO exception;err_producto_no pedidos08.producto_no%type;BEGINselect producto_no into err_producto_no from productos08where producto_no=par_producto_no;if sql%found then raise MOSTRAR_PRODUCTO;end if;

EXCEPTIONwhen MOSTRAR_PRODUCTO thenDbms_output.put_line('numero de producto: '|| par_producto_no);when NO_DATA_FOUND thenbool:=false;Dbms_output.put_line('ERROR: no existe el numero de producto '||par_producto_no);END;

/*error si no se encuentra CLIENTE_NO*/DECLAREMOSTRAR_CLIENTE exception;err_cliente_no pedidos08.cliente_no%type;beginselect cliente_no into err_cliente_no from clientes08where cliente_no=par_cliente_no;if sql%found then raise MOSTRAR_CLIENTE;end if;

EXCEPTIONwhen MOSTRAR_CLIENTE thenDbms_output.put_line('numero de cliente: '|| par_cliente_no);when NO_DATA_FOUND thenbool:=false;Dbms_output.put_line('ERROR: no existe el cliente '||par_cliente_no);END;

Page 19: Actividades Clase CURSORES

/*comprobamos que no tenemos errores*/if (bool=true) then

/*insertar nuevo pedido*/insert into pedidos08 values (par_pedido_no, par_producto_no, par_cliente_no, par_unidades, sysdate);

/*Actualizamos deuda del cliente*/Update clientes08 set debe=debe+( v_precio_actual * par_unidades)where cliente_no=par_cliente_no;

/*Actualizamos Stock disponible*/Update productos08set stock_disponible = (stock_disponible - par_unidades )where producto_no=par_producto_no;

end if;

EXCEPTION /*eliminar mensaje de violacion PK*/when DUP_VAL_ON_INDEX then null;

END pedidoNuevo;/show errors;