Diferència entre revisions de la pàgina «M2 - Bases de dades / Exercicis UF3: PL-SQL»

De wikiserver
Dreceres ràpides: navegació, cerca
(Solucions exercicis)
 
(Hi ha 269 revisions intermèdies del mateix usuari que no es mostren)
Línia 1: Línia 1:
==T3- Declaració de variables ==
+
==Introducció a PL/SQL==
  
*'''Exercici 1'''
+
'''1.-''' Quin bloc PL/SQL dels següents s'executa correctament?
 +
 
 +
<pre>
 +
    a) BEGIN
 +
        END;
 +
    b) DECLARE
 +
          v_amount INTEGER(10);
 +
        END;
 +
    c) DECLARE
 +
        BEGIN
 +
        END;
 +
    d) DECLARE
 +
          v_amount INTEGER(10);
 +
        BEGIN
 +
          DBMS_OUTPUT.PUT_LINE(v_amount);
 +
        END;
 +
</pre>
 +
 
 +
'''2.-''' Crea i executa un bloc anònim simple, la seva sortida ha de ser “Hello World”. Executa i guarda aquest sript com lab_01_02_soln.sql.
 +
 
 +
==Declaració de variables ==
  
:Avalua les següents declaracions de variables determinant quines no son correctes (donen error), explica perquè.
+
'''1.-''' Especifica identificadors vàlids i no vàlids:
  
::a) DECLARE v_id NUMBER(4);
+
:a) today
 +
:b) last_name
 +
:c) today’s_date
 +
:d) Number_of_days_in_February_this_year
 +
:e) Isleap$year
 +
:f) #number
 +
:g) NUMBER#
 +
:h) number1to7
  
::b) DECLARE v_x, v_y,v_z VARCHAR2(10);
+
'''2.-''' Identifica les declaracions e inicialitzacions de variables vàlides i no vàlides:
  
::c) DECLARE v_data_naixament DATE NOT NULL;
+
:a) number_of_copies&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PLS_INTEGER;
 +
:b) PRINTER_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constant VARCHAR2(10);
 +
:c) deliver_to&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2(10):=Johnson;
 +
:d) by_when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DATE:= CURRENT_DATE+1;
  
::d) DECLARE v_en_stock BOOLEAN :=1
+
'''3.-''' Examina el següent bloc anònim i selecciona la frase que serà certa de entre les següents:
 +
<pre>
 +
  DECLARE
 +
    v_fname VARCHAR2(20);
 +
    v_lname VARCHAR2(15) DEFAULT 'fernandez';
 +
  BEGIN
 +
    DBMS_OUTPUT.PUT_LINE(v_fname ||' ' ||v_lname);
 +
  END;
 +
</pre>
  
*'''Exercici 2'''
+
:a) El bloc s'executa correctament i s'imprimeix “fernandez”.
 +
:b) El bloc produeix un error perquè s'utilitza la variable fname sense inicialitzar-se.
 +
:c) El bloc s'executa correctament i s'imprimeix "null fernandez".
 +
:d) El bloc produeix un error perquè no es pot utilitzar la paraula clau DEFAULT per inicialitzar una variable de tipus VARCHAR2.
 +
:e) El bloc produeix un error perquè no es declara la variable v_fname.
  
:Determina el tipus de dades de les expressions resultants en les següents assignacions
+
'''4.-''' Modifica un bloc anònim existent i guarda'l com un nou script.
  
::a) v_dies_que_falten := v_date - SYSDATE;
+
:a) Obre el script lab_01_02_soln.sql, creat en la Pràctica 1.
 +
:b) En aquest bloc PL/SQL, declara las següents variables:
 +
::1. v_today del tipus DATE. Inicialitza today amb SYSDATE.
 +
::2. v_tomorrow del tipus today. Utilitza l'atribut %TYPE per declarar aquesta variable.
 +
:c) En la secció executable:
 +
::1. Inicialitza la variable v_tomorrow amb una expressió, que calculi la data de demà (agrega un 1 al valor de today)
 +
::2. Imprimeix el valor de v_today i tomorrow desprès de imprimir “Hello World”
 +
:d) Guarda el script com a lab_02_04_soln.sql i executa'l.
  
::b) v_sender := USER || ':' || TO_CHAR(v_deptno);
+
:La sortida de l'exemple és com la següent (els valors de v_today i v_tomorrow seran diferents per reflexar la data actual d'avui i la de demà):
  
::c) v_sum := $100,000+$250,000;
+
<pre>
 +
        anonymous bloc completed
 +
          Hello World
 +
        TODAY IS : 07-MAR-16
 +
        TOMORROW IS: 08-MAR-16
 +
</pre>
  
::d) v_bandera := TRUE;
+
'''5.-''' Edita el script lab_02_04_soln.sql.
  
::e) v_n1 := v_n2 > (2*v_n3);
+
:a) Agrega codi per crear dues variables d'enllaç: b_basic_percent i b_pf_percent. Ambdues de tipus NUMBER.
 +
:b) En la secció executable del bloc PL/SQL, assigna els valors 45 i 12 a b_basic_percent i b_pf_percent, respectivament.
 +
:c) Termina el bloc PL/SQL amb “/” i mostra el valor de las variables d'enllaç amb l'ordre PRINT.
 +
:d) Executa i guarda el script com a lab_02_05_soln.sql. La sortida de exemple és la següent:
 +
­<pre>
 +
        anonymous bloc completed
 +
        b_basic_percent
 +
        --
 +
        45
  
::f) v_valor := NULL;
+
        b_pf_percent
 +
        --
 +
        12
 +
</pre>
  
*'''Exercici 3'''
 
  
:Crea un bloc anònim per imprimir la frase “Benvingut a PL/SQL”
+
==Escriptura de Sentències Executables ==
  
*'''Exercici 4'''
+
En aquesta pràctica, examinaràs i escriuràs sentències executables.
  
:Crea un bloc que declari dues variables. Assigneu el valor d'aquestes variables PL/SQL a variables SQL*PLUS i imprimeix el valor d'aquestes dues variables per pantalla. Guarda el bloc PL/SQL en un arxiu anomenat p2q4.spl.
+
[[Imatge:M2UF3_ESE_1.png |600px|center| Escriptura de Sentències Executables]]
  
:::V_CHAR Character (variable length)
+
'''1.-''' Avalua el bloc PL/SQL anterior i determina el tipus de dada i el valor de cada una de les següents variables, segons les regles dels àmbits:
  
:::V_Number
+
:a) Valor de v_weight en la posició 1:
 +
:b) Valor de v_new_locn en la posició 1:
 +
:c) Valor de v_weight en la posició 2:
 +
:d) Valor de v_message en la posició 2:
 +
:e) Valor de v_new_locn en la posició 2:
  
::Assigna els següents valors a les variables:
+
[[Imatge:M2UF3_ESE_2.png |600px|center| Escriptura de Sentències Executables]]
  
:::Variable        Value
+
'''2.-''' En el bloc anterior, determina el valor i el tipus de dada en cada un dels següents cassos:
:::---------      ---------------------------------------------
 
:::V_CHAR          The literal '42 is the answer'
 
:::V_NUM          The first two characters form V_CHAR
 
­
 
<!--
 
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T3 | Solucions declaració de variables]]
 
-->
 
  
==T4- Sentencies executables ==
+
:a) Valor de v_customer en el bloc anidat:
 +
:b) Valor de v_name en el bloc anidat:
 +
:c) Valor de v_credit_rating en el bloc anidat:
 +
:d) Valor de v_customer en el bloc principal:
 +
:e) Valor de v_name en el bloc principal:
 +
:f) Valor de v_credit_rating en el bloc principal:
  
*'''Exercici 1'''
+
'''3.-''' Utilitza la mateixa sessió que vas utilitzar per executar les pràctiques de la lliçó anomenada "Declaració de Variables PL/SQL". Se has obert una nova sessió, executa lab_02_05_soln.sql. A continuació, edita lab_02_05_soln.sql de la siguent forma:
  
:Observa el següent bloc PL/SQL i determina els valors de les variables següents d'acord amb les regles d'àmbit
+
:a) Amb la sintaxis de comentaris d'una sola línia, comenta les línies que creen les variables d'enllaç i activa SERVEROUTPUT.
 +
:b) Amb els comentaris de varies línies, comenta en la secció executable les línies que assignen valors a les variables d'enllaç.
 +
:c) En la secció de declaracions:
 +
::1. Declara e inicialitza dues variables temporals per substituir les variables d'enllaç comentades.
 +
::2. Declara dues variables addicionals: v_fname de tipus VARCHAR2 i
 +
tamany 15, i v_emp_sal del tipus NUMBER i tamany 10.
 +
:d) Inclou la següent sentència SQL en la secció executable:
 +
<pre>
 +
    SELECT first_name, salary INTO v_fname, v_emp_sal
 +
    FROM employees WHERE employee_id=110;
 +
</pre>
 +
:e) Canvia la línia que imprimeix “Hello World” per a que imprimeixi “Hello” i el nom. A continuació, comenta les línies que mostren les dates i les que imprimeixen  les variables d'enllaç.
 +
:f) Calcula l'aportació de l'empleat al fons de previsió (PF). PF és el 12% del salari bàsic, i el salari bàsic es el 45% del salari. Utilitza les variables locals per fer el càlcul. Intenta utilitza només una expressió per calcular el valor de PF. Imprimeix el salari de l'empleat i la seva aportació a PF.
 +
:g) Executa i guarda el script com lab_03_03_soln.sql. La sortida de l'exemple és la següent:
 +
<pre>
 +
        anonymous bloc completed
 +
          Hello Jhon
 +
        YOUR SALARY IS : 8200
 +
        YOUR CONTRIBUTION TOWARDS PF: 442.8
 +
</pre>
  
::DECLARE
+
==Interacció amb Oracle Server ==
  
::v_weight NUMBER(3):=600;
+
En aquesta pràctica utilitzarà codi PL/SQL per interactuar amb Oracle Server.
  
::v_message VARCHAR2(255):='Product 10012';
+
'''1.-''' Crea un bloc PL/SQL que seleccioni l'identificador de departament superior en la taula departments i l'emmagatzemi en la variable v_max_deptno. Mostra l'identificador de departament superior.
  
::BEGIN
+
:a) Declara una variable v_max_deptno de tipus NUMBER en la secció de declaracions.
  
::::DECLARE
+
:b) Inicia la secció executable amb les paraules BEGIN e inclou una sentència SELECT per recupera el valor màxim de department_id de la taula departments.
  
:::::v_weight NUMBER(3):=1;
+
:c) Mostra v_max_deptno i finalitza el bloc executable.
  
:::::v_message VARCHAR2(255):='Product 11001';
+
:d) Executa i guarda el script lab_04-01_soln.sql. La sortida és la següent:
  
:::::v_new_locn VARCHAR2(50):='Europe';
+
[[Imatge:M2UF3_IOS_5.png |400px|center| Interacció Oracle Server]]
  
:::::BEGIN
+
'''2.-''' Modifica el bloc PL/SQL creat en el pas 1 per afegir un nou departament en la taula departments.
  
:::::::v_weight:= v_weight+1;
+
:a) Carrega el script lab_04_01_soln.sql. Declara dues variables:
 +
::v_dept_name de tipus departments.department_name i v_dept_id de tipo NUMBER
 +
::Assigna 'Eduction' a v_dept_name en la secció de declaracions.
  
:::::::v_new_locn:='Western'|| v_new_locn;
+
:b) Ja has recuperat el número de departament superior actual de la taula departments. Suma-li 10 i assigna-li el resultat a v_dept_id.
  
:::::END;
+
:c) Inclou una sentència INSERT per insertar dades en les columnes department_name, department_id y location_id de la taula departments.
 +
:Utilitza valors en dept_name i dept_id per a department_name i department_id, respectivament, i utilitza NULL per a location_id.
  
:::::v_weight:= v_weight+1;
+
:d) Utilitza l'atribut SQL SQL%ROWCOUNT per mostrar el número de files que es veuen afectades.
  
:::::v_message:=v_message||'is in stock';
+
:e) Executa una sentència SELECT per comprovar si s'ha afegit el nou departament. Acaba el bloc PL/SQL amb "/" e inclou una sentència SELECT en el script.
  
:::::v_new_locn:='Western'|| v_new_locn;
+
:f) Executa i guarda el script com lab_04_02_soln.sql. La sortida d'exemple és la següent:  
  
::END;
+
[[Imatge:M2UF3_IOS_6.png |600px|center| Interacció Oracle Server]]
  
 +
'''3.-''' En el pas 2, defineix location_id en NULL. Crea un bloc PL/SQL que actualitzi location_id a 3000 per al nou departament.
  
:a) El valor de v_weight en el subbloc és:
+
:a) Inicia el bloc executable amb la paraula clau BEGIN. Inclou la sentència UPDATE per definir location_id en 3000 per al nou departament.
  
:b) El valor de v_new_locn en el subbloc és:
+
:b) Acaba el bloc executable en la paraula clau END. Acaba el bloc PL/SQL amb "/" e inclou una sentència SELECT per mostrar el departament que ha actualitzat.
  
:c) El valor de v_weight en el bloc principal és:
+
:c) Inclou una sentència DELETE per suprimir el departament agregat.
  
:d) El valor de v_message en el bloc principal és:
+
:d) Executa i guarda el script com lab_04_03_soln.sql. La sortida de l'exemple és la següent:  
  
:e) El valor de v_new_locn en el bloc principal es
+
[[Imatge:M2UF3_IOS_7.png |600px|center| Interacció Oracle Server]]
  
*'''Exercici 2'''
 
  
SUPOSEM QUE INCLOEM UN SUBBLOC EN UN BLOC TAL COM ES MOSTRA TOT SEGUIT. DETERMINA ELS VALORS EN ELS CASOS SEGÜENTS
+
'''ADDICIONALS'''
  
DECLARE
+
'''EXERCICI 1'''
  
  v_customer    VARCHAR2(50):='Womansport';
+
Per a aquest exercici, es necessita una taula temporal per emmagatzemar els resultats.
  
  v_credit_rating    VARCHAR2(50):='excellent';
+
'''1.-''' Crea la taula descrita a continuació:
  
BEGIN
+
[[Imatge:M2UF3_IOS_1.png |600px|center| Interacció Oracle Server]]
  
      DECLARE
+
<pre>
 +
CREATE TABLE TEMP(
 +
  NUM_STORE NUMBER(7,2),
 +
  CHAR_STORE VARCHAR2(35),
 +
  DATE_STORE DATE);
 +
</pre>
  
            v_customer  NUMBER(7):=201;
+
'''2.-''' Escriu un bloc PL/SQL que realitzi les següents accions:
  
            v_name        VARCHAR2(25):='unisports';
+
:a) Declara dues variables i assigna el següents valors a aquestes variables:  
  
      BEGIN
+
[[Imatge:M2UF3_IOS_2.png |600px|center| Interacció Oracle Server]]
  
      END;
+
:b) Emmagatzema els valors d'aquestes variables en les columnes adients de la tabla TEMP.
  
END;
+
'''3.-''' Verifica els resultats consultant la taula TEMP. La sortida resultant ha de ser com la següent:
  
a) El valor de v_customer en el subbloc és:
+
[[Imatge:M2UF3_IOS_3.png |600px|center| Interacció Oracle Server]]
  
b) El valor de v_name en el subbloc és:
+
'''EXERCICI 2'''
  
c) El valor de v_credit_rating en el subbloc és:
+
En aquest exercici, utilitzaràs dades de la taula employees.
  
d) El valor de v_customer en el bloc principal és:
+
'''1.-''' Escriu un bloc PL/SQL per determinar el nombre d'empleats que treballen en un determinat departament. El bloc PL/SQL haurà de:
  
e) El valor de v_name en el bloc principal es
+
:* Utilitzar una variable de substitució per emmagatzemar un número de departament
 +
:* Imprimir el nombre de persones que treballen en el departament especificat
  
f) El valor de v_credit_rating en el bloc principal és:
+
'''2.-''' Quan s'execute el bloc , apareixerà una finestra de variable de substitució. Introdueix un número de departament vàlid i fes clic en OK. La sortida resultant haurà de tenir un aspecte similar al següent:
  
*'''Exercici 3'''
+
[[Imatge:M2UF3_IOS_4.png |600px|center| Interacció Oracle Server]]
  
CREA I EXECUTA UN BLOC PL/SQL ANOMENAT “T3E3.sql” QUE ACCEPTI DOS NUMEROS PER MITJÀ DE VARIABLES SQL*PLUS. S'HA DE DIVIDIR EL PRIMER NÚMERO PEL SEGON I DESPRÉS AFEGIR EL SEGON AL RESULTAT. EL RESULTAT S'HA D'ESCRIURE EN UNA VARIABLE PL/SQL I S'HA D'IMPRIMIR EN PANTALLA AMB UNA VARIABLE SQL*PLUS.
+
==Escriptura de les estructures de control==
  
*'''Exercici 4'''
+
En aquesta pràctica, crearàs blocs PL/SQL que incorporin bucles i estructures de control condicionals. En aquesta pràctica es comprovarà el teu coneixement de varies sentències IF i construccions L00P.
  
GENEREU UN BLOC PL/SQL QUE CALCULI LA COMPENSACIÓ TOTAL PER UN ANY. EL SALARI ANUAL I EL PERCENTATGE ANUAL DE BONIFICACIONS ES PASARAN AL BLOC PL/SQL A TRAVÉS DE VARIABLES DE SUBSTITUCIÓ SQL*PLUS I L'IMPORT DE BONIFICACIÓ HAURÀ DE SER CONVERTIT EN NUMERO ENTER A DECIMAL (per exemple 15 a 0,15). SI EL SALARI ES NUL ASIGNEU-LI ZERO ABANS DE CALCULAR LA COMPENSACIÓ TOTAL. UTILITZEU LA FUNCIÓ NVL PER A GESTIONAR ELS VALORS NULS.
+
'''1.-''' Executa l'ordre en l'arxiu lab_05_01.sql per crear la taula messages.
 +
Escriu un bloc PL/SQL per afegir números en la taula messages.
  
==T5- Interacció amb el servidor Oracle ==
+
<pre>
 +
  CREATE TABLE messages(
 +
    results VARCHAR2(100));
 +
</pre>
  
EXERCICI 1
+
:a) Afegeix el números del 1 al 10, excloent el 6 i el 8.
 +
:b) Confirma abans del final de bloc.
 +
:c) Executa la sentència SELECT per verificar que el bloc PL/SQL ha funcionat.
  
CREAR UN BLOC PLSQL QUE SELECCIONI EL DEPARTAMENT AMB EL NÚMERO MÉS ALT DE LA TAULA DEPT I IMPRIMEIXI ELS RESULTATS PER PANTALLA.
+
:Resultat: has de veure la següent sortida:
  
EXERCICI 2
+
[[Imatge:M2UF3_EEC_1.png |300px|center| Escriptura de les estructures de control]]
  
CREAR UN BLOC PLSQL QUE INSERTI UN NOU DEPARTAMENT EN LA TAULA DEPT. COM A NOU NUMERO D E DEPARTAMENT UTILITZA EL NÚMERO DE DEPARTAMENT RECUPERAT EN L'EXERCICI ANTERIOR I AFEIGEIX 10 AL NUMERO COM A NOU NÚMERO DE DEPARTAMENT.
+
'''2.-''' Executa el script lab_05_=2.sql. Aquest script crea una taula emp, que és una replica de la taula employees. Modifica la taula emp per agegir una nova columna, stars, de tipus de dades VARCHAR2 i una mida de 50. Crea un bloc PL/SQL que afegeixi un asterisc en la columna stars per cada $1000 del salari de l'empleat. Guarda aquest script com lab_05_02_soln.sql.
  
RECULLI EL NOM DEL NOU DEPARTAMENT PER TECLAT. DEIXA LA UBICACIÓ COM A NULA. AL FINAL MOSTRA EL NOU DEPARTAMENT QUE S'HA CREAT.
+
<pre>
 +
  CREATE TABLE employees2
 +
  AS
 +
  SELECT *
 +
  FROM employees;
  
EXERCICI 3
+
  ALTER TABLE employees2
 +
  ADD (stars VARCHAR2(50));
 +
</pre>
  
Crea un bloc plsql que actualitzi la ubicació d'un departament existent. Guarda el bloc en un arxiu anomenat “t5p3.sql”.
+
:a) En la secció de declaracions del bloc, declara una variable v_empno del tipus employees2.employee_id e inicialitza-la en 176. Declara una variable v_asterisk del tipus emp.stars e inicialitza-la en NULL. Crea una variable v_sal del tipus emp.salary.
  
a) crea un paràmetre per a guardar el número de departament introduit
+
:b) En la secció executable, escriu lògica per afegir un asterisc (*) a la cadena per cada 1000 dòlars del salari. Per exemple, si l'empleat guanya 8000 dòlars, la cadena d'asteriscs ha d'incloure vuit asteriscs. Si l'empleat guanya 12500 dòlars, la cadena d'asteriscs ha d'incloure 13 asteriscs.
  
b) crea un altre paràmetre per a guardar la nova ubicació del departament
+
:c) Actualitza la columna stars per a l'empleat amb la cadena d'asteriscs.
 +
:Confirma abans del final del bloc.
  
c) executa el bloc i actualitza la ubicació d'un departament
+
:d) Mostra la fila de la taula emp per verificar que el bloc PL/SQL s'ha executat correctament.
  
e) comprova que s'ha actualitzat correctament.
+
:e) Executa i guarda el script com a lab_05_02_soln.sql. La sortida és la següent:
  
EXERCICI 4
+
[[Imatge:M2UF3_EEC_2.png |450px|center| Escriptura de les estructures de control]]
  
Crea un bloc pl/sql que suprimeixi el departament creat en l'exercici 2.Guarda el bloc en un arxiu anomenat “t5p4.sql”
+
==Treballar amb tipus de dades compostes==
  
a) crea un paràmetre per a guardar el número de departament introduit
+
'''1.-''' Escriu un bloc PL/SQL per imprimir informació sobre un país determinat.
  
b) imprimeix per pantalla el número de files afectades
+
:a) Declara una variable v_countryid. Assigna-li CA a v_countryid.
  
c) què passa si introduïu un número de departament inexistent?
+
:b) En la secció de declaracions, utilitza l'atribut %ROWTYPE i declara la variable v_countryid_record del tipus countries.
  
d) confirma que el departament s'ha suprimit.
+
:c) En la secció executable, obté tota la informació de la taula countries mitjançant v_countryid. Mostra la informació seleccionada sobre el país. la sortida d'exemple és la següent:
  
==T6- Creació d'estructures de control ==
+
[[Imatge:M2UF3_TDC_1.png |450px|center| Tipus de dades compostes]]
  
EXERCICI 1
+
:d) Executa el bloc PL/SQL pels països amb els identificadors DE, UK i US.
  
crear una nova taula anomenada MESSAGES per emmagatzemar en una columna anomenada RESULTS cadenes de caràcters de longitud màxima 60 caràcters.
+
'''2.-''' Crea un bloc PL/SQL per recuperar els noms d'alguns departaments de la taula departments e imprimir el nom de cada departament en la pantalla, incorporant una matriu associativa. Guarda el script com lab_06_02_soln.sql.
  
a) crea un bloc per insertar els números del 1 al 10 excepte el 6 i el 8
+
:a) Declare una taula INDEX BY dept_table_type del tipus departments.department_name. Declara una variable my_dept_table del tipus dept_table_type per emmagatzema temporalment els noms dels departaments.
  
b) fes un COMMIT al final del bloc
+
:b) Declara dues variables: f_loop_count i v_deptno del tipus NUMBER. Assigna 10 a f_loop_count i 0 a v_deptno.
  
EXERCICI 2
+
:c) Amb un bucle, recupera els noms de 10 departaments i emmagatzema'ls en la matriu associativa. Comença pel department_id 10. Augmentav_deptno en 10 per a cada interacció de bucle. La següent taula mostra els valors department_id per als que cal recuperar department_name.
  
Crear un nou bloc plsql per a calcular l'import de la comissió d'un empleat, aquesta comissió dependrà del sou de l'empleat.
+
[[Imatge:M2UF3_TDC_2.png |450px|center| Tipus de dades compostes]]
  
a) Inserta un nou empleat en la taula EMP que tingui un sou NULL.
+
:d) Si utilitzes un altre bucle, pots recuperar els noms dels departaments de la matriu associativa i mostrar-los.
  
b) Crea una variable per tal d'emmagatzemar el número de l'empleat introduït per teclat.
+
:e) Executa i guarda el script com a lab_06_02_soln.sql. La sortida és la segúent:
  
c) si el sou d'aquest empleat és inferior a 1000$ l'import de la comissió serà un 10% d'aquest sou.
+
[[Imatge:M2UF3_TDC_3.png |200px|center| Tipus de dades compostes]]
  
d) si el sou d'aquest empleat està entre 1000$ i 1500$ l'import de la comissió serà un 15% d'aquest sou.
+
'''3.-''' Modifica el bloc creat en la Pràctica 2 per recuperar tota la informació de cada departament de la taula departments i mostra-la. Utilitza una matriu associativa amb el mètode de taula de registres INDEX BY.
  
e) si el sou d'aquest empleat és superior a 1500$ l'import de la comissió serà un 20% d'aquest sou.
+
:a) Carga el script lab_06_02_soln.sql.
  
f) si el sou d'aquest empleat és NULL la comissió serà un 0.
+
:b) Has declarat que la matriu associativa sigui del tipus departments.department_name. Modifica la declaració de la matriu associativa per emmagatzemar temporalment el número, el nom i la ubicació de tots els departaments. Utilitza l'atribut %ROWTYPE.  
  
g) comprova el funcionament d'aquest bloc per cadadascun dels casos anteriors.
+
:c) Modifica la sentència SELECT per recuperar tota la informació del departament que està en la taula departments i emmagatzemar-la en la matriu associativa.
  
 +
:d) Si utilitzes un altre bucle, pots recuperar la informació dels departaments de la matriu associativa i mostrar-la.
  
EXERCICI 3
+
: La sortida d'exemple és la següent:
  
Modifica l'exercici 1 per afegir al costat del número parell o imparell en funció de si aquest és parell o imparell.
+
[[Imatge:M2UF3_TDC_4.png |550px|center| Tipus de dades compostes]]
  
EXERCICI 4
+
==Us de cursors explícits==
  
Afegiu una nova columna a la taula EMP per afegirs asteriscs “*
+
En aquest tema, resoldràs dos exercicis:
 +
* Primer, utilitzaràs un cursor explícit per processar un nombre de files d'una taula i omplir una altra taula amb els resultats mitjançant un bucle FOR de cursos.
 +
* Desprès, escriuràs un bloc PL/SQL que processi la informació amb dos cursors, incloent un que utilitzi un paràmetre.
  
EXERCICI 5
+
'''1.-''' Crea un bloc PL/SQL que realitzi les següents accions:
  
Crea un bloc PL/SQL que introdueixi en la columna creada anteriorment un asterisc per cada 100$ d'un empleat seleccionat per teclat al introduir el seu número d'empleat. Arrodoniu el sou fins el número enter més proper.
+
:a) En la secció de declaracions, declara e inicialitza una variable anomenada v_deptno de tipus NUMBER. Assigna-li un valor de departament vàlid (consulta els valors de la taula del pas d).
  
==T7- Tipus de dades compostes ==
+
:b) Declara un cursor anomenat c_emp_cursor, que recuperi last_name, salary i mangager_id dels empleats que treballen en el departament especificat en v_deptno.
  
REGISTRES
+
:c) En la secció executable, utilitza el bucle FOR de cursor per realitzar operacions en les dades recuperades. Si el salari de l'empleat es menor que 5000 i el identificador de su superior (manager_id) es 101 0 124, apareix el missatge "<<last_name>> Due for a raise". En cas contrari, apareix el missatge "<<last_name>> Not Due for a raise"
  
TYPE nom_tipus IS RECORD ( campo1 tipo1, campo2 tipo2, campo3 tipo3...)
+
:d) Prova el bloc PL/SQL per als següents cassos:
  
REGISTRO |camp1|camp2|camp3|
+
[[Imatge:M2UF3_UCE_1.png |400px|center| Us de cursors explícits]]
  
--Ejemplo: definimos un tipo de registro PL/SQL para contener un nombre, un oficio y un salario.
+
'''2.-''' A continuació, escriu un bloc PL/SQL que declari i utilitzi dos cursors: un sense paràmetre i un altre amb paràmetre. El primer cursor recupera el número de departament i el nom del departament de la taula departaments per a tots els departaments que tinguin un identificador menor que 100. El segon cursor rep el número de departament com a paràmetre i recupera els detalls dels empleats que treballen en aquest departament i amb un employee_id menor de 120.
  
TYPE tipo_registro_emp (ename VARCHAR2(10), job VARCHAR2(9), sal NUMBER(7,2));
+
:a) Declara un cursor c_dept_cursor per reuperar department_id i department_name per als departaments amb department_id menor que 100. Ordena per department_id.
  
TYPE tipo_registro_emp (ename emp.ename%TYPE, job emp.job%TYPE, sal emp.sal%TYPE);
+
:b) Declara un altre cursor c_emp_curosr que prengui el número de departament com a paràmetre i recuperi les següents dades: last_name, job_id, hire_date i salary dels empleats que treballen en aquest departament, amb employee_id inferior a 120.
  
--Declaramos una varible (reg_emp1) de este tipo:
+
:c) Declara les variables que contenen els valors recuperats de cada cursor. Utilitza l'atribut %TYPE per declara les variables.
  
reg_emp1 tipo_registro_emp;
+
:d) Obre c_dept_cursor, utilitza un bucle simple i recupera els valors en les variables declarades. Mostra el número i el nom del departament. Utilitza l'atribut de cursor adequat per sortir del bucle.
  
--reg_emp1 |ename|job|sal|
+
:e) Obre c_emp_cursor transferint el número de departament actual com a paràmetre. Inicia un altre bucle i recupera els valors de emp_cursor en les variables e imprimeix tots els detalls recuperats en la taula employees.
  
--para hacer referencia o acceder a un campo determinado de un registro se escribe NOMBRE_REGISTRO.NOMBRE_CAMPO
+
:'''Nota'''
 +
:* Comprova si c_emp_cursor ja està obert abans d'obrir-lo.
 +
:* Utilitza l'atribut de cursor adequat per a la condició de sortida.
 +
:* Quan termina el bucle, imprimeix una línia desprès de haver mostrat els detalls de cada departament i tanca c_emp_cursor.
  
--reg_emp1.ename :='Pedro';
+
:f) Finalitza el primer bucle i tanca c_dept_cursor. A continuació, finalitza la secció executable.
  
%ROWTYPE
+
:g) Executa el script. La sortida d'exemple és la següent:
  
– Podemos declarar un registro basándonos en una colección de columnas de una tabla o vista de datos.
+
[[Imatge:M2UF3_UCE_2.png |550px|center| Us de cursors explícits]]
  
registro_emp emp%ROWTYPE;
+
'''3.-''' Crea un bloc PL/SQL que utilitzi un cursor explícit per determinar los n salaris més alts dels empleats.
  
– un cop definit podem omplir-lo amb el resultat d'una select
+
:a) Executa el scrilpt lab_07-2.sql per crear la taula top_salaries per emmagatzemar els salaris dels empleats.
 +
<source lang="SQL">
 +
  CREATE TABLE top_salaries(
 +
    salary NUMBER(7,2));
 +
</source>
 +
:b) En la secció declaracions, declara la variable v_num del tipus NUMBER que contengui el número n, que representa els n salaris més alts de la taula employees. Per exemple, per veure els cinc salaris més alts de la taula, introdueix un 5. Declara un altra variable sal del tipus employees.salary. Declara un cursor, c_emp_cursor, que recuperi els salaris dels empleats en ordre descendent.
 +
: Recorda que els salaris no han de estar duplicats.
  
SELECT *
+
:c) En la secció executable, obre un bucle, recupera els n salaris principals e afegeix-los a la taula top_salaris. Pots utilitzar un bucle simple per realitzar operacions amb les dades. A més a més, utilitza els atributs %ROWCOUNT i %FOUND per a la condició de sortida.
  
INTO registro_emp
+
:'''Nota:''' assegura't d'agregar una condició de sortida per evitar un bucle infinit. 
  
FROM emp
+
:d) Desprès d'afegir-los en la taula top_salaries. mostra les files amb una sentència SELECT. La sortida que es mostra presenta els cinc salaris més alts de la taula employees.
  
WHERE ename='Scott';
+
[[Imatge:M2UF3_UCE_3.png |200px|center| Us de cursors explícits]]
  
el registre definit anteriorment estarà format pels camps que pertanyen a la taula EMP (ename, job, sal, comm)
+
:e) Prova diferents cassos especials, com v_num = 0 o amb un v_num més gran que el nombre d'empleats de la taul employees. Buida la taula top_salaries després de cada prova.
  
És molt útil per a guardar el valor de una fila d'una taula amb la sentència SELECT
+
==Maneig d'excepcions predefinides==
TAULES PL/SQL
 
  
--S'anomenen així als objectes de tipus TABLE
+
'''1.-''' En aquesta pràctica, escriuràs un bloc PL/SQL que apliqui una excepció predefinida per a processar un únic registre a la vegada. El bloc PL/SQL seleccionarà el nom de l'empleat amb un valor de salari determinat.
  
--utilitzen una clau primaria per oferir accés de tipus vector a les files.
+
:a) Executa l'odre de l'arxiu lab_05_01.sql per tornar a crear la taula messages.
  
--poden agumentar dinàmicament de mida (és a dir créixer) doncs no tenen restriccions
+
:b) En la secció de declaracions, declara dues variables: v_ename de tipus employees.last_name i v_emp_sal del tipus employees.salary.
 +
:Inicialitza l'última en 6000.
  
--anem a definir un tipus taula amb una sola columna. Les files s'identifiquen mitjançant enters:
+
:c) En la secció executable, recupera els cognoms dels empleats amb salaris iguals al valor de v_emp_sal. Si el salari introduït torna només una fila, afegeix en la taula messages el nom i el import del salari de l'empleat.
 +
:'''Nota:''' no utilitzis cursors explícits.
  
TYPE tipus_taula_noms IS TABLE OF emp.ename%TYPE
+
:d) Si el salari introduït no torna cap fila, manega l'excepció amb un manegador d'excepcions adequat i afegeix en la taula messages el missatge "No employee with a salary of <salary>".
  
INDEX BY BINARI_INTEGER; --aquest tipus de dades accepta també enters negatius així doncs la indexació no té perquè començar amb 1.
+
:e) Si el salari introduït torna varies files, manega l'excepció amb un manegador d'excepcions adequat i afegeix en la taula messages el missatge "More than one employee with a salary of <salary>".
  
taula_noms tipus_taula_noms; --definim una variable d'aquest tipus.
+
:f) Manega qualsevol altra excepció amb un manegador d'excepcions adequat i afegix en la taula messages el missatge "Some other error ocurred".
  
--l'estructura d'aquest tipus de taula seria
+
:g) Mostra les files de la taula messages per comprovar si el bloc PL/SQL s'ha executat correctament. La sortida és la següent:
  
|clau principal|columna |
+
[[Imatge:M2UF3_MEP_1.png |300px|center| Maneig d'excepcions predefinides]]
  
|1 |Jones |
+
:h) Canvia el valor inicialitzat de v_emp_sal a 2000 i torna a executar. La sortida és la següent:
  
|2 |Smith |
+
[[Imatge:M2UF3_MEP_2.png |300px|center| Maneig d'excepcions predefinides]]
  
|3 |Pepito |
+
'''2.-''' En aquesta pràctica, escriuràs un bloc PL/SQL que declari una excepció per a l'error de Oracle Server ORA-02292 (integrity constraint violated - child record found). El bloc comprovarà l'excepció i mostrarà el missatge d'error.
  
--per referenciar a un registre de la taula concret es fa:
+
:a) En la secció de declaracions, declara una excepció e_childrecord_exists.
 +
:Associa l'excepció declarada al error d'Oracle Server estàndard -02292.
  
taula_noms(4):='Anna';
+
:b) En la secció executable, mostra "Deleting department 40...". Inclou una sentència DELETE per suprimir el departament amb department_id 40.
  
--podem consultar si existeix una fila concreta d'una taula o no, per exemple el registre o fila 6:
+
:c) Inclou una secció d'excepcions per manegar l'excepció e_childrecord_exists i mostra el missatge adequat.
  
taula_noms.EXISTS(6)
+
:La sortida d'exemple és la següent:
  
--si l'expressio anterior retorna TRUE és que existeix aquesta fila si retorna FALSE és que no existeix.
+
[[Imatge:M2UF3_MEP_3.png |500px|center| Maneig d'excepcions predefinides]]
TAULES DE REGISTRES
 
  
--es defineixen com una taula on el tipus de variable són registres.
+
==Creació i us de procediments emmagatzemats==
  
TYPE tipus_taula_dept IS TABLE OF dept%ROWTYPE
+
En aquesta pràctica, modificaràs scripts existents per crear i utilitzar procediments emmagatzemats.
  
INDEX BY BINARI_INTEGER;
+
'''1.-''' A partir de l'exercici 4 del tema2:
 +
<pre>
 +
  DECLARE
 +
    v_today DATE:=SYSDATE;
 +
    v_tomorrow v_today%TYPE;
 +
  BEGIN
 +
    v_tomorrow:=v_today +1;
 +
    DBMS_OUTPUT.PUT_LINE(' Hello World ');
 +
    DBMS_OUTPUT.PUT_LINE('TODAY IS : '|| v_today);
 +
    DBMS_OUTPUT.PUT_LINE('TOMORROW IS : ' || v_tomorrow);
 +
  END;
 +
</pre>
  
taula_dept tipus_taula_dept;
+
:a) Modifica el script per convertir el bloc anònim en un procediment anomenat greet. ('''Indicació:''' elimina també l'ordre SET SERVEROUTPUT ON).
  
--els seus elements es referencien per la fila.columna
+
:b) Executa el script per crear el procediment. La sortida resultant ha de ser com la següent:
  
taula_dept(2).dname:='Ventas';
+
[[Imatge:M2UF3_PE_1.png |250px|center| Maneig d'excepcions predefinides]]
EXERCICI 1
 
  
Crea una nova taula per tal d'emmagatzemar empleats i els seus sous..
+
:c) Guarda aquest script com lab_09_01_soln.sql.
  
CREATE TABLE emp_sal (
+
:d) Prem el botó Clear per netejar l'espai de treball.
  
name varchar2(25),
+
:e) Crea i executa un bloc anònim per cridar al procediment greet.
 +
:('''Indicació:' assegura't d'activa SERVEROUTPUT al principi del bloc).
  
salary number(11,2)
+
:La sortida ha de ser similar a la següent:
  
);
+
[[Imatge:M2UF3_PE_2.png |250px|center| Maneig d'excepcions predefinides]]
  
EXERCICI 2
+
'''2.-''' Modifica el script lab_09_01_soln.sql de la següent forma:
  
Escriu un bloc PL/SQL per recuperar el nom i el sou d'un empleat concret de la taula EMP a partir de la introducció del seu número d'empleat.
+
:a) Elimina el procediment greet amb la següent ordre:
 +
<pre>
 +
    DROP PROCEDURE greet;
 +
</pre>
  
==T8- Cursors explícits ==
+
:b) Modifica el procediment per acceptar un argument de tipus VARCHAR2
 +
:anomena al argument p_name.
  
Cursores Implícitos
+
:c) Imprimeix Hello ''<name>'' (es a  dir, el contingut de l'argument) en lloc de Hello World.
  
Cuando se ejecuta una sentencia DML (son aquellas utilizadas para insertar, borrar, modificar y consultar los datos en una base de datos) un cursor implícito es lanzado. La principal característica es que no se declara con la palabra reservada CURSOR y que se suele utilizar para trabajar con un registro especifico. Los cursores implicitos se utilizan para realizar consultas SELECT...INTO que devuelven un único registro.
+
:d) Guarda el script com lab_09_02_soln.sql.
  
Deben tenerse en cuenta los siguientes puntos cuando se utilizan cursores implicitos:
+
:e) Executa el script per crear el procediment. La sortida resultant ha de ser com la següent:
* Con cada cursor implicito debe existir la palabra clave INTO.
 
* Las variables que reciben los datos devueltos por el cursor tienen que contener el mismo tipo de dato que las columnas de la tabla.
 
* Los cursores implicitos solo pueden devolver una única fila. En caso de que se devuelva más de una fila (o ninguna fila) se producirá una excepcion.
 
  
Cursors explícits
+
[[Imatge:M2UF3_PE_3.png |250px|center| Maneig d'excepcions predefinides]]
  
http://www.devjoker.com/print/Tutorial-PLSQL/39/Tutorial-PLSQL.aspx
+
:f) Crea i executa un bloc anònim per cridar el procediment greet amb un valor de paràmetre. El bloc també ha de produir la sortida.
  
S'utilitzen aquests cursors per a processar individualment les files retornades per una sentència SELECT que retorna varies files (joc de resultats).
+
:La sortida del exemple ha de ser similar a la següent:
  
Amb PL/SQL podem obrir un cursor, processar les files retornades i finalment tancar el cursor.
+
[[Imatge:M2UF3_PE_4.png |250px|center| Maneig d'excepcions predefinides]]
 +
<!--
 +
==T5- Interacció amb el servidor Oracle ==
  
Control dels cursors explícits.
+
*'''Exercici 1'''
  
    Cal declarar el cursor amb la paraula CURSOR (posar-li nom i indicar l'estructura de la consulta de la que guardarà informació)
+
Crea un bloc PL/SQL que seleccioni el departament amb el número més alt de la taula DEPT i mostri els resultats per pantalla.
    OBRIR el cursor amb la sentència OPEN.
 
    Recuperem les dades de cada fila del cursor amb FETCH...INTO i les guardem en variables. Cada recuperació o FETCH apunta a una fila diferent retornada per la consulta. Si no troba mes files tanca el cursor.
 
    La sentència CLOSE allibera el cursor i podem si volem tornar-lo a obrir.  
 
  
CURSOR nom_cursor IS  SELECT ...;
+
*'''Exercici 2'''
  
exemple:
+
Crea bloc PL/SQL que insereixi un nou departament en la taula DEPT, com a número de departament utilitza el recuperat en l'apartat anterior més 10.
  
DECLARE
+
Utilitza una variable de substitució per el nom de departament i deixa la ubicació com a nula. Finalment mostra el nou departament creat.
  CURSOR c1 IS
 
      SELECT * FROM emp WHERE sal >2000;
 
BEGIN
 
  OPEN c1;
 
  FETCH c1 INTO v_emp;
 
  ...
 
  CLOSE c1;
 
END;
 
  
EXERCICI 1
+
*'''Exercici 3'''
  
Cree un bloque plsql que determine los n empleados con sueldos mas altos (suposem que no hi ha dos empleats o mes amb el mateix sou):
+
Crea un bloc plsql que actualitzi la ubicació d'un departament existent. Guarda el bloc en un arxiu anomenat “t5p3.sql”.
  
a) obtenir un numero "n" entrat per teclat per l'usuari amb un paràmetre de substitució.
+
a) crea un paràmetre per a guardar el número de departament introduit
  
b) en un bucle, obtenir els cognoms  i sous d'aquests "n" empleats de la taula EMP
+
b) crea un altre paràmetre per a guardar la nova ubicació del departament
  
c) guarda aquestes dades en la taula TOP_DOGS.
+
c) executa el bloc i actualitza la ubicació d'un departament
  
d) comprova varis casos: n=0 i n>que el número màxim d'empleats.
+
e) comprova que s'ha actualitzat correctament.
  
f) buida la taula TOP_DOGS després de cada prova
+
*'''Exercici 4'''
  
SET SERVEROUTPUT ON;
+
Crea un bloc pl/sql que suprimeixi el departament creat en l'exercici 2.Guarda el bloc en un arxiu anomenat “t5p4.sql”
SET VERIFY OFF;
 
ACCEPT num_emp PROMPT  'Introdueixi el número de empleats amb sou més alt:  '
 
DECLARE
 
  v_numemp number(3) :=&num_emp;   
 
  
  --declarem un cursor que guardarà totes les dades de la taula empleats
+
a) crea un paràmetre per a guardar el número de departament introduit
  CURSOR c_emp IS SELECT * FROM emp ORDER BY sal DESC;
 
  
  --declarem una variable registre capaç de guardar totes les dades de una fila del cursor anterior
+
b) imprimeix per pantalla el número de files afectades
  
  v_emp c_emp%ROWTYPE;
+
c) què passa si introduïu un número de departament inexistent?
 
BEGIN
 
  OPEN c_emp; --obrim el cursor, aquest es posiciona apuntant el primer registre del cursor
 
  FETCH c_emp INTO v_emp; --carreguem el valor de la primera fila en la variablle c_emp, el cursor se situa
 
  
                          --en el seguent registre
+
d) confirma que el departament s'ha suprimit.
   
 
    FOR i IN 1..v_numemp LOOP --usem un bucle per repetir la càrrega tantes vegades com v_numemp
 
        IF c_emp%NOTFOUND THEN EXIT; --condició de sortida del for, si c_emp està buida, el fetch no
 
  
                                    --retorna cap valor
 
        END IF;
 
 
 
        INSERT INTO top_dogs VALUES (v_emp.ename,v_emp.sal); --inserim una nova fila amb el valors carregats
 
        FETCH c_emp INTO v_emp; --fem que el cursor carregui de nou i passi al següent registre
 
    END LOOP;
 
   
 
    CLOSE c_emp;--tanquem el cursor, alliberem memòria
 
  
END;
+
==T6- Creació d'estructures de control ==
  
EXERCICI 2
 
  
Considere el caso de que varios empleados tengan el mismo salario. Al igual que el ejercicio anterior cree un bloque plsql que determine los n empleados con sueldos mas altos pero en este caso si se muestra una persona con el mismo sueldo se tendran que mostrar todos los que tengan este sueldo.
+
*'''Exercici 1'''
  
a) Si el usuario introduce n=2 deben aparecer tres registros (king, ford i scott, estos últimos tienen el mismo sueldo.
+
crear una nova taula anomenada MESSAGES per emmagatzemar en una columna anomenada RESULTS cadenes de caràcters de longitud màxima 60 caràcters.
  
b) Si el usuario introduce n=3 deben aparecer 4 registros (king, ford i scott i jones)
+
a) crea un bloc per insertar els números del 1 al 10 excepte el 6 i el 8
  
c) vacía todas la filas de la tabla TOP_DOGS antes de probar  el ejercicio.
+
b) fes un COMMIT al final del bloc
  
  
SET SERVEROUTPUT ON;
+
*'''Exercici 2'''
SET VERIFY OFF;
 
ACCEPT num_emp PROMPT  'Introdueixi el número de empleats amb sou més alt:  '
 
DECLARE
 
  v_numemp number(3) :=&num_emp;   
 
  v_sal emp.sal%TYPE :=-1;
 
  
  CURSOR c_emp IS SELECT * FROM emp ORDER BY NVL(sal,0) DESC;
+
Crear un nou bloc plsql per a calcular l'import de la comissió d'un empleat, aquesta comissió dependrà del sou de l'empleat.
 
BEGIN
 
  DELETE FROM top_dogs; --buidem la taula top_dogs
 
  FOR v_emp IN c_emp LOOP
 
        DBMS_OUTPUT.PUT_LINE(v_numemp);   
 
        EXIT WHEN  (c_emp%ROWCOUNT > v_numemp AND v_sal<>v_emp.sal) OR (v_numemp=0);
 
        INSERT INTO top_dogs VALUES (v_emp.ename,v_emp.sal);   
 
          IF (v_sal=v_emp.sal) THEN v_numemp:=v_numemp+1;
 
            ELSE  v_sal:=v_emp.sal;
 
          END IF;
 
    END LOOP;
 
END;
 
/
 
  
--------------------------------------------------------------------------------------------------
+
a) Inserta un nou empleat en la taula EMP que tingui un sou NULL.
  
--Versión 2 de este ejericio
+
b) Crea una variable per tal d'emmagatzemar el número de l'empleat introduït per teclat.
  
ACCEPT p_num PROMPT 'introduce el máximo numero de sueldos distintos: '
+
c) si el sou d'aquest empleat és inferior a 1000$ l'import de la comissió serà un 10% d'aquest sou.
  
DECLARE
+
d) si el sou d'aquest empleat està entre 1000$ i 1500$ l'import de la comissió serà un 15% d'aquest sou.
  
  v_num  NUMBER(3):= &p_num;
+
e) si el sou d'aquest empleat és superior a 1500$ l'import de la comissió serà un 20% d'aquest sou.
  
  v_ename  emp.ename%TYPE;
+
f) si el sou d'aquest empleat és NULL la comissió serà un 0.
  
  v_salari_actual  emp.sal%TYPE;
+
g) comprova el funcionament d'aquest bloc per cadadascun dels casos anteriors.
  
  v_ultimo_salario  emp.sal%TYPE:= 1;
+
*'''Exercici 3'''
  
  CURSOR  emp_cursor IS  SELECT ename, sal FROM emp WHERE sal IS NOT NULL ORDER BY sal DESC;
+
Modifica l'exercici 1 per afegir al costat del número parell o imparell en funció de si aquest és parell o imparell.
  
BEGIN
+
*'''Exercici 4'''
  
  open emp_cursor;
+
Afegiu una nova columna a la taula EMP per afegirs asteriscs “*”
  
  FETCH emp_cursor INTO v_ename, v_salari_actual;
+
*'''Exercici 5'''
  
  WHILE (emp_cursor%ROWCOUNT <= v_num OR v_salari_actual=v_ultimo_salario) AND emp_cursor%FOUND LOOP
+
Crea un bloc PL/SQL que introdueixi en la columna creada anteriorment un asterisc per cada 100$ d'un empleat seleccionat per teclat al introduir el seu número d'empleat. Arrodoniu el sou fins el número enter més proper.
  
              INSERT INTO top_dogs(name, salary)
+
==T7- Tipus de dades compostes ==
  
              VALUES (v_ename,v_salari_actual);
+
Crea una nova taula per emmagatzemar salaris i sous.
  
              v_ultimo_salario:=v_salari_actual;
+
<pre>
 +
SQL> CREATE TABLE top_dogs
 +
  2  (name    VARCHAR2(25),
 +
  3  salary  NUMBER(11,2));
 +
</pre>
  
              FETCH emp_cursor INTO v_ename, v_salari_actual;
+
*'''Exercici 1'''
  
  END LOOP;
+
Escriu un bloc PL/SQL que inicialitzi les 3 primeres posicions d'una taula de registres (nom, salari) i a continuació actualitzi la taula top_dogs amb aquesta informació.
  
  close emp_cursor;
+
*'''Exercici 2'''
  
COMMIT;
+
Escriu un bloc PL/SQL per recuperar el nom i el sou d'un empleat concret de la taula EMP a partir de la introducció del seu número d'empleat.
  
END;
+
a. Declara dues taules: rev_salary_table per emmagatzemar el percentatge de augment de salari. i emp_table per guardar l'empleat tractat.
  
==T9- Conceptes avançats de cursors explplícits ==
+
b. Inicialitza les posicions, corresponents als números de departament de la taula dept, amb els diferents percentatges:
  
EXERCICI 1
+
      10 --  2; 20 -- 3; 30 -- 4; 40 -- 3 ...
  
Ejecute una consulta pera recuperar todos los departamentos y empleados de cada departamento. Inserte los resultados en la tabla MESSAGES.
+
c. Guarda el nom i salari en la taula emp_table en la posició corresponent al departament de l'empleat.
  
Utilice un cursor per a recuperar el número de departament i transfieralo a un cursor para recuperar los empleados de este departamento.
+
d. Finalment guarda en la taula top_dogs el nom de l'empleat i el seu salari revisat en funció del departament al que pertany.
  
EXERCICI 2
+
==T8- Cursors explícits ==
  
Modifica l'exercici p4q5 per incorporar la funcionalitat FOR UPDATE i WHERE CURRENT OF al procesament de cursors.
+
*'''Exercici 1'''
  
==T10- Gestió d'excepcions ==
+
Previ: buida la taula TOP_DOGS.
  
EJERCICIO 1
+
Crea un bloc pl/sql que determini els n empleats amb sous més alts (suposeu que no hi ha dos empleats o més amb el mateix sou):
  
Escribe una bloque PLSQL para seleccionar el nombre del empleado con un valor concreto de sueldo preguntado al usuario.
+
a. obtenir un numero "n" entrat per teclat per l'usuari amb un paràmetre de substitució.
  
a) si el sueldo devulve más de una fila gestione la excepción con un manejador de excepciones apropiado i inserta dentro de la tabla MESSAGES "Más de un empleado con el mismo sueldo"
+
b. en un bucle, obtenir els cognoms  i sous d'aquests "n" empleats de la taula EMP
  
b) si el sueldo no devuelve ninguna fila, escribir "ningun empleado con este salario"
+
c. guarda aquestes dades en la taula TOP_DOGS.
  
c) si el sueldo sólo devuelve una sola fila, insertar el nombre del empleado y el sueldo.
+
d. Suposa que no hi ha dos empleats amb al mateix sou.
  
d) si se produce cualquier otra excepción introducir "se produjo algún otro error"
+
e. comprova varis casos: n=0 i n més gran que el número màxim d'empleats.
 +
*'''Exercici 2'''
  
e) pruebe el bloque con los distintos casos y verifica que funciona correctamente.
+
Considera el cas de que varis empleats tinguin el mateix salari. Al igual que l'exercici anterior crea un bloc pl/sql que determini els n empleats amb sous més alts, però en aquest cas si se cal mostrar totes les persones que tinguin un mateix sou.
  
SET VERIFY OFF;
+
a. Si l'usuari introdueix n=2 han d'aparèixer tres registres (king, ford i scott, aquest últims tenen el mateix sou.
ACCEPT salari PROMPT  'Introdueixi el salari a buscar:  '
 
DECLARE
 
  
  v_ename emp.ename%TYPE;
+
b. Si l'usuari introdueix n=3 han d'aparèixer 4 registres (king, ford i scott i jones).
  
  v_sal emp.sal%TYPE :=&salari;
+
c. Buida totes les files de la taula TOP_DOGS abans de prova l'exercici.
  
BEGIN
+
==T9- Conceptes avançats de cursors explícits ==
  SELECT ename*  INTO v_ename FROM emp WHERE emp.sal=v_sal;
 
  INSERT INTO messages (results) VALUES(v_ename||' - '||v_sal);
 
  
EXCEPTION
 
    WHEN NO_DATA_FOUND THEN 
 
              INSERT INTO missatges VALUES('No hi ha cap empleat amb aquest salari introduït' || TO_CHAR(v_sal));
 
    WHEN TOO_MANY_ROWS THEN 
 
              INSERT INTO missatges VALUES('Hi ha més d'un empleat amb aquest sou de ' || TO_CHAR(v_sal));
 
    WHEN OTHERS THEN 
 
              INSERT INTO missatges VALUES('algún altre error sha produit')     
 
END;
 
/
 
  
select  * from missatges;
+
*'''Exercici 1'''
  
 +
Ejecute una consulta pera recuperar todos los departamentos y empleados de cada departamento. Inserte los resultados en la tabla MESSAGES.
  
EJERCICIO 2
+
Utilice un cursor per a recuperar el número de departament i transfieralo a un cursor para recuperar los empleados de este departamento.
  
Modifica el ejercicio 3 del tema 4 p4q3.sql para añadir un manejador de excepciones.
+
<pre>
 +
  RESULTS
 +
  -------------------------
 +
  KING - Department 10
 +
  CLARK - Department 10
 +
  MILLER - Department 10
 +
  JONES - Department 20
 +
  FORD - Department 20
 +
  SMITH - Department 20
 +
  SCOTT - Department 20
 +
  ADAMS - Department 20
 +
  BLAKE - Department 30
 +
  MARTIN - Department 30
 +
  ALLEN - Department 30
 +
  TURNER - Department 30
 +
  JAMES - Departmens 30
 +
  WARD - Department 30
 +
  14 rows selected.
 +
</pre>
 +
*'''Exercici 2'''
  
a) escriba un manejador para que comunique un mensaje al usuario diciendo que el departamento especificado no existe si este es el caso.
+
Modifica l'exercici p6q5 per incorporar la funcionalitat FOR UPDATE i WHERE CURRENT OF al procesament de cursors.
  
b) prueba con un departamento que no exista
+
<pre>
 +
  EMPNO  SAL  START
 +
  -----  ----  ----------------
 +
  8000 
 +
  7900  950  **********
 +
  7844  1500  ***************
 +
</pre>
  
SET SERVEROUTPUT ON;
+
==T10- Gestió d'excepcions ==
  
  ACCEPT lloc_dept PROMPT  'Introdueixi la localitat del departament:  '
+
*'''Exercici 1'''
  ACCEPT num_dept PROMPT  'Introdueixi el nombre del departament:  '
 
  
DECLARE
+
Escriu un bloc PLSQL per seleccionar el nom de l'empleat amb un valor concret de sou. Cal que demanis el sou a l'usuari mitjançant un paràmetre SQL*PLUS.  
    v_llocdept dept.loc%TYPE :='&lloc_dept';
 
    v_numdept DEPT.DEPTNO%type:= &num_dept;
 
    v_dept dept%ROWTYPE;
 
  
BEGIN
+
a. si el sou introduït torna més d'una fila, gestiona l'excepció amb un manegador d'excepcions apropiat i afegeix a la taula MESSAGES el texte: "Més d'un empleat amb un sou de <sou>".
      SELECT * INTO v_dept FROM dept WHERE v_dept.deptno=v_numdept;
 
      UPDATE dept
 
      SET loc=v_llocdept
 
      WHERE deptno=v_numdept;
 
 
EXCEPTION
 
    WHEN NO_DATA_FOUND THEN 
 
        DBMS_OUTPUT.PUT_LINE('NO EXISTEIX EL DEPARTAMENT');
 
END;
 
/
 
 
  
EJERCICIO 3
+
b. si el sou introduït no torna cap fila, gestiona l'excepció amb un manegador d'excepcions apropiat i afegeix a la taula MESSAGES el texte: "Cap empleat amb un sou <sou>".
  
Escriu un bloc PLSQL que imprimeixi els noms dels empleats que guanyen 100$ mes o menys que un valor introduït per teclat.
+
c. si el sou introduït només torna una fila, afegeix a la taula MESSAGES el nom del empleat i l'import del sou.
  
a) si no hi ha cap empleat dins aquest rang mostra un missatge al usuari indicant l'error que s'ha produït
+
d. Si es produeix qualsevol altra excepció, gestiona-la amb un manegador d'excepcions apropiat i afegeix a la taula MESSAGES el texte: "S'ha produït algun altre error".
  
b) si hi ha un o més empleats dins aquests rang el missatge hauria d'indicar quants empleats hi ha en aquest rang de sous.
+
e. Prova el bloc amb diferents cassos i assegurat de que funciona correctament.
  
c) gestiona qualsevol altra excepció indicant que s'ha produit un altre tipus d'error.
+
*'''Exercici 2'''
  
+
Modifica l'exercici 3 del tema 5 t5p3.sql per afegir manegadors d'excepcions definida per l'usuari.
SET SERVEROUTPUT ON;
 
  
ACCEPT sal_emp PROMPT  'Introdueixi el salari:  '
+
a. escriu un manegador per a que comuniqui missatge a l'usuari dient que el departament especificat no existeix, si és el cas.
 
DECLARE
 
    v_sal emp.sal%TYPE :=&sal_emp;
 
    v_nemp number(4);
 
    e_ningu EXCEPTION;
 
BEGIN
 
    SELECT COUNT(*)  INTO v_nemp 
 
    FROM emp
 
    WHERE sal BETWEEN (v_sal-100) and (v_sal+100);
 
 
    IF v_nemp = 0 THEN RAISE e_ningu;
 
    ELSE DBMS_OUTPUT.PUT_LINE(v_nemp||' '||'COBREN AQUEST SALARI');
 
    END IF;
 
 
EXCEPTION
 
    WHEN e_ningu THEN 
 
        DBMS_OUTPUT.PUT_LINE('Ningú no té aquest salari');
 
END;
 
/
 
  
 +
b. fes la comprovació amb un departament que no existeixi.
  
 +
*'''Exercici 3'''
  
 +
Escriu un bloc PLSQL que imprimeixi els nombre d'empleats que guanyen 100$ més o  menys que un valor introduït per teclat.
  
-------------------------------------------------------------------------------------------------------------
+
a. si no hi ha cap empleat dins aquest rang mostra un missatge al usuari indicant l'error que s'ha produït.
  
-------------------------------ALTRA VERSIÓ EXERICI 1--------------------------------------------
+
b. si hi ha un o més empleats dins aquests rang el missatge hauria d'indicar quants empleats hi ha en aquest rang de sous.
  
SET VERIFY OFF;
+
c. gestiona qualsevol altra excepció indicant que s'ha produït un altre tipus d'error.
 
ACCEPT salari PROMPT  'Introdueixi el salari a buscar:  '
 
 
DECLARE
 
 
v_sal emp.sal%TYPE :=&salari;   
 
 
v_emp emp%ROWTYPE;
 
 
ERROR2 VARCHAR2(25);
 
 
BEGIN
 
      RAISE_APPLICATION_ERROR(-20000,'hola');
 
      SELECT * INTO v_emp FROM emp WHERE emp.sal=v_sal;
 
      DBMS_OUTPUT.PUT_LINE(v_emp.ename);   
 
   
 
EXCEPTION
 
    WHEN NO_DATA_FOUND THEN 
 
        INSERT INTO missatges VALUES('Ningú no compleix la condixció');
 
        DBMS_OUTPUT.PUT_LINE('Ningú no compleix la condixció');
 
    WHEN TOO_MANY_ROWS THEN 
 
        INSERT INTO missatges VALUES('N''hi ha més d''un');
 
        DBMS_OUTPUT.PUT_LINE('N''hi ha més d''un');
 
    WHEN OTHERS THEN 
 
        ERROR2:=SQLERRM;
 
        INSERT INTO missatges VALUES(ERROR2);
 
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
 
END;
 
/
 
  
 
==T11- Creació de procediments ==
 
==T11- Creació de procediments ==
  
EJERCICIO 1
+
*'''Exercici 1'''
  
 
a) Crea un procediment anomenat ADD_PROD per insertar un producte nou a la taula PRODUCT
 
a) Crea un procediment anomenat ADD_PROD per insertar un producte nou a la taula PRODUCT
  
b) Compilar el codi, cridar al procediment i consultar la taula PRODUCT per veure els resultats.
+
b) Compila el codi, cridar al procediment i consulta la taula PRODUCT per veure els resultats.
  
 
c) Crida de nou el procediment, passat l'identificador de producte 100860 ¿què passa i per què?
 
c) Crida de nou el procediment, passat l'identificador de producte 100860 ¿què passa i per què?
  
EJERCICIO 2
+
*'''Exercici 2'''
  
a) Crea un procediment anomenat UPD_PROD per actualitzar la descripció d'un producte de la taula PRODUCT. Incloure la manipulació d'excepcions necessaris.
+
a) Crea un procediment anomenat UPD_PROD per actualitzar la descripció d'un producte de la taula PRODUCT. Inclou la manipulació d'excepcions necessària.
  
b) Compilar el codi, cridar al procediment i consultar la taula PRODUCT per veure els resultats.
+
b) Compila el codi, crida al procediment i consulta la taula PRODUCT per veure els resultats. Comprova el control d'excepcions, intentant modificar un producte que no existeix.
  
EJERCICIO 3
+
*'''Exercici 3'''
  
a) Crea un procediment anomenat DEL_PROD per esborrar un producte de la taula PRODUCT. Incloure la manipulació d'excepcions necessaris.
+
a) Crea un procediment anomenat DEL_PROD per esborrar un producte de la taula PRODUCT. Inclou la manipulació d'excepcions necessària.
  
b) Compilar el codi, cridar al procediment i consultar la taula PRODUCT per veure els resultats. Verifica també el control d'excepcions intentant esborrar un producte que no existeix.
+
b) Compila el codi, crida al procediment i consulta la taula PRODUCT per veure els resultats. Verifica també el control d'excepcions intentant esborrar un producte que no existeix.
  
EJERCICIO 4
+
*'''Exercici 4'''
  
a) Crea un procediment per consultar la taula EMP per tal que recuperi el salari i l'ofici d'un empleat (emp_no).
+
a) Crea un procediment que a partir del codi d'un empleat (empno), recuperi de la taula EMP el seu salari i ofici.
  
b) Compilar el codi, cridar al procediment i  visualitzar el salari i l'ofici per l'empleat 7839·
+
b) Compila el codi, crida al procediment i  visualitza el salari i l'ofici per a l'empleat amb codi 7839·
  
c) crida una altra vegada al procediment passant ara el número d'un empleat 9898. Què passa? Per què?
+
c) Crida una altra vegada al procediment passant ara el número de empleat 9898. Què passa? Per què?
  
 
==T12- Creació de funcions ==
 
==T12- Creació de funcions ==
  
EXERCICI 1
+
*'''Exercici 1'''
  
a) Crea una funció anomenada Q_PROD que retorni la descripció d'un producte a una variable host (una varible global).
+
a) Crea una funció anomenada Q_PROD que retorni la descripció d'un producte a una variable host (una variable global).
  
b) Compila el codi, crida a la funció i tot seguit consulta la variable host per a verure el resultat.
+
b) Compila el codi, crida a la funció i tot seguit consulta la variable host per a veure el resultat.
  
EXERCICI 2
+
*'''Exercici 2'''
  
a) Crea una funció emmagatzemada ANNUAL_COMP que ens retorni el salari anual quan li passem el salari mensual i la comissió d'un empleat. La funció ha de retornar el salari anual definit per (sal*12)+comm
+
a) Crea una funció emmagatzemada ANNUAL_COMP que ens retorni el salari anual quan li passem el salari mensual i la comissió d'un empleat. La funció ha de retornar el salari anual definit per (sal*12)+comm. Assegura't que la funció controla valors NULL.
  
 
b) Utilitza la funció anterior en una sentència SELECT contra la taula EMP.
 
b) Utilitza la funció anterior en una sentència SELECT contra la taula EMP.
  
EXERCICI 3
+
*'''Exercici 3'''
  
Crea un procediment NEW_EMP, per insertar un empleat nou dins de la taula EMP. El procediment haurà de contenir una crida a la funció VALID_DEPTNO per comprovar si existeix en la taula del departament especificat per al nou empleat.
+
Crea un procediment, NEW_EMP, per inssertar un empleat nou dins de la taula EMP. El procediment haurà de contenir una crida a la funció VALID_DEPTNO per comprovar si existeix en la taula del departament especificat per al nou empleat.
  
a) Crear una funció VALID_DEPNO per tal que ens validi un número de departament especificat. La funció ha de retornar un BOOLEÀ.
+
a) Crea la funció VALID_DEPNO per tal que ens validi un número de departament especificat. La funció ha de retornar un BOOLEÀ.
  
b) Crear un procediment NEW_EMP per afegir un nou empleat a la taula EMP. S'hauria d'afegir un nou registre a la taula EMP si la funció retorna TRUE. Si retorna FALSE, el procediment hauria d'alertar a l'usuari amb un missatge.
+
b) Crea el procediment NEW_EMP per afegir un nou empleat a la taula EMP. S'hauria d'afegir un nou registre a la taula EMP si la funció retorna TRUE. Si retorna FALSE, el procediment hauria d'alertar a l'usuari amb un missatge apropiat.
 +
Defineix valors DEFAULT per a la majoria d'arguments. La comissió per defecte és 0, el salari per defecte és 1000, el número de departament per defecte és 30, l'ofici per defecte és SALESMAN i el cap per defecte és 7839.
  
c) Comprovar el procediment NEW_EMP afegint un nou nom d'empleat al departament 99 (HARRIS). Deixar la resta de paràmetres amb el seus valors per defecte. Quin és el resultat?
+
c) Comprova el procediment NEW_EMP afegint un nou empleat (7777) al departament 99 (HARRIS). Deixar la resta de paràmetres amb el seus valors per defecte. Quin és el resultat?
 
 
d) Comprovar el nou procediment NEW_EMP afegint un nou nom d'empleat al departament 30 (HARRIS). Deixar la resta de paràmetres amb els seus valors per defecte. Quin és el resultat?
 
  
 +
d) Comprovar el nou procediment NEW_EMP afegint un nou empleat (8888) al departament 30 (MIKEL). Deixar la resta de paràmetres amb els seus valors per defecte. Quin és el resultat?
  
 
==T13- Creació de paquets ==
 
==T13- Creació de paquets ==
  
EXERCICI 1
+
*'''Exercici 1'''
  
a) Crea la especificació i el cos d'un paquet anomenat PROD_PACK que contingui els procediments creats ADD_PROD, UPD_PROD i DEL_PROD i la funció Q_PROD.
+
Crea la especificació i el cos d'un paquet anomenat PROD_PACK que contingui els procediments creats ADD_PROD, UPD_PROD i DEL_PROD i la funció Q_PROD.
  
b) Fer tots els programes públics. (considereu si seguiu necessitant els procediments i funcions empaquetats com objectes independents)
+
a) Fer tots els programes públics. (considereu si seguiu necessitant els procediments i funcions empaquetats com objectes independents)
  
c) Crida al procediment DEL_PROD
+
b) Crida al procediment DEL_PROD.
  
d)Consulta la taula PRODUCT per veure el resultat.
+
c) Consulta la taula PRODUCT per veure el resultat.
  
EXERCICI 2
+
*'''Exercici 2'''
  
a) Crea i l'especificació i el cos d'un paquet anomenat EMP_PACK que contingui els procediment NEW_EMP com a construcció pública i la funció VALID_DEPTNO com a construcció privada.
+
a) Crea l'especificació i el cos d'un paquet anomenat EMP_PACK que contingui els procediment NEW_EMP com a construcció pública i la funció VALID_DEPTNO com a construcció privada.
  
 
b) Crida al procediment NEW_EMP utiitzant el valor 99 com a número de departament.
 
b) Crida al procediment NEW_EMP utiitzant el valor 99 com a número de departament.
  
c)Crida al procediment NEW_EMP utiitzant el valor 30 com a número de departament.
+
c) Crida al procediment NEW_EMP utiitzant el valor 30 com a número de departament.
  
EXERCICI 3
+
*'''Exercici 3'''
  
a) Crea un paquet anomenat CHK_PACK que contingui els procediments  CHK_HIREDATE i CHK_DEPT_MGR. Fes-los com a programes públics.
+
Crea un paquet anomenat CHK_PACK que contingui els procediments  CHK_HIREDATE i CHK_DEPT_MGR. Fes-los com a programes públics.
  
a) El primer procediment comprova si la data de contracctació d'oun empleat està dins el rang següent (sysdate-50 years, sysdate+3months)
+
a) El procediment CHK_HIREDATE comprova si la data de contractació d'un empleat està dins el rang següent (sysdate-50 years, sysdate+3months)
  
 
Nota: si la data és invalida ha d'aparèixer un missatge d'error indicant perquè no s'accepta aquesta data. Utilitza una constant per a referir-se al límit de 50 anys. Si el valor de la data de contractació és un valor nul, aquesta serà considerada una data de contractació invalida.
 
Nota: si la data és invalida ha d'aparèixer un missatge d'error indicant perquè no s'accepta aquesta data. Utilitza una constant per a referir-se al límit de 50 anys. Si el valor de la data de contractació és un valor nul, aquesta serà considerada una data de contractació invalida.
  
b) El segon procediment comprova si la combinació del departament i del director per a un empleat donat. Això significa que el número de director facilitat ha de ser igual al número de director que supervisa el departament de l'empleat.
+
b) El procediment CHK_DEPT_MGR comprova la combinació del departament i del director per a un empleat donat. Això significa que el número de director facilitat ha de ser igual al número de director que supervisa el departament de l'empleat.
  
 
Nota: Si la combinació número/director és invalida ha d'aparèixer un missatge d'error. Assegura't de controlar el cas en el que no hi ha director pel departament.
 
Nota: Si la combinació número/director és invalida ha d'aparèixer un missatge d'error. Assegura't de controlar el cas en el que no hi ha director pel departament.
Línia 738: Línia 779:
 
c) Prova el procediment CHK_HIREDATE mitjançant la comanda  següent:
 
c) Prova el procediment CHK_HIREDATE mitjançant la comanda  següent:
  
     SQL> execute chk_pack.chk_hiredate('01-JAN-47')
+
     SQL> execute chk_pack.chk_hiredate('01-ENE-47')
  
 
d) Prova el procediment CHK_HIREDATE mitjançant la comanda  següent:
 
d) Prova el procediment CHK_HIREDATE mitjançant la comanda  següent:
Línia 746: Línia 787:
 
e) Prova el procediment CHK_HIREDATE mitjançant la comanda  següent:
 
e) Prova el procediment CHK_HIREDATE mitjançant la comanda  següent:
  
     SQL> execute chk_pack.chk_hiredate('01-JAN-98')
+
     SQL> execute chk_pack.chk_hiredate('01-ENE-98')
 +
 
 +
==T15- Creació de triggers ==
 +
 
 +
*'''Exercici 1'''
 +
 
 +
Les operacions DML sobre taules només es permetran en hores de feina, es a dir, entre les 8:45 del matí i las 5:50 de la tarda; de dilluns a divendres.
 +
 
 +
a) crea un procediment emmagatzemat anomenat SECURE_DML que mostri un missatge d'error, en cas de no complir la regla anterior, com "Només es pot modificar dades en horari de feina".
 +
 
 +
*'''Exercici 2'''
 +
 
 +
Crea un trigger en la taula PRODUCT que cridi al procediment anterior.
 +
 
 +
a) prova el procediment modificant la franja horària proposada anteriorment e intentant afegir un nou registre en la taula PRODUCT. Després de la comprovació restableix els valors originals.
 +
 
 +
*'''Exercici 3'''
 +
 
 +
La comissió d'un venedor canviaria amb qualsevol comanda nova o canvis en les comandes existents. La seva comissió s'emmagatzema en la columna COMM de la taula EMP. En la taula CUSTOMER s'assigna un venedor a un client particular.
 +
 
 +
a) crea un procediment que actualitzarà la comissió del venedor. Utilitzaràs paràmetres per enviar l'identificador del client, el total antic de la comanda i el total nou de la comanda, des del trigger que es fa la crida. El procediment necessitarà localitzar el codi del empleat en la taula CUSTOMER i actualitzar el registre del venedor en la taula EMP, afegint una nova comissió al valor existent (percentatge de comissió el 5% del total de la comanda).
 +
 
 +
b) Crea un trigger en la taula ORD que cridi al procediment, passant els paràmetres necessaris.
 +
 
 +
c) Modifica la comanda 601 per assignar-li un total de 3$. Comprova que la comissión de WARD s'ha incrementat en 0.03. La comissió original era de 500.
 +
 
 +
*'''Exercici 4'''
 +
 
 +
A las taules EMP i DEPT se'ls aplica una sèrie de regles de negoci.
  
 +
Implementa les regles de negoci mitjançant triggers.
  
==T15- Creació de triggers ==
+
Reglas de negocio:
  
EJERCICIO 1
+
1. La taula EMP hauria de contenir exactament un PRESIDENT. Comproveu la resposta.
  
Las operaciones DML sobre las tablas sólo se permitirán en horas de trabajo, es decir, entre las 8:45 de la mañana  i las 5:50 de la tarde; de lunes a viernes.
+
2. Els salaris només podran augmentar-se, no disminuir-se.
  
a) crea un procedimiento almacenado llamado SECURE_DML que muestre un mensaje de error, en caso de no cumplir la regla especificada anteriormente como "Sólo puede modificar datos durante horas oficiales de trabajo".
+
3. Si un departament es trasllada a una altra ubicació, cada empleat d'aquest departament tindrà automàticament un increment de salari del 2%.
 +
-->
  
EJERCICIO 2
+
==Solucions exercicis ==
  
Crea un trigger en la tabla PRODUCT que llame al procedimiento anterior.
+
'''Conceptes fonamentals'''
  
a) prueba el procedimiento modificando la franja horaria propuesta anteriormente e intentando insertar un nuevo registro en la tabla PRODUCT. Después de la comprovación reestablezca los valores originales.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T1 | Introducció PL/SQL]]
  
EJERCICIO 3
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T2 | Declaració de variables]]
  
La comisión de un vendedor cambiaría con cualquier pedido nuevo o por cambios en los pedidos existentes. Su comisión se almacena en la columna COMM de la tabla EMP. En la tabla CUSTOMER se asigna un vendedor a un cliente particular.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T3 | Escriptura de sentencies executables]]
  
a) crear un procedimiento que actualizará la comisión del vendedor. Usaremos parámetros para enviar el identificador del cliente, el total antiguo del pedido i el total nuevo, desde el trigger que hace la llamada. El procedimiento necesitará localizar el número del empleado en la tabla CUSTOMER i actualizar el registro del vendedor en la tabla EMP, añadiendo una nueva comisión al valor existente (porcentaje de comisión el 5% del total del pedido)
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T4 | Interacció amb Oracle Server]]
  
b) Crear un trigger en la tabla ORD el cual llamará al procedimiento, pasando los parámetros necesarios.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T5 | Estructures de control]]
  
c) Modificar el pedido 601 para asignarle un total de 3$. Verficar que la comisión de WARD se ha incrementado en 0.03. La comisión original era de 500.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T6 | Tipus de dades compostes]]
  
EJERCICIO 4
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T7 | Ús de cursors explícits]]
  
A las tablas EMP i DEPT se les aplica una serie de reglas de negocio.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T8 | Manegament d'excepcions]]
  
a) decidir cómo implementar cada regla por medio de constraints i triggers. ¿qué restricciones o triggers se necesitarán i qué problemas podemos esperar?
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T9 | Creació i us de procediments emmagatzemats]]
  
b) implemente las reglas de negocio mediante triggers.
+
<!----><!---->
  
reglas de negocio:
+
<!--
 +
==Solucions exercicis ==
 +
BD SCOTT
  
1. Los vendedores siempre deberían recibir una comisión. Los empleados que no son vendedores nunca deberían recibir una comisión. (implemente esta regla con una constraint)
 
2. La tabla EMP debería contener exactamente un PRESIDENT.
 
  
3. Los salarios solo podrían aumentarse, no disminuirse.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T4 | Sentencies executables]]
  
4. Si un departamento se traslada a otra parte, cada empleado de dicho departamento tendrá automáticamente un incremento de salario del 2%.
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T5 | Interacció amb el servidor Oracle]]
 +
 +
-->
 +
<!--
 +
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T10 | Gestió d'excepcions]]
 +
 
 +
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T11 | Creació de procediments]]
 +
 
 +
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T12 | Creació de funcions]]
  
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T3 | Solucions declaració de variables]]
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T13 | Creació de paquets]]
  
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T4 | Solucions sentencies executables]]
+
:*[[M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T15 | Creació de triggers]]
 +
-->

Revisió de 17:13, 12 març 2024

Introducció a PL/SQL

1.- Quin bloc PL/SQL dels següents s'executa correctament?

     a) BEGIN
        END;
     b) DECLARE
          v_amount INTEGER(10);
        END;
     c) DECLARE
        BEGIN
        END;
     d) DECLARE
          v_amount INTEGER(10);
        BEGIN
          DBMS_OUTPUT.PUT_LINE(v_amount);
        END;

2.- Crea i executa un bloc anònim simple, la seva sortida ha de ser “Hello World”. Executa i guarda aquest sript com lab_01_02_soln.sql.

Declaració de variables

1.- Especifica identificadors vàlids i no vàlids:

a) today
b) last_name
c) today’s_date
d) Number_of_days_in_February_this_year
e) Isleap$year
f) #number
g) NUMBER#
h) number1to7

2.- Identifica les declaracions e inicialitzacions de variables vàlides i no vàlides:

a) number_of_copies           PLS_INTEGER;
b) PRINTER_NAME               constant VARCHAR2(10);
c) deliver_to                        VARCHAR2(10):=Johnson;
d) by_when                          DATE:= CURRENT_DATE+1;

3.- Examina el següent bloc anònim i selecciona la frase que serà certa de entre les següents:

  DECLARE
    v_fname VARCHAR2(20);
    v_lname VARCHAR2(15) DEFAULT 'fernandez';
  BEGIN
    DBMS_OUTPUT.PUT_LINE(v_fname ||' ' ||v_lname);
  END;
a) El bloc s'executa correctament i s'imprimeix “fernandez”.
b) El bloc produeix un error perquè s'utilitza la variable fname sense inicialitzar-se.
c) El bloc s'executa correctament i s'imprimeix "null fernandez".
d) El bloc produeix un error perquè no es pot utilitzar la paraula clau DEFAULT per inicialitzar una variable de tipus VARCHAR2.
e) El bloc produeix un error perquè no es declara la variable v_fname.

4.- Modifica un bloc anònim existent i guarda'l com un nou script.

a) Obre el script lab_01_02_soln.sql, creat en la Pràctica 1.
b) En aquest bloc PL/SQL, declara las següents variables:
1. v_today del tipus DATE. Inicialitza today amb SYSDATE.
2. v_tomorrow del tipus today. Utilitza l'atribut %TYPE per declarar aquesta variable.
c) En la secció executable:
1. Inicialitza la variable v_tomorrow amb una expressió, que calculi la data de demà (agrega un 1 al valor de today)
2. Imprimeix el valor de v_today i tomorrow desprès de imprimir “Hello World”
d) Guarda el script com a lab_02_04_soln.sql i executa'l.
La sortida de l'exemple és com la següent (els valors de v_today i v_tomorrow seran diferents per reflexar la data actual d'avui i la de demà):
         anonymous bloc completed
           Hello World
         TODAY IS : 07-MAR-16
         TOMORROW IS: 08-MAR-16

5.- Edita el script lab_02_04_soln.sql.

a) Agrega codi per crear dues variables d'enllaç: b_basic_percent i b_pf_percent. Ambdues de tipus NUMBER.
b) En la secció executable del bloc PL/SQL, assigna els valors 45 i 12 a b_basic_percent i b_pf_percent, respectivament.
c) Termina el bloc PL/SQL amb “/” i mostra el valor de las variables d'enllaç amb l'ordre PRINT.
d) Executa i guarda el script com a lab_02_05_soln.sql. La sortida de exemple és la següent:
­
         anonymous bloc completed
         b_basic_percent
         --
         45

         b_pf_percent
         --
         12


Escriptura de Sentències Executables

En aquesta pràctica, examinaràs i escriuràs sentències executables.

Escriptura de Sentències Executables

1.- Avalua el bloc PL/SQL anterior i determina el tipus de dada i el valor de cada una de les següents variables, segons les regles dels àmbits:

a) Valor de v_weight en la posició 1:
b) Valor de v_new_locn en la posició 1:
c) Valor de v_weight en la posició 2:
d) Valor de v_message en la posició 2:
e) Valor de v_new_locn en la posició 2:
Escriptura de Sentències Executables

2.- En el bloc anterior, determina el valor i el tipus de dada en cada un dels següents cassos:

a) Valor de v_customer en el bloc anidat:
b) Valor de v_name en el bloc anidat:
c) Valor de v_credit_rating en el bloc anidat:
d) Valor de v_customer en el bloc principal:
e) Valor de v_name en el bloc principal:
f) Valor de v_credit_rating en el bloc principal:

3.- Utilitza la mateixa sessió que vas utilitzar per executar les pràctiques de la lliçó anomenada "Declaració de Variables PL/SQL". Se has obert una nova sessió, executa lab_02_05_soln.sql. A continuació, edita lab_02_05_soln.sql de la siguent forma:

a) Amb la sintaxis de comentaris d'una sola línia, comenta les línies que creen les variables d'enllaç i activa SERVEROUTPUT.
b) Amb els comentaris de varies línies, comenta en la secció executable les línies que assignen valors a les variables d'enllaç.
c) En la secció de declaracions:
1. Declara e inicialitza dues variables temporals per substituir les variables d'enllaç comentades.
2. Declara dues variables addicionals: v_fname de tipus VARCHAR2 i

tamany 15, i v_emp_sal del tipus NUMBER i tamany 10.

d) Inclou la següent sentència SQL en la secció executable:
     SELECT first_name, salary INTO v_fname, v_emp_sal
     FROM employees WHERE employee_id=110;
e) Canvia la línia que imprimeix “Hello World” per a que imprimeixi “Hello” i el nom. A continuació, comenta les línies que mostren les dates i les que imprimeixen les variables d'enllaç.
f) Calcula l'aportació de l'empleat al fons de previsió (PF). PF és el 12% del salari bàsic, i el salari bàsic es el 45% del salari. Utilitza les variables locals per fer el càlcul. Intenta utilitza només una expressió per calcular el valor de PF. Imprimeix el salari de l'empleat i la seva aportació a PF.
g) Executa i guarda el script com lab_03_03_soln.sql. La sortida de l'exemple és la següent:
         anonymous bloc completed
           Hello Jhon
         YOUR SALARY IS : 8200
         YOUR CONTRIBUTION TOWARDS PF: 442.8

Interacció amb Oracle Server

En aquesta pràctica utilitzarà codi PL/SQL per interactuar amb Oracle Server.

1.- Crea un bloc PL/SQL que seleccioni l'identificador de departament superior en la taula departments i l'emmagatzemi en la variable v_max_deptno. Mostra l'identificador de departament superior.

a) Declara una variable v_max_deptno de tipus NUMBER en la secció de declaracions.
b) Inicia la secció executable amb les paraules BEGIN e inclou una sentència SELECT per recupera el valor màxim de department_id de la taula departments.
c) Mostra v_max_deptno i finalitza el bloc executable.
d) Executa i guarda el script lab_04-01_soln.sql. La sortida és la següent:
Interacció Oracle Server

2.- Modifica el bloc PL/SQL creat en el pas 1 per afegir un nou departament en la taula departments.

a) Carrega el script lab_04_01_soln.sql. Declara dues variables:
v_dept_name de tipus departments.department_name i v_dept_id de tipo NUMBER
Assigna 'Eduction' a v_dept_name en la secció de declaracions.
b) Ja has recuperat el número de departament superior actual de la taula departments. Suma-li 10 i assigna-li el resultat a v_dept_id.
c) Inclou una sentència INSERT per insertar dades en les columnes department_name, department_id y location_id de la taula departments.
Utilitza valors en dept_name i dept_id per a department_name i department_id, respectivament, i utilitza NULL per a location_id.
d) Utilitza l'atribut SQL SQL%ROWCOUNT per mostrar el número de files que es veuen afectades.
e) Executa una sentència SELECT per comprovar si s'ha afegit el nou departament. Acaba el bloc PL/SQL amb "/" e inclou una sentència SELECT en el script.
f) Executa i guarda el script com lab_04_02_soln.sql. La sortida d'exemple és la següent:
Interacció Oracle Server

3.- En el pas 2, defineix location_id en NULL. Crea un bloc PL/SQL que actualitzi location_id a 3000 per al nou departament.

a) Inicia el bloc executable amb la paraula clau BEGIN. Inclou la sentència UPDATE per definir location_id en 3000 per al nou departament.
b) Acaba el bloc executable en la paraula clau END. Acaba el bloc PL/SQL amb "/" e inclou una sentència SELECT per mostrar el departament que ha actualitzat.
c) Inclou una sentència DELETE per suprimir el departament agregat.
d) Executa i guarda el script com lab_04_03_soln.sql. La sortida de l'exemple és la següent:
Interacció Oracle Server


ADDICIONALS

EXERCICI 1

Per a aquest exercici, es necessita una taula temporal per emmagatzemar els resultats.

1.- Crea la taula descrita a continuació:

Interacció Oracle Server
CREATE TABLE TEMP(
  NUM_STORE NUMBER(7,2),
  CHAR_STORE VARCHAR2(35),
  DATE_STORE DATE);

2.- Escriu un bloc PL/SQL que realitzi les següents accions:

a) Declara dues variables i assigna el següents valors a aquestes variables:
Interacció Oracle Server
b) Emmagatzema els valors d'aquestes variables en les columnes adients de la tabla TEMP.

3.- Verifica els resultats consultant la taula TEMP. La sortida resultant ha de ser com la següent:

Interacció Oracle Server

EXERCICI 2

En aquest exercici, utilitzaràs dades de la taula employees.

1.- Escriu un bloc PL/SQL per determinar el nombre d'empleats que treballen en un determinat departament. El bloc PL/SQL haurà de:

  • Utilitzar una variable de substitució per emmagatzemar un número de departament
  • Imprimir el nombre de persones que treballen en el departament especificat

2.- Quan s'execute el bloc , apareixerà una finestra de variable de substitució. Introdueix un número de departament vàlid i fes clic en OK. La sortida resultant haurà de tenir un aspecte similar al següent:

Interacció Oracle Server

Escriptura de les estructures de control

En aquesta pràctica, crearàs blocs PL/SQL que incorporin bucles i estructures de control condicionals. En aquesta pràctica es comprovarà el teu coneixement de varies sentències IF i construccions L00P.

1.- Executa l'ordre en l'arxiu lab_05_01.sql per crear la taula messages. Escriu un bloc PL/SQL per afegir números en la taula messages.

  CREATE TABLE messages(
    results VARCHAR2(100));
a) Afegeix el números del 1 al 10, excloent el 6 i el 8.
b) Confirma abans del final de bloc.
c) Executa la sentència SELECT per verificar que el bloc PL/SQL ha funcionat.
Resultat: has de veure la següent sortida:
Escriptura de les estructures de control

2.- Executa el script lab_05_=2.sql. Aquest script crea una taula emp, que és una replica de la taula employees. Modifica la taula emp per agegir una nova columna, stars, de tipus de dades VARCHAR2 i una mida de 50. Crea un bloc PL/SQL que afegeixi un asterisc en la columna stars per cada $1000 del salari de l'empleat. Guarda aquest script com lab_05_02_soln.sql.

   CREATE TABLE employees2
   AS
   SELECT *
   FROM employees;

   ALTER TABLE employees2 
   ADD (stars VARCHAR2(50));
a) En la secció de declaracions del bloc, declara una variable v_empno del tipus employees2.employee_id e inicialitza-la en 176. Declara una variable v_asterisk del tipus emp.stars e inicialitza-la en NULL. Crea una variable v_sal del tipus emp.salary.
b) En la secció executable, escriu lògica per afegir un asterisc (*) a la cadena per cada 1000 dòlars del salari. Per exemple, si l'empleat guanya 8000 dòlars, la cadena d'asteriscs ha d'incloure vuit asteriscs. Si l'empleat guanya 12500 dòlars, la cadena d'asteriscs ha d'incloure 13 asteriscs.
c) Actualitza la columna stars per a l'empleat amb la cadena d'asteriscs.
Confirma abans del final del bloc.
d) Mostra la fila de la taula emp per verificar que el bloc PL/SQL s'ha executat correctament.
e) Executa i guarda el script com a lab_05_02_soln.sql. La sortida és la següent:
Escriptura de les estructures de control

Treballar amb tipus de dades compostes

1.- Escriu un bloc PL/SQL per imprimir informació sobre un país determinat.

a) Declara una variable v_countryid. Assigna-li CA a v_countryid.
b) En la secció de declaracions, utilitza l'atribut %ROWTYPE i declara la variable v_countryid_record del tipus countries.
c) En la secció executable, obté tota la informació de la taula countries mitjançant v_countryid. Mostra la informació seleccionada sobre el país. la sortida d'exemple és la següent:
Tipus de dades compostes
d) Executa el bloc PL/SQL pels països amb els identificadors DE, UK i US.

2.- Crea un bloc PL/SQL per recuperar els noms d'alguns departaments de la taula departments e imprimir el nom de cada departament en la pantalla, incorporant una matriu associativa. Guarda el script com lab_06_02_soln.sql.

a) Declare una taula INDEX BY dept_table_type del tipus departments.department_name. Declara una variable my_dept_table del tipus dept_table_type per emmagatzema temporalment els noms dels departaments.
b) Declara dues variables: f_loop_count i v_deptno del tipus NUMBER. Assigna 10 a f_loop_count i 0 a v_deptno.
c) Amb un bucle, recupera els noms de 10 departaments i emmagatzema'ls en la matriu associativa. Comença pel department_id 10. Augmentav_deptno en 10 per a cada interacció de bucle. La següent taula mostra els valors department_id per als que cal recuperar department_name.
Tipus de dades compostes
d) Si utilitzes un altre bucle, pots recuperar els noms dels departaments de la matriu associativa i mostrar-los.
e) Executa i guarda el script com a lab_06_02_soln.sql. La sortida és la segúent:
Tipus de dades compostes

3.- Modifica el bloc creat en la Pràctica 2 per recuperar tota la informació de cada departament de la taula departments i mostra-la. Utilitza una matriu associativa amb el mètode de taula de registres INDEX BY.

a) Carga el script lab_06_02_soln.sql.
b) Has declarat que la matriu associativa sigui del tipus departments.department_name. Modifica la declaració de la matriu associativa per emmagatzemar temporalment el número, el nom i la ubicació de tots els departaments. Utilitza l'atribut %ROWTYPE.
c) Modifica la sentència SELECT per recuperar tota la informació del departament que està en la taula departments i emmagatzemar-la en la matriu associativa.
d) Si utilitzes un altre bucle, pots recuperar la informació dels departaments de la matriu associativa i mostrar-la.
La sortida d'exemple és la següent:
Tipus de dades compostes

Us de cursors explícits

En aquest tema, resoldràs dos exercicis:

  • Primer, utilitzaràs un cursor explícit per processar un nombre de files d'una taula i omplir una altra taula amb els resultats mitjançant un bucle FOR de cursos.
  • Desprès, escriuràs un bloc PL/SQL que processi la informació amb dos cursors, incloent un que utilitzi un paràmetre.

1.- Crea un bloc PL/SQL que realitzi les següents accions:

a) En la secció de declaracions, declara e inicialitza una variable anomenada v_deptno de tipus NUMBER. Assigna-li un valor de departament vàlid (consulta els valors de la taula del pas d).
b) Declara un cursor anomenat c_emp_cursor, que recuperi last_name, salary i mangager_id dels empleats que treballen en el departament especificat en v_deptno.
c) En la secció executable, utilitza el bucle FOR de cursor per realitzar operacions en les dades recuperades. Si el salari de l'empleat es menor que 5000 i el identificador de su superior (manager_id) es 101 0 124, apareix el missatge "<<last_name>> Due for a raise". En cas contrari, apareix el missatge "<<last_name>> Not Due for a raise"
d) Prova el bloc PL/SQL per als següents cassos:
Us de cursors explícits

2.- A continuació, escriu un bloc PL/SQL que declari i utilitzi dos cursors: un sense paràmetre i un altre amb paràmetre. El primer cursor recupera el número de departament i el nom del departament de la taula departaments per a tots els departaments que tinguin un identificador menor que 100. El segon cursor rep el número de departament com a paràmetre i recupera els detalls dels empleats que treballen en aquest departament i amb un employee_id menor de 120.

a) Declara un cursor c_dept_cursor per reuperar department_id i department_name per als departaments amb department_id menor que 100. Ordena per department_id.
b) Declara un altre cursor c_emp_curosr que prengui el número de departament com a paràmetre i recuperi les següents dades: last_name, job_id, hire_date i salary dels empleats que treballen en aquest departament, amb employee_id inferior a 120.
c) Declara les variables que contenen els valors recuperats de cada cursor. Utilitza l'atribut %TYPE per declara les variables.
d) Obre c_dept_cursor, utilitza un bucle simple i recupera els valors en les variables declarades. Mostra el número i el nom del departament. Utilitza l'atribut de cursor adequat per sortir del bucle.
e) Obre c_emp_cursor transferint el número de departament actual com a paràmetre. Inicia un altre bucle i recupera els valors de emp_cursor en les variables e imprimeix tots els detalls recuperats en la taula employees.
Nota
  • Comprova si c_emp_cursor ja està obert abans d'obrir-lo.
  • Utilitza l'atribut de cursor adequat per a la condició de sortida.
  • Quan termina el bucle, imprimeix una línia desprès de haver mostrat els detalls de cada departament i tanca c_emp_cursor.
f) Finalitza el primer bucle i tanca c_dept_cursor. A continuació, finalitza la secció executable.
g) Executa el script. La sortida d'exemple és la següent:
Us de cursors explícits

3.- Crea un bloc PL/SQL que utilitzi un cursor explícit per determinar los n salaris més alts dels empleats.

a) Executa el scrilpt lab_07-2.sql per crear la taula top_salaries per emmagatzemar els salaris dels empleats.
CREATE TABLE top_salaries(
    salary NUMBER(7,2));
b) En la secció declaracions, declara la variable v_num del tipus NUMBER que contengui el número n, que representa els n salaris més alts de la taula employees. Per exemple, per veure els cinc salaris més alts de la taula, introdueix un 5. Declara un altra variable sal del tipus employees.salary. Declara un cursor, c_emp_cursor, que recuperi els salaris dels empleats en ordre descendent.
Recorda que els salaris no han de estar duplicats.
c) En la secció executable, obre un bucle, recupera els n salaris principals e afegeix-los a la taula top_salaris. Pots utilitzar un bucle simple per realitzar operacions amb les dades. A més a més, utilitza els atributs %ROWCOUNT i %FOUND per a la condició de sortida.
Nota: assegura't d'agregar una condició de sortida per evitar un bucle infinit.
d) Desprès d'afegir-los en la taula top_salaries. mostra les files amb una sentència SELECT. La sortida que es mostra presenta els cinc salaris més alts de la taula employees.
Us de cursors explícits
e) Prova diferents cassos especials, com v_num = 0 o amb un v_num més gran que el nombre d'empleats de la taul employees. Buida la taula top_salaries després de cada prova.

Maneig d'excepcions predefinides

1.- En aquesta pràctica, escriuràs un bloc PL/SQL que apliqui una excepció predefinida per a processar un únic registre a la vegada. El bloc PL/SQL seleccionarà el nom de l'empleat amb un valor de salari determinat.

a) Executa l'odre de l'arxiu lab_05_01.sql per tornar a crear la taula messages.
b) En la secció de declaracions, declara dues variables: v_ename de tipus employees.last_name i v_emp_sal del tipus employees.salary.
Inicialitza l'última en 6000.
c) En la secció executable, recupera els cognoms dels empleats amb salaris iguals al valor de v_emp_sal. Si el salari introduït torna només una fila, afegeix en la taula messages el nom i el import del salari de l'empleat.
Nota: no utilitzis cursors explícits.
d) Si el salari introduït no torna cap fila, manega l'excepció amb un manegador d'excepcions adequat i afegeix en la taula messages el missatge "No employee with a salary of <salary>".
e) Si el salari introduït torna varies files, manega l'excepció amb un manegador d'excepcions adequat i afegeix en la taula messages el missatge "More than one employee with a salary of <salary>".
f) Manega qualsevol altra excepció amb un manegador d'excepcions adequat i afegix en la taula messages el missatge "Some other error ocurred".
g) Mostra les files de la taula messages per comprovar si el bloc PL/SQL s'ha executat correctament. La sortida és la següent:
Maneig d'excepcions predefinides
h) Canvia el valor inicialitzat de v_emp_sal a 2000 i torna a executar. La sortida és la següent:
Maneig d'excepcions predefinides

2.- En aquesta pràctica, escriuràs un bloc PL/SQL que declari una excepció per a l'error de Oracle Server ORA-02292 (integrity constraint violated - child record found). El bloc comprovarà l'excepció i mostrarà el missatge d'error.

a) En la secció de declaracions, declara una excepció e_childrecord_exists.
Associa l'excepció declarada al error d'Oracle Server estàndard -02292.
b) En la secció executable, mostra "Deleting department 40...". Inclou una sentència DELETE per suprimir el departament amb department_id 40.
c) Inclou una secció d'excepcions per manegar l'excepció e_childrecord_exists i mostra el missatge adequat.
La sortida d'exemple és la següent:
Maneig d'excepcions predefinides

Creació i us de procediments emmagatzemats

En aquesta pràctica, modificaràs scripts existents per crear i utilitzar procediments emmagatzemats.

1.- A partir de l'exercici 4 del tema2:

   DECLARE
     v_today DATE:=SYSDATE;
     v_tomorrow v_today%TYPE;
   BEGIN
     v_tomorrow:=v_today +1;
     DBMS_OUTPUT.PUT_LINE(' Hello World ');
     DBMS_OUTPUT.PUT_LINE('TODAY IS : '|| v_today);
     DBMS_OUTPUT.PUT_LINE('TOMORROW IS : ' || v_tomorrow);
   END;
a) Modifica el script per convertir el bloc anònim en un procediment anomenat greet. (Indicació: elimina també l'ordre SET SERVEROUTPUT ON).
b) Executa el script per crear el procediment. La sortida resultant ha de ser com la següent:
Maneig d'excepcions predefinides
c) Guarda aquest script com lab_09_01_soln.sql.
d) Prem el botó Clear per netejar l'espai de treball.
e) Crea i executa un bloc anònim per cridar al procediment greet.
(Indicació:' assegura't d'activa SERVEROUTPUT al principi del bloc).
La sortida ha de ser similar a la següent:
Maneig d'excepcions predefinides

2.- Modifica el script lab_09_01_soln.sql de la següent forma:

a) Elimina el procediment greet amb la següent ordre:
     DROP PROCEDURE greet;
b) Modifica el procediment per acceptar un argument de tipus VARCHAR2
anomena al argument p_name.
c) Imprimeix Hello <name> (es a dir, el contingut de l'argument) en lloc de Hello World.
d) Guarda el script com lab_09_02_soln.sql.
e) Executa el script per crear el procediment. La sortida resultant ha de ser com la següent:
Maneig d'excepcions predefinides
f) Crea i executa un bloc anònim per cridar el procediment greet amb un valor de paràmetre. El bloc també ha de produir la sortida.
La sortida del exemple ha de ser similar a la següent:
Maneig d'excepcions predefinides

Solucions exercicis

Conceptes fonamentals