Vous êtes sur la page 1sur 59

Soluciones de las Prcticas

Prctica 2 Soluciones Evale las siguientes declaraciones. Determine cules de ellos no son legales, y explique por qu. Ilegal, porque slo se permite un identificador por declaracin. C. DECLARE v_birthdate DATE NOT NULL; Ilegal, porque una variable NOT NULL ha de ncializarse. Ilegal, porque 1 no es una expresin booleana. Desarrcllo de Aplicaciones con PL/SQL Apndice E-2

Prctica 2 Soluciones (continuacin) Determine el tipo de datos de las expresiones resultantes delas siguientes asignaciones Number Ilegal, PL/SQL no puede convertir smbolos especiales de VARCHAR2 a NUMBER Boolean Cree un bloque annimo para imprimir la frase "My PL/SQL Block Works en la pantalla. VARIABLE gwmessage VARCHAR2 (30) BEGIN :g_message 'My PL/SQL Block Works', END: / PRINT g__mesBage G_MESSAGE My PL/SQL Block Works Desarrollo de Aplicaciones con PLISQL Apndice E-3

Prctica 2 Soluciones (continuacin) Si tiene tiempo, realice el siguiente ejercicio. 4. Cree un bloque que declare dos variables. Asigne el valor de estas variables PL/SQL a variables SQL*Plus e imprima los rcsulados de las vaables PL/SQL en las pantalla. Ejecute su bloque PL/SQL. Guarde su bloque Pl/ SQL en un archivo llamado p2q4..sql. VCHAR Character (variable length) VMNUM Number Asigne vaores a estas variables del siguiente made 1 Variable Value V_CHAR The literal '42 is the answer' The first: two characters from VHCHAR Desarrollo de Aplicaciones con PL/SQL Apndice

Prctica 3 Soluciones PLISQL Block Desarrollo de Aplcacinnes con PLISQL Apndice

Prctica 3 Soluciones (continuacin) 1. Observe el bloque PL/SQL de la pgina anterior y determine los siguientes valores de acuerdo con las reglas de mbito. a. El valor de /WEIGHT en el subbloque es 2 y el tipo de dato es NUMBER. b. El valor de \/_NEWMLOCN en el subbloque es Western Europe y el tipo de dato es VARCHAR2. c. El valor de en el bloque pxincpal es 601 y el tipo de dato es NUMBER. d. El valor de V_MESSAGE en el bloque principal es Product 10012 is in stock y el tipo de dato es VARCHAR2` e. El valor de VNEWhLOCN en el bloque principal es Ilegal porque vnewlocn no es visible fuera del sub-bloque. Desarrollo de Aplicaciones con PLJSQL Apndice E-6

Prctica 3 Soluciones (continuacin) Ejemplo de mbito DECLARE v_customer Womansport ; EXCELLENT Desarrollo de Aplicaciones con PL/SQL Apndice

Prctica 3 Soluciones (continuacin) 2. Suponga que embebe un subbloque en un bloque, como se mostraba en la pgina anterior. Declarar dos variables, V_CUSTOMER y V_CREDIT*RAT1NG, en el bloque principal. Tambin declara' dos variables, V_CUSTOMER y VNAME, en el subbloque. Determine los valores delos siguientes casos. a. El valor de V_,CUSTOMER en el subbloque es 201 y el tipo de dato es NUMBER. b. El valor de V_NAME en el subbloque es Unsparts y el tipo de dato es VARCHAR1?.e c. El valor de VCRED1T_RATING en el subbloque es EXCELLENT y el tipo de dato es VARCHAR2. d. The value of V_CUSTOMER in the main block is womansport y el tipo de dato es VARCHAR2. e. El valor de V__NAME en el bloque principal es /_NAME no es visible en el bloque principal y vera un error. El valor de VCREDIT_RATING en el bloque principal es EXCELLENT y el tipo de dam es VARCHAR2. Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 3"SoIucones (continuacin) 3. Cree y ejecute un bloque PLISQL que acepte dos nmeros por medio de variables de SQL*Plus. Se debera dividir el primer nmero entre el segundo, y despus aadir el segundo nmero al resultado. El resultado debera escribifse ein una variable PL/ SQL e imprimirse en la pantalla a travs de una variable de SET VERIFY OFF VARIABLE Vhreult NUMBER ACCEPT pnum1 PROMPT 'Please enter the first number: ACCEPT pnum2 PROMPT 'Please enter the second number:

Prctica 3 Soluciones (continuacin) 4. Genere un bloque PL/SQL que calcule la compensacin total para un ao. El salario anual y el porcentaje anual de bonicaciones se pasarn al bloque PL/SQL a travs de variables de sustitucin SQL*Plus y el importe do las bonicaciones tendr que ser convertido de un nmero entero a un decimal (por ejemplo, 15 a 0.15). Si el salario es nulo, asignele cero antes de calcular la compensacin total. Ejecute el bloque PL/SQL. Recuerde: Utilice la funcin NVL para gesionar los valores nulos. Nota: Para comprobar el caso de la funcin NVL, necesitaremos escribir NULL en el prompt; ya que pulsar [Return] provoca un error. SET VERIFY OFF VARIABLE NUMBER ACCEPT pwsalary PROMPT 'Please enter the salary amount: ' ACCEPT p_bonua PROMPT 'Please enter the bonus percentage: ' Desarrollo de Aplicaciones con PL/SQL Apndice

Prctica 4 Soluciones l. Cree un bloque PL/SQL que seleccione el departamento con el nmero ms alto de la tabla DEPT y lo almacene en una variable SQL*Plus. Imprima los resultados en la pantalla. Guarde su bloque PL/SQL en un archivo llamado p4q1.sql.. VARIABLE gmax*deptno NUMBER 2. Cree un bloque PUSQL que inserte un nuevo departamento en la tabla DEPT. Guarde su bloque PL/SQL en un archivo llamado p4q2.sql. a. Utilice el nmero del departamento recuperado del ejercicio 1 y aada 10 al nmero como nmero de departamento de entrada para el nuevo depimamemto4 b. Cree un parmetro para el nombre del departamento. c. Por el momento deje la ubicacin como nula. d. Ejecute el bloque PL/SQL Desarrollo de Aplicaciones con PLISQL Apndice E~11

Prctica 4 Soluciones (continuacin) SET VERIFY OFF ACCEPT pmdeptvname PROMPT 'Introduzca el nombre del departamento: DECLARE v__deptno DEPT . DEPTNO951YPE ; BEGIN vudeptno :gwmaxwdeptno + 10; INSERT INTO dept (deptno, dname, loc) VALUES ivveptno, '&p*dept._name, NULL); COMMIT; END; / SET VERIFY ON d. Ejecute el bloque PL/SQL, e. Muestre el nuevo depanamemo que ha creado. 3. Cree un bloque PL/SQL que actualice la ubicacin de un departamento existente. Guarde el bloque PL/SQL es un archivo llamado p4q3.sql. a. Cree un parmetro para el nmero del departamento. b. Cree un parmetro para la ubicacin del depanamento. c. Compruebe el bloque PL/SQL. d. Muestre el nmero de departamento, el nombre del departamento y la ubicacin del departamento actualizado. SET VERIFY OFF ACCEPT pvdeptno PROMPT Introduzca el codigo de departamento: ACCEPT p_loc PROMPT Introduzca la localidad del departamento: ' BEGIN UPDATE dept: SET loc = WHERE deptno &p_deptn0: COMMIT; END; / SET VERIFY ON SQL> START p4q3.sq1 Desarrollo de Aplicaciones can PL/SQL Apndice E-12

Prctica 4 Soluciones (cuntnuacin) 4. Cree un bloque PIJSQL que suprima el departamento creado en el ejercicio 2. Guarde el bloque PL/SQL en un archivo llamado p4q4.sqlA a. Cree un parmetro para el nmero de departamento. b. Imprima en la pantalla el nmero de las afectadas. c. Compruebe el bloquePL/SQL. Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 4 Soluciones (continuacin) d. Qu pasa si introduce un nmero de depaxtamemo que no existe? Si el operador introduce un nmero de departamento que no existe, el bloque PL/SQL se completa satisfactoriamente. porque esto no constituye una excepcin. e. Confume que el departamento se ha suprimido. SQL> SELECT * 2 FROM dept; 3 WHERE deptno = Smmdeptno ; Desarrollo de Aplicaciones con PIJSQL Apndice E-14

Prctica 5 Soluciones 1. Ejecute el script messages.sql para crear la tabla MESSAGES. Escriba un bloque PL/SQL para insertar nmeros en la tabla MESSAGES` CREATE TABLE messages (results VARCHAR2 (60)) / a. Inserte los nmeros 1 a 10 excepto 6 y 8. b. Haga commit antes del fnal del bloque. BEGI N FOR i IN 1..10 LOOP IF i 6 or i = 8 THEN null: ELSE INSERT INTO messages (results) VALUES (5.); END IF; COMMIT 7 END LOOP ENDI c. Haga una seleccin en la tabla MESSAGES para vecar que funcion su bloque PL/SQL. SQL> SELECT * 2 FROM messages: Cree un bloque PL/'SQL que ei importe de comisin de un empleado, basndose en sueldo del empleado. a. Acepte el nmero de empleado como entrada de usuau con un parmetro de sustitucin SQL*Plus. b. Si el sueldo del empleado es inferior a 100053, establezca el impone de comisin del empleado en un 10% del sueldo. c. S el sueldo del empleado est entre 1000$ y 15()0$, establezca el importe de comisin del empleado en un 15% del sueldo. d Si el sueldo del empleado pasa de 150055, establezca el importe de comisin del empleado en el 20% del sueldoA e. Si el sueldo del empleado es NULL, establezca el importe de comisin del empleado en 0. f . Haga commit. Desarrollo de Aplicaciones con PUSQL Apndice E-15

Prctica 5 Soluciones (continuacin) ACCEPT pMempno PROMPT 'Please enter employee number: g. Compruebe el bloque PUSQL para cada caso utilizando los siguientes casos de prueba, y compruebe todas las comisiones actualizadas. Nmero de empleado Sueldo Comisin Resultante 7369 800 80 7934 130() 195 7499 1600 320 8000 NULL O Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 5 Snlucinnes (continuacin) SQL> SELECT empno. Bal, comm 2 FROM emp 3 WHERE 4 ORDER BY comm; Si tiene tiempo, complete los siguientes ejercicios. 3. 4. Cree un bloque PL/SQL que recompense a un empleado aadiendo un asterisco en la columna STARS por cada 10033 del sueldo del empleado. Redondee el sueldo del empleado hasta el nmero entero Aada una nueva columna en la tabla EMP para almacenar asteriscos (*) sQL> ALTER TABLE emp 2 ADD stars vARCaAR2(100): ms cercano. Guarde el bloque PL/SQL en un archivo llamado p5q4.sql. a, Acepte el Id del empleado como entrada del usuario con un parmetro de sustitucin SQL*Plus. b. Inicalice una variable que contenga una cadena vacia, un asterisco a la cadena por cada 100$ del sueldo. Por ejemplo, si el empleado tiene un sueldo de 80035, la cadena de asteriscos contar con ocho asteriscosA d. Actualice la columna STARS del empleado con la cadena de asteriscos e, Haga commit f. Compruebe el bloque con un empleado que no tiene sueldo y con un empleado que tiene sueldo. SET VERIFY OFF END LOOP; UPDATE emp SET stars v_asterisk WHERE empno vempno; COMMIT; END. / SET VERIFY ON SQL> START SQL> SELECT empno, sal, stars 2 FROMemp 3 WHERE empno IN (7934, 8000), ACCEPT p_empno PROMPT Please enter the employee number: Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 6 Soluciones L Crear una nueva tabla en la que almacenar empleados y sus sueldos. SQL> CREATE TABLE topdogs 2 (name VARCHAR2 (25) , 3 salary NUMBER(11,2)); 2. Escriba un bloque PL/SQL para recuperar el nombre y el sueldo de un empleado concreto de la tabla EMP basndose en el nmero del empleado. Utilice tablas PL/SQL. a. Declare dos tablas PL/SQL, ENAME_TABLE y SAL_TABLE para almacenar temporalmente los nombres y los sueldos. b. Puesto que todos los nombres y sueldos son recuperados dentro del loop, almacnelos en tablas PL/SQL. c. Fuera del loop, transfiera los nombres y sueldos de las tablas PL/SQL a la tabla TOP__DOGS. do Vace la tabla TOPODOGS y ejecute el ejercicio. Desarrollo de Apiicaciones con PLISQL Apndice

Prctica 6 Soluciones (continuacin) SET VERIFY OFF ACCEPT p__empno PROMPT 'Please enter the employee number: ' DECLARE TYPE ename_tab1e_type IS TABLE OF VARCHAR2(10) INDEX BY BINARYMINTEGER; TYPE sa1_tah1etype IS TABLE OF NUMBER(7,2) INDEX BY BINARYMINTEGER; INSERT INTO top_dogs (name, salary) VALUES (ename_table (i) , ) : COMMIT: END ; / SET VERIFY ON Desarrollo de Aplicaciones con PL/SQL Apndice E-19

Prctica 7 Soluciones 1. Preprcse para este ejercicio vaciando la tabla TOILDOGS. 2. Cree un blnque PL/SQL que determine los empleados con sueldos ms altos. a. Acepte un nmero n como entrada de usuario con un parmetro de sustitucin SQL*Plus. b. En un bucle, obtenga los apellidos y sueldos de los n empleados con sueldos ms altos de la tabla EMP. c. Almacena los nombres y suddcs en la tabla TOP,DOGS. d. Suponga que no hay dos empleados con el mismo sueldo. e, Compruebe varios casos, como un n , 0 donde n es mayor que el nmero de empleados de la tabla EMP. ACCEPT pmnum PROMPT Please enter the number of top money makers: fA Vaca la tabla TOP_DOGS despus de cada prueba. Desarrollo de Aplicaciones con PLISGL Apndice

Prciica 7 Soluciones (continuacin) 3. Considere el caso de que varios empleados tienen el mismo salario. Si se incluye una persona, deber incluirse tambin a todas las personas con el mismo sueldo. 21. Por ejemplo, si el usuario introduce un valor de 2 para rz, apareceran King, Ford y Scott. (Estos dos ultimos empleados tienen el segundo sueldo ms alto). b. Si el usuario introduce un valor de 3, aparecern King, Ford, Scott y Jones. Suprma todas las las de TOP_DOGS y pruebe el ejercicio. CURSOR empcursor IS SELECT ename. sal FROM emp WHERE Bal IS NOT NULL ORDER BY Bal DESC BEGIN Desarrollo de Aplicaciones con PL/SQL Apndice E-21

Prctica 8 Soluciones 1. Ejecute una consulta para recuperar todos los departamemos y empleados de cada departamento. Inserte los resultados en la tabla MESSAGES, Utilice un cursor para recuperar el nmero de dpanamemo y transralo a un cursor para recuperar los empleados de ese departamento. Desarrollo de Aplicaciones con PL/SQL Apndice E-22

Prctica 8 Solucinnes (continuacin) 2, Modique p5q4.sql para incorporar la funcionalidad FOR UPDATE y WHERE CURRENT OF al procesamiento de cursores, K SET VERIFY OFF ACCEPT p_empno IPROMPT 'Please enter the employee nube Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 9 Soluciones l. Escriba un PL/SQL para seleccionar el nombre del empleado con un valor concreto de sueldo. Le preguntaremos el sueldo al usuario a travs de un parametro SQL*Plus. a. Si el sueldo introducido devuelve ms de una gestione la excepcin con un manejador de excepciones apropiado e inserte en la tabla MESSAGES Ms de un empleado con un sueldo de <.sueldo>. b. Si el sueldo introducido no devuelve ninguna fila, gestione la excepcin con un manejador de excepciones apropiado e inserte en la tabla MESSAGES Ningn empleado con un sueldo de <sueld0>. C, Si el sueldo introducido solo devuelve una fila, insene en la tabla MESSAGES el nombre del empelado y el importe del sueldo. d. Gestione cualquier otra excepcin con un manejador de excepciones apropiado e inserte en la tabla MESSAGES Se produjo algn otro error` e. Pruebe el bloque con varios casos SET VERIFY OFF ACCEPT p_sa1 PROMPT 'Please enter the salary value: ' WHEN nodatafound THEN INSERT INTO messages (results) VALUES ('No employee with a salary of H TOCHAR(v_sal)); WHEN too__many,_rows THEN INSERT INTO messages (results) VALUES ('More than one employee with a salary of ' H TO_CHAR(v__sa1) ) ; WHEN others THEN INSERT INTO messages (results) VALUES ('Some other error occurred. '); END: / SET VERIFY ON SQL> START p9ql.Bq1 Desarrollo de Aplicaciones con PUSQL Apndice E-24

Prctica 9 Soluciones (continuacin) 2. Modque p4q3.sql para aadir un manejador de excepciones. a, Escriba un manejador para que comunique un mensaje al usuario diciendo que el departamento especicado no existe, b. Ejecute el bloque PL/SQL introduciendo un departamento que no existe. SET VERIFY OFF Desarroilo de Apiicacones con PUSQL Apndice E-25

Prciica 9 Soluciones (continuacin) 3. Escriba un bloque PL/SQL que imprima los nombres de los empleados que ganan 100$ ms o menos del valor del salao introducido. a. Si no hay ningn empleado dentro de ese rango de sueldo, muestre un mensaje al usuario indicando cul es el caso Utilice una excepcin para este caso. b. Si hay uno o ms empleados dentro de ese rango, el mensaje debera indicar cuntos empleados hay en ese rango de sueldo. c. Gestione cualquier otra excepcin con un manejador de excepciones apropiado, el mensaje debera indicar que se ha producido otro error. SET VERIFY OFF ACCEPT psal PROMPT Please enter the salary: ' Desarrollo de Aplicaciones con PUSQL Apndice E-26

Prctica 10: Soluciones 1. Crear y llamar al procedimiento ADD__PROD y analizar los resultados: 3. b. Crear un procedimiento llamado ADD_PROD para insertar un nuevo producto en la tabla PRODUCT. CREATE OR REPLACE PROCEDURE add Mprod 1N v_descrip IN product.descrip"/TYPE) IS BEGIN INSERT INTO product (prodid, descrip) VALUES (v_prodid, v__deBcrip); COMMIT; END add _prod; / Compile el cdigo, llame al procedimiento, y a continuacin, consulte la tabla PRODUCT para ver los resultados: Procedure created. SQL> EXECUTE add__prod (9999, PL/SQL procedure successfully completed. SP TENNIS BALLS') Llame de nuevo al procedimiento, pasando un valor para prodid de 100860. Sabra dar una explicacin sobre qu pasa y por qu? SQL> EXECUTE add__prOd (100860, begin addprod(l00860, 'SP ADULT TENNIS RACKET') ERROR at line 1 Hay una restriccin de integridad de clave primaria sobre la columna prodd. Desarrollo de Aplicaciones con PUSQL Apndice E-27

Prctica 10: Soluciones (continuacin) 2. Cree un procedimiento llamado UPDMPROD para modificar un producto dc la tabla PRODUCT , a. Crcc un procedimiento llamado UPD__PROD para modificar la descripcin del producto. Incluya el control de excepciones necesario: IS BEGIN UPDATE product SET descrip v_descrip IF SQL/QNOTFOUND THEN RAISEHAPPLICATION_ERROR(-20202, 'N0 products updated. ) ; END IF.' END updjrodi / b. Compile el cdigo, llame al procedimiento, y a continuacin consulte la tabla PRODUCT para verlos resultados. Tambin chequeo el control de excepciones, intentando modificar un producto que no existe. Procedure created. SQL) EXECUTE upd_pr0d (9999, 'SP TENNIS NETS') PL/SQL procedure successfully completed. Desarrollo de Aplicaciones con PLISQL Apndice

Prctica 1D: Soluciones (continuacin) 3. Cree un procedimiento llamado DELPROD para borrar un producto de la tabla PRODUCT. a. Cree un procedimiento llamado DEL*PROD para borrar un producto de la tabla PRODUCT. Incluya el control de excepciones necesario: CREATE OR REPLACE PROCEDURE de1__prod (vwprcdid IN product.prodid%TYPE) IS BEGIN DELETE FROM product WHERE prodd IF SQUBSNOTFOUND THEN RAISEAPPLICATION_ERROR(-20203, No products deleted. ) ; END IF; END DELMPROD; / b. Compile el cdigo, llame al procedimiento, y a continuacin consulte la tabla PRODUCT para ver los resultados. Tambin chequee el control de excepciones, intentando borrar un producto que no existe. Procedure created. SQL> EXECUTE de1_prod (9999) PL/SQL successfully completed, Desarrollo de Aplicaciones con PL/SQL Apndice E-29

Prctica 10: Soluciones (continuacin) 4. Cree un procedimiento para consultar la tabla EMP que recupere el salario y oficio del empleado 7839. a. Cree un procedimiento que devuleva el SALARIO y OFICIO del empleado especicado. (Use EMPNO). b. Compile el cdigo, llame al procedimiento y vsuace el salario y oficio para el empleado nmero Procedure created. SQL> VARIABLE g_Ba1 NUMBER SQL> VARIABLE Ob VARCHAR2 (15) SQL> EXECUTE query~emp (7839, :g_job) PL/SQL procedure successfully Completed. Desarrollo de Aplicaciones can PLISQL Apndice E-30

Prctica 10: Soluciones (continuacin) SQL> PRINT gujob GMJOB PRESIDENT c. Llame otra vez al procedimiento, pasando el nmero de empleado 9898. Qu ocurre? Por qu? ERROR at line 1: ORA~0l403: no data found ORAv06512: at SCOTT.QUERY__EMP", line 7 ORA-O6512: at line 1 No hay ningn empleado enla tabla EMP que se corresponda con el nmero 9898. La sentencia SELECT no recupera datos de la B.D, resdltando un error fatal de PL/SQL: NODATAFOUND. Desarrollo de Aplicaciones con PUSQL Apndice E-31

Prctica 11: Soluciones 1. Cree y llame a la funcin que devuelva la descripcin de un producto. a. Cree una funcin llamada Q_PROD que devuelva la descripcin de un producto, a una variable host: CREATE OR REPLACE FUNCTION CLpr0d (vprodid IN product.prodid/JTYPE) RETURN VARCHAR2 IS v~deecrip product . descrip%TYPE; BEGIN SELECT descrip INTO v_descrip FROM product WHERE prodid = v__prodid; RETURN (vdescrip) ; END q_prodi / b. Compile the cdigo, llame a la funcin, y a continuacin csnsuke la variable host para ver el resultado: Funct ion Created _ SQL> VARIABLE g__descrip VARCHAR2(30) SQL> EXECUTE :gdescrip Lprod (101863) PL/SQL procedure successfully Completed. SQL> PRINT gwdescrip GDESCRIP SP JUNIOR RACKET Desarroilo de Aplicaciones con PLISQL Apndice E-32

Prctica 11: Snluciones (continuacin) 2. Crear una funcin almacenada ANNUALHCOMP para devolver el salario anual cuando se pasa el salario mensual y la comisin de un empleado, Asegurarse de que la funcin controla valores NULL. a. Crear y llamar ala funcin ANNUAL_COMP, pasando los valores del salario mensual y de la comisin. La funcin debera devolver el salario anual, denido CREATE OR REPLACE FUNCTION annua1comp (vwsal IN emp.sal%TYPE, vacomm IN emp.comm"<=TYPE) RETURN NUMBER IS BEGIN RETURN (NVL(v*sa1,0) * 12 + NVL(vcomm,0)); END annualwcompp / b. Utilice la funcin almacenada en una sentencia SELECT contra la tabla EMP. SQL> SELECT empno, ename, 2 annua1_ccmp(sa1, comm) "Annual Compensation" 3 FROM emp; EMPNO ENAME Annual Compensation 7839 KING 60000 7698 BLAKE 34200 7782 CLARK 29400 '7566 JONES 35700 14 rows selected. Desarrollo de Aplicaciones con PL/SQL Apndice E-33

Prctica 11: Soluciones (continuacin) 3. Crear un procedimiento, NEW_EMP, para insertar un empleado nuevo dentro dela tabla EMP. El procedimiento debera contener una llamada a la funcin VALIDDEPTN() para comprobar si existe en la xabla el departamento especcado para el nuevo empleado. a. Crear una funcin VALID,DEPTNO para validar un nmero de departamento especcado. La funcin debera devolver un BOOLEAN. CREATE OR REPLACE FUNCTION va1id_deptno (v__deptno IN dept.deptno%'IYPE) RETURN BOOLEAN IS vwduxnmy VARCHAR2(1); BEGIN SELECT 'X' INTO v_dummy FROM dept WHERE deptno = v_dept:no; RETURN (TRUE) ; EXCEPTION WHEN NoDATAFOUND THEN RETURN (FALSE); END va1id_eptno; / Desarrollo de Aplicaciones con PLISQL Apndice

Prctica 11: Soluciones (continuacin) b. Crear el procedimiento NEWEMP para aadir un empleado a la tabla EMP, Debera aadirse un nuevo registro a EMP si la funcin devuelve TRUE. Sila funcin devuelve FALSE, el prodimiento debera alertar al usuario con un mensaje apropiado Denir valores DEFAULT para la mayora de argumentos. La comisin por defecto es 0, el salario por defecto es 1000, el nmero de departamento por defecto es 30, el puesto por defecto es SALESMAN y el nmero de gestor por defecto es 7839. c. Comprobar el procedimiento NEW_EMP aadiendo un nuevo nombre de empleado al departamento 99 (HARRIS). Dejar el resto delos parmetros con sus valores por defecto, Cual es el resultado?. SQL> execute newwemp(v_ename => HARRIS',v_deptno => 99) Invalid department number. Try again. PL/SQL procedure successfully completed. d. Comprobar el procedimiento NEW_EMP aadiendo un nuevo nombre de empleado al departamento 30 (HARRIS). Dejar el resto de los parmetros con sus valores por defecto, Cual es el resultado?. PL/ SQL procedure successfully Completed . Desarrollo de Aplicaciones can PUSQL Apndice E-35

Prctica 12: Soluciones 1. Cree la especicacin y cuerpo de un paquete llamado PROD_PACK que contenga los procedimientos ADDMPRD, UPD_PROD y DELMPROD y la funcin Q_PROD. a. Hacer todos los programas pblicos. Nota: Considere si sigue necesitando los procedimientos y la funcin, que acaba de empaquetar, como objetos independientes. CREATE OR REPLACE PACKAGE pr0d__pack IS PRQCEDURE addmprod (vvprodid IN product.prodid%'IYPE, vwdescrip IN product.deacrip/UTYPE) PROCEDURE upd _prod (v_prodid IN product.prodid%TYPE, v_descrp IN product.descrip"/QTYPE) ; PROCEDURE del prod (v_prodid IN product.prodid/'1YPE); RETURN VARCHAR2; END prod Jack; / Desarrolio de Aplicacinnes con PLISQL Apndice

Prctica 12: Soluciones (continuacin) CREATE OR REPLACE PACKAGE BODY prod___pack IS PROCEDURE add prod (v__prodd IN product.prodd%TYPE, v__descrp IN product.descrp%TYPE) IS BEGIN INSERT IMQ product (prodid, descrip) VALUES (vwprodid, v_descrip); END add Jarod; PROCEDURE upd _prod (vwprodd IN prcduct.prodd%TYPE, v_descrip IN product.descrp%TYPE) IS BEGIN UPDATE product SET descrip vwdescrp RAISE_APPLICATION_ERROR ( 02 02 , No products updated. ) ; PROCEDURE del _prod (vprodid IN product.prodd/JPYPE) IS BEGIN DELETE FROM product WHERE prodid = RAISEMAPPLICATION_ERR0R (-20203, 'No products deleted. ) ; Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 12: Soluciones (continuacin) FUNCTION q_prod (v_prodd IN product.prodid%TYPE) RETURN VARCHAR2 IS vmdescrip product; . descrip/QTYPE; BEGIN SELECT descrip scrip FROM product b. Llame al procedincnto DEL_PROD: SQL> execute prodMpack.delprod(100860) PL/SQL procedure successfully completed. C. Consulte la tabla PRODUCT para ver el resultado. SQL> SELECT * from product 2 WHERE prodid -_- 100860: no rows selected Desarrollo de Aplicaciones con PL/SQL Apndice E-38

Prctica 12: Soluciones (conlnuacin) 2. Cree y llame a un paquete que contenga construcciones pblicas y privadas. a. Cree la especifcacin y el cuerpo de un paquete llamado EMP~PACK que contenga el procedimiento NEWHEMP como construccin pblica y la funcin VALIDDEPTNO, como construccin privada. CREATE OR REPLACE PACKAGE emp__pack IS PROCEDURE newnemp DEFAULT DEFAULT DEFAULT DEFAULT DEFAULT Desarrollo de Aplicaciones con PL/SQL Apndice

Prctica 13: Soluciones (continuacin) CREATE OR REPLACE PACKAGE BODY empjack IS FUNCTION validmdeptno (v__deptno IN dept.deptno%TYPE) RETURN BOOLEAN Desarrollo de Aplicaaiones con PLISQL Apndice

Prctica 12: Soluciones (continuacin) b. Llame al procedimiento NEW_EMP utilizando el valor 99 como n de departamento: Invalid department number try again. c. Llame al procedimiento NEW_EMP utilizando el valor 30 como 11 de departamento: PL/SQL procedure successfully completed. 3. Crear un paquete llamado CHK__PACK que contenga los procedimientos CHKJIIREDATE y CHK_DEPTMGR, Hacerlos como programas pblicos. a. El procedimiento CHK__HIREDATE comprueba si la fecha de contratacin de un empleado est dentro del siguiente rango: [sysdatc - 50 years, sysdatc + 3 months] Notas: Sila fecha es invalida, aparecera un mensaje de error en la aplicacin indicando por que no se acepta la fecha. Asegurese que se ignora el componente del tiempo en el valor de la fecha. Utilizar una constante para referirse al lmite de 5() aos. Si el valor de la fecha de contrato es un valor nulo, sera considerada como una fecha de contrato invlida. b. El procedimiento CHK_DEPT_MGR comprueba la combinacin del departamento y dei director para un empleado dado. Esto significa que ei nmero de director facilitado debe ser igual ai nmero de director que supervisa el departamento del empleado. Notas: Si la combinacin nmero/director del departamento es invlida, aparecera un mensaje de error en la aplicacin. Asegurese de controlar el caso en el que no hay director para el departamento. Desarrollo de Aplicaciones can PUSQL Apndice E-41

Prctica 12: Saluciones (continuacin) CREATE OR REPLACE PACKAGE BODY chk__pack IS PROCEDURE chkhiredate(vdate in emp.hiredate/ctype) OR v~date IS NULL THEN RAISE__APPLICATION_ERROR ( 2 02 00 , Not a valid hiredate'); RAISE_APPLICA'1ION_ERROR(-20201. Not the mgr for this department ) ; WHEN OTHERS THEN RAISE__APPLICATION_ERROR ( -2 02 02 , Other error occurred' ) ; END chk_dept_mgr.' END chkmpack; / Desarrollo de Aplicaciones can FLISOL Apndice

Prctica 12: Soluciones (continuacin) c. Pruebe el procedimiento CHK_HIREDA'I'E mediante el comando siguiente: d. Pruebe el procedimiento CHK__HIREDA'I`E mediante el comando siguiente:

ERROR at line 1: ORA20200: Not a valid hiredate ORA-06512: at "SCOTT CHKMPACK" , line 9 ORA~065l2: at line 1 e. Pruebe el procedimiento CHKJIIREDATE mediante el comando siguiente: SQL> execute chkpack.chkhiredate('01-JAN-98') PL/SQL procedure successfully completed. Desarrollo de Aplicaciones con PLISQL Apndice

Prctica 13: Solucianes 1. Cree un nuevo paquete que implemente una regla de negocio. a. Cree un procedimiento llamado CHK_DEPT_JOB para vericar si determinada combinacin de nmero de depto. y trabajo es vlida. En este caso, vlida signica que tiene que ser una combinacin que actualmente exista en la tabla EMP. Notas: Use una tabla PL/SQL para almacenar las combinaciones vlidas de dpto. y ocio. La tabla PUSQL necesita ser rellcnada slo una vez. ' Si la combinacin no es vlida, emitir un mensaje de error en la aplicacin. Desarrollo de Aplicaciones con PUSQL Apndice E-44

Prctica 13: Soluciones (continuacin) CREATE OR REPLACE PACKAGE BODY Chk__paCk2 IS number TYPE emp_tab1e_type IS TABLE OF VARCHAR2(50) INDEX BY BINARYMINTEGER; ob emp_tab1etype ; CURSOR emp_cur IS SELECT deptno,job FROM emp; RAISE_APPLICATION_ERROR(-20500, 'Not a valid job for this dept'); Desarrollo de Aplicaciones con PLISQL Apndice E-45

Prctica 13: Soluciones (continuacin) b. Pruebe el procedimiento empaquetado CHK_DEP1`_JOB mediante el comando siguiente: C. Pruebe el procedimiento empaquetado CHK_DEPTJOB mediante el comando siguiente: Desarrollo de Aplicaciones con PL/SQL Apndice

Prctica 13: Soluciones (continuacin) 2. Cree dos funciones, con el mismo nombre PRINTIT, para imprimir una fecha 0 un nmero, dependiendo del mtodo de llamar ala funcin. Notas: Para imprimir el valor de fecha, utilizar como formato de entrada y como formato de salida FmMonth/dd/yyyy". Asegurarse de que se manejan entradas invljdas. ~ Para imprimir el nmero, utilizar como formato de salida 999,999.0U. CREATE OR REPLACE PACKAGE over_1oad is FUNCTION prnt__t (v_arg date) RETURN VARCHAR2 FUNCTION print__it(v__arg VARCHAR2) RETURN NUMBER; END over__1cad; / CREATE OR REPLACE PACKAGE BODY Cveruload is FUNCTION print_it(v__arg date) RETURN VARCHAR2 IS BEGIN RETURN to_char(v_arg, 'FmMonth, dd/yyyy' ) ; END FUNCTION printmit (vmarg VARCHAR2) RETURN NUMBER ' Is BEGIN RETURN tounumbex (v__arg, 999, 999 . 00 ) ; END END overwloadf / Desarrollo de Aplicaciones con PLISQL Apndice E-47

Prctica 13: Soluciones (continuacin) a. Pruebe la primera versin de PRINT__IT mediante el comando siguiente: SQL> variable todaysdate varchar2(20) PL/SQL procedure successfully Completed. SQL> print todays_date TODAYSDATE January, 29/1998 b. Pruebe la segunda versin de PRINTJT mediante el comando siguiente: Desarrollo de Aplicaciones con PLISQL Apndice E-48

Prctica 14: Soluciones 1. Las operaciones DML sobre tablas solamente se permitirn en horas de trabajo, es decir, entre las 8:45 dela maana y las 5:50 de la tarde; de lunes a viernes. a. Cree un procedimiento almacenado llamado SECURE_DML que muestre un mensaje de error, en caso de no cumplir la rega especcada anteriormente, como Slo puede modicar datos durante las horas ociales de trabajo. CREATE QB. REPLACE PROCEDURE SeCure_dm1 IS BEGIN IF TOWCHAR (SYSDATE, HH24:MI') NOT BETWEEN '08:45' AND '17:30' OR T0__CHAR (SYSDATE, IN ('SAT , 'SUN') THEN RAISE__APPLICATION_ERROR (-20205, 'You may only make changes during normal office hours' ); END IF? END securedml; / 2. Crear un nigger en la tabla PRODUCT que llame al procedimiento de arriba. CREATE OR REPLACE TRIGGER securenprod BEFORE INSERT OR UPDATE OR DELETE ON product BEGIN Becurendmlf END secure__prod; a. Pruebe el procedrniento, modicando la franja horaria propuesta en el prodimiento inicial, e intentando insertar un nuevo registro en la tabla PRODUCT. Despus de la comprobacin, restablezca la franja horaria a sus valores originales (paso 1). SQL> insert into product 2 values (99999, 'My Product' )7 insert into product * ERROR at line 1: ORA-20205: You may only make Changes during normal office hours. ORA-06512: at "SCOTT.SECURE__DML", line 6 ORA~065l2: at "SCOTT.SECURE~PROD", line 2 ORA~O4088: error during execution of trigger 'SCOTT.SECUREPROD' Desarrollo de Aplicaciones con PUSQL Apndice E-49

Prctica 14: Soluciones (continuacin) 3. La comisin de un vendedor cambiara con cualquier pedido nuevo 0 por cambios en los pedidos existentes. Su comisin se almacena en la columna COMM de la tabla EMP. En la tabla CUSTOMER se asigna un vendedor a un cliente en particular. a. Crear un procedimiento que actualizar la comisin de un vendedor. Utilizaremos parmetros para enviar el identificador del cliente, el total antiguo del pedido y el total nuevo del pedido, desde el trigger que hace la llamada. El procedimiento necesitar localizar el nmero del empleado en la tabla CUSTOMER y actualizar el registro del vendedor en la tabla EMP, aadiendo una nueva comisin al valor existente. Para este ejercicio pondremos una porcentaje de comisin del 5%. CREATE OR REPLACE PROCEDURE update_cOmm IN NUMBER, IN NUMBER, v_new_tot IN NUMBER) IS v__repid NUMBER ; omm NUMBER; BEGIN SELECT repid INTO v_:cepid FROM customer WHERE custid = vwcustid; b. Crear un nigger en la tabla ORD el cual llamar al procedimiento, pasando los parmetros necesarios. CREATE OR REFLACE TRIGGER updateempcomm AFTER INSERT OR UPDATE OR DELETE ON Ord FOR EACH ROW BEGIN update_comm (:new.custid, :o1d.tota1, :new.total); END: / Desarrollo de Aplicaciones con PLJSQL Apndice E-50

Prctica 14: Soluciones (continuacin) c. Modicar el pedido 601, para asignarle un total de Vericar queI la comisin de WARD se ha incrementado en 0.03. La comisin original cra 500. SQL> UPDATE Ord SET total 3 WHERE ordid = 601; SQL> SELECT ename, comm FROM emp WHERE ename = 'WARD' ENAME COMM WARD 500 _ 03 4. A las tablas EMP y DEPT se les aplica una serie de reglas de negocio, 2. Decidir cmo implementar cada regla: por medio de constraints o triggers. Qu restricciones o triggers se necesitan y qu problemas podemos esperar?. b. Implemente las reglas de negocio mediante triggers. Reglas de Negoco 1. Los vendedores siempre deberan recibir una comisin. Los empleados que no son vendedores nunca deberan recibir una comisin. Implemente la regla 1 con una conslaint. ALTER TABLE emp ADD CONSTRAINT emp_comm_chk CHECK ((job = 'SALESMAN and comm IS NOT NULL) OR (jab 'SALESMAN' and Comm IS NULL)): Desarrollo de Anicaciones con PLISQL Apndice

Prctica 14: Soluciones (continuacin) 2. La rabia EMP debera contener exactamente un PRESIDENT. Comprobar nuestra respuesta. CREATE OR REPLACE TRIGGER presidente BEFORE DELETE OR INSERT OR UPDATE OF job ON emp FOR EACH ROW DECLARE num _presi NUMBER; BEG IF DELETING AND :OLD.JOB = 'PRESIDENT' THEN RAISE_APPLICATIONERROR (-20001, 'No podemos borrar al PRESIDENT' ) ; END IF; IF UPDATING THEN IF :OLD.JOB = 'PRESIDENT' THEN IF :NEW.JOB 'PRESIDENT' THEN RAISEAPPLICA'IION__ERROR (-20002 , El PRESIDENT no puede dejar de serlo' ) ; END IF; ELSE IF :NEW.JOB = 'PRESIDENT' THEN RAISEAPPLICATION_ERROR (-20003, Ya tenemos un PRESIDENT' ) ; END IF; END IF; END IF; IF INSERTING AND :NEW.JOB = PRESIDENT THEN RAISE_APPLICATION__ERROR (-20003 , 'Ya tenemos un PRESIDENT' ) SQL> insert into emp (empno, ename, job. deptno) 2 values (7800, HARRIS, 'PRESIDENT',20); insert; into emp (empno, ename, job, deptno) ERROR at line 1: ORA20003: Ya tenemos un President ORA"06512: at "SCOTT.PRESIDENTE", line 2 ORA~O4088: error during execution of trigger 'SCOTT.PRESIDENTE' Desarrollo de Aplicaciones con PLJSQL Apndice

Prctica 14: Soluciones (continuacin) 3. Los salarios solo podran aumentarse, no disminuirse. Comprobar nuestra respuesta. CREATE OR REPLACE TRIGGER check*sa1 BEFORE UPDATE OF sal ON emp FOR EACH ROW WHEN (new.sa1 o1d.sa1) BEGIN RAISEAPPLICA'1IONmERROR(-20002 , Salary may not be reduced ' ) , END check_sal; / SQL> update emp 2 set sal 1160 3 where empno = 7934; update emp * ERROR at line 1: ORA~20002: Salary may not be reduced ORA-06512: at "SCO'IT.CHECK_SAL", line 2 ORA-O4088: error during execution of trigger 'SCOTT.CHECK_SAL Desarrollo de Aplicaciones con PUSQL Apndice

Prctica 14: Soluciones (continuacin) 4. Si un dcpartamento se traslada a otra parte, cada empleado de ese departamento tendr automticamente un incremento de salado del 2%. CREATE OR REPLACE TRIGGER change_1ocation AFTER UPDATE OF loc ON dept FOR EACH ROW WHEN (0LD.loc NEW.loc) BEGIN SET sal sa1*1.02 WHERE deptno = :NEw.deptno; END changewlocation; / SQL> select ename, sal, deptno 2 from emp 3 where deptno = 30, ENAME SAL DEPTNO BLAKE 2 8 5 O 3 0 NARTIN 12 5 O 3 O ALLEN 1 6 0 O 3 O SQL> update dept; 2 Set loc = 'HOUSTON' 3 where deptno = 30; SQL> select ename, sal, deptno 2 from emp 3 where deptno = 30; ENAME SAL DEPTNO BLAKE 2 9 O7 3 O MARTIN 1 2 7 5 3 0 ALLEN 1 6 3 2 3 0 Desarrollo de Aplicaciones con PUSQL Apndice E-54

Prctica 15: Soluciones 1. Contesta a las siguientes preguntas: a. Pueden una tabla o un sinnimo ser invlidos? Una tabla 0 sinnimo nunca puede ser nvalidado, sin embargo si pueden serlo los objetos dependientes. b. Imagine la siguiente situacin: El procedimiento standalone MY__PROC depende del procedimiento empaquetado MYPROC_PACK. ' La definicin del procedimiento MYPROC_PACK se cambia mediante recompilacin del cuerpo del paquete. La especificacin del procedimiento MY__PROC_PACK no se altera en la del paquete. ' Se invalida el procedimiento standalone MYPROC? Aunque el cuerpo del paquete sea reeompilado, el procedimiento standalone MY_PROC que depende del procedimiento empaquetado MY__PROCPACK, no resultar no vlido, porque la especificacin del paquete no ha cambiado. 2. Supongamos que hemos perdido el cdigo del procedimiento NEW_EMP y de la funcin VALDWDEPTNO que creamos en la leccin 11. Para regenerar el cdigo, crear un fichero spool paraconsultar la vista apropiada del Diccionario de Datos. SET ECHO OFF HEADING OFF FEEDBACK OFF VERIFY OFF COL DUMMY NOPRINT COL LINE NOPRINT SET PGESIZE 0 SPOOL RECREATE . SQL SELECT text , line FROM USERWSOURCE WHERE name = &the_object UNION SELECT 'CREATE OR REPLACE ',1 dummy FROM DUAL ORDER BY line / SELEC1` / ' FROM DUAL / SPOOL OFF SET PAGESIZE 24 SET FEEDBACK ON VERIFY ON HEADING ON ECHO ON Desarrollo de Aplicaciones con PLJSQL Apndice E-55

Prctica 15: Solucinnes (continuacin) 3. Ejecute el script utldlreexsql. Dibuja una jerarqua que mucsire todas las dependencias involucrando al procedimiento NEWHEMP y a la funcin VALlDDEPI`NO. Consulte la vista ideptree para ver los resultados. SQL> exec deptree_fi11( PROCEDURE , 'SCOTT' . 'NEW_EMP' ) PL/SQL procedure successfully completed. SQL> select * from ideptree; DEPENDENC IES PROCEDURE SCOTT . NEWMEMP SQL> exec deptreefi1l( FUNCTION , 'SCOTT' , VALIDDEP'INO' ) PL/SQL procedure successfully completed. SQL> select * from ideptree; DEPENDENCIES FUNCTION SCOTT . VALIDMDE PTNO PROCEDURE SCOTT . NEW EMP Ejercicio Opcional: 4. Validar los objetos invlidos de forma dinmica. a. Haga una copia de la tabla EMP, llamada EMP_COP. CREATE TABLE empgcop AS SELECT * FROM emp; b. Modcar la tabla EMP y aadir la columna TOTSAL(NUMBER(9,2)). ALTER TABLE emp ADD (totaal NUMBER(9,2) ); c. Crear un chern script para imprimir el nombre, tipo y status delos objetos invalides. SELECT ob3'ect_name, object_type, status FROM userobjects WHERE Status INVALID / Desarrollo de Aplicaciones con PL/SQL Apndice

Prctica 15: Soluciones (continuacin) d. Crear un procedimiento llamado C()MPILE_OBJ que recompile todos los objetos invlidos en nueso esquema. Haga uso del procedimiento ALTER_COMPILE dei paquete DBMSwDDL. CREATE OR REPLACE PROCEDURE comp1e_obj IS CURSOR obj__cur IS SELECT obj ectjzype! obj ect_name FROM userobj eats WHERE status ' INVALID ' AND obj ectgtype IN ( PROCEDURE , FUNCTION , PACKAGE , e. Ejecute el script anterior y chequcc el estado del valor de la columna. Desarrollo de Aplicaciones con PUSQL Apndce E-57