Documente Academic
Documente Profesional
Documente Cultură
Bertrand LIAUDET
Exercice 1 : prise en main du PL-SQL RENDU Chaque exercice impose un rendu. Tous les rendus sont mis dans un fichier texte unique. Ce fichier sappellera obligatoirement : Nom du fichier : NOM-Prenom-PLSQL-01.txt Ce fichier est envoy par mail. Lobjet du mail est obligatoirement : Objet du mail : NOM-Prenom-PLSQL-01.txt 00-Installation de lenvironnement Dans lenvironnement dj cr, ouvrez une session SQL-PLUS en tant que TPSELECT. Vous pouvez utiliser le dossier fournit avec le tlchargement. Rappel : pour crer lutilisateur TPSELECT : CREATE USER tpselect IDENTIFIED BY "tpselect"; GRANT CONNECT, RESOURCE TO tpselect; 1. Afficher le nom de lutilisateur est connect.
Show user
RENDU : le code de rponse aux trois questions. 01-bonjour.sql - Affichage 1. Excuter le script 01-bonjour.sql dans la calculette slq_plus. Corriger les erreurs. 2. Modifier le script pour que laffichage se fasse (serveroutput) 3. Modifier le script pour que le temps dexcution saffiche (timing)
4. Mettez jour le fichier login.sql pour que laffichage se fasse chaque fois que vous vous connecterez. RENDU : le fichier login.sql. Explication de la correction apporte.
Fichier login.sql set linesize 120 set pagesize 500 set timing on set serveroutput on Fichier corrig begin dbms_output.put_line ('Bonjour '|| user || '. Nous sommes le ' || to_char(sysdate, 'dd month yyyy') || '. Vous tes bien l''INSIA !'); end; / il y avait deux problmes dapostrophe
02-variable.sql empdept.sql - & 1. 2. 3. 4. 5. Excutez le script empdept.sql dans la calculette slq_plus. Listez les tables de votre catalogue. Excutez le script 02-variable.sql Excutez une deuxime fois le script 02-variable.sql. Que constatez-vous ? Regardez le code et explicitez toute la syntaxe.
03- moySalDept.sql (empdept) - Fonction 1. Excutez le script 04-moySalDept.sql dans la calculette slq_plus. 2. affichez le code pris en compte : Col text format A80 Select line, text From user_source where name = MOYSALDEPT; 3. Explicitez toute la syntaxe. 4. Testez la fonction en utilisant la pseudo-table DUAL 5. Ecrire une requte avec une variable de substitution qui permette dafficher, pour un dpartement dont on saisira la valeur lexcution de la requte, tous les employs qui gagnent plus que la moyenne des salaires du dpartement. RENDU : les questions 4 et 5
4 : select moySalDept(10) from dual; 5 : select * from emp where deptno=&v_deptno and sal > moySalDept(deptno);
04- AffEmpDept.sql (empdept) - Procdure 1. Excutez le script 03-AffEmpDept.sql dans la calculette slq_plus. 2. Affichez les erreurs repres par le systme Show errors; 3. affichez le code pris en compte. Col text format A80 Select line, text From user_source where name = AFFEMPDEPT; 4. Corrigez la ou les erreurs. Explicitez toute la syntaxe. 5. Appelez la procdures pour toutes les valeurs de dpartement. 6. Mettez jour la procdure pour quelle prenne correctement en compte le cas o le numro de dpartement nexiste pas. RENDU : le code de la procdure corrige avec un appel de cette procdure
create or replace procedure affEmpDept(v_deptno EMP.DEPTNO%TYPE) is v_nbemp number; vide number; Begin select count(*) into vide from dept where deptno=v_deptno; if vide=0 then dbms_output.put_line('Le dept '|| v_deptno || ' n''existe pas'); return; end if; select count(*) into v_nbemp from emp where deptno=v_deptno; dbms_output.put_line('Le dpartement '||v_deptno|| ' contient '||v_nbemp||' employe(s) : ') ; dbms_output.put_line('.'); for i_emp in ( select empno, ename, sal, deptno from emp where deptno = v_deptno ) loop dbms_output.put_line('. Employ n'|| i_emp.EMPNO||' : '||i_emp.ENAME||
INSIA - BASES DE DONNES SIGL 2 PL-SQL-ORACLE-TP 1 - page 3/8 - Bertrand LIAUDET
', salaire = '||i_emp.SAL); -- il manquait une ' avant ||i_emp.ENAME|| end loop; dbms_output.put_line('.'); end; / call affEmpDept(10); call affEmpDept(1); REMARQUE : pour le 5 Soit on fait call affEmpDept(10); call affEmpDept(20); call affEmpDept(30); call affEmpDept(40); soit on fait : create or replace procedure tousLesAffEmpDept is Begin for i_dept in ( select deptno from dept ) loop -- dbms_output.put_line('. affEmpDept(i_dept.DEPTNO) ; end loop; end; / call tousLesAffEmpDept() ; A noter que les appels de procdure dans la procdure se font sans call
05- Curseurs 1. Excutez les scripts 05-lesEmployes_01.sql et 05-lesEmployes_02.sql dans la calculette slq_plus. 2. Comparez les rsultats. 3. Comparez les codes des deux scripts. 4. Transformer les deux scripts en procdure, la procdure prenant le numro du dpartement en paramtre et laffichage se limitant aux employs du dpartement trait. Affichez un message spcial si le dpartement est vide. RENDU : Explication de la diffrence entre les deux scripts. Code de la procdure de lexo 4.
Le premier code utilise un curseur explicite : cursor ... is select Le deuxime code utilise un curseur implicite : for .. in
create or replace procedure affEmpDept(v_deptno EMP.DEPTNO%TYPE) is v_nbemp number; i number; BEGIN i:=0; for v_emp in ( select empno, ename, job, sal+nvl(comm, 0) as saltot from emp where deptno=v_deptno order by saltot desc ) loop dbms_output.put_line(v_emp.empno||'-'||v_emp.ename ||'-'||v_emp.job||'-'||v_emp.saltot); i:=i+1; end loop; if i=0 then dbms_output.put_line('le dpartement est vide'); end if; dbms_output.put_line('Nb lignes traites : '|| i); END; / call affEmpDept(10); call affEmpDept(1);
06- SQL dynamique - exercice 1. Ecrire une procdure (ou un bloc) qui permet dafficher, pour chaque table de la BD, le nom de la table, le nombre de tuples, et les 5 premiers tuples de chaque table. RENDU : Code de la procdure.
create or replace procedure consulteTable is TYPE NameList IS TABLE OF user_tab_columns.COLUMN_NAME%TYPE; i number; nbColonnes number; nbTuples number; v_columname NameList; v_sqlDynamique varchar2(200); v_sqlDynamique2 varchar2(1000); v_sqlDynamique3 varchar2(1000); v_attribut varchar2(30); v_valeur varchar2(200); Begin i:=0;
-- on boucle sur toutes les tables for v_table in (select table_name FROM user_tables) loop dbms_output.put_line('----------------------------------------------------------------------'); -- dbms_output.put_line('Table '||v_table.table_name); -- rcupration du nombre de tuples de la table v_sqlDynamique3:='select count(*) from '|| v_table.table_name; -- dbms_output.put_line(v_sqlDynamique3); EXECUTE IMMEDIATE v_sqlDynamique3 into nbTuples; -- rcupration des attributs de la table v_sqlDynamique:='SELECT COLUMN_NAME FROM user_tab_columns table_name='''|| v_table.table_name||''''; -- dbms_output.put_line(v_sqlDynamique); EXECUTE IMMEDIATE v_sqlDynamique BULK COLLECT INTO v_columname;
WHERE
-- on peut aussi crire : notez le 1 et le USING -- v_sqlDynamique:='SELECT COLUMN_NAME FROM user_tab_columns WHERE table_name=:1'; -- EXECUTE IMMEDIATE v_sqlDynamique BULK COLLECT INTO v_columname USING v_table.table_name; -- Cration de la requte dans v_sqlDynamique2 v_sqlDynamique2:='BEGIN for v_attributs in (select '; nbColonnes:=0; FOR j IN 1..v_columname.count LOOP -- dbms_output.put_line('Attribut : '||v_columname(j)); v_attribut:=v_columname(j); v_sqlDynamique2:=v_sqlDynamique2||v_attribut||','; nbColonnes:=nbColonnes+1; END LOOP; v_sqlDynamique2:=v_sqlDynamique2||' '''' as nb FROM '||v_table.table_name||' WHERE rownum<6) LOOP dbms_output.put_line('; FOR j IN 1..v_columname.count LOOP v_attribut:=v_columname(j); v_sqlDynamique2:=v_sqlDynamique2||'v_attributs.'||v_attribut||'||'' ''|| '; END LOOP; v_sqlDynamique2:=v_sqlDynamique2||'v_attributs.nb); END loop; END;'; -- fin de la cration de la requte dans v_sqlDynamique2 dbms_output.put_line('La Table '||v_table.table_name||' nbColonnes ||' colonnes et '|| nbTuples ||' tuples : '); dbms_output.put_line('-'); EXECUTE IMMEDIATE v_sqlDynamique2; possde '||
i:=i+1; dbms_output.put_line('-'); end loop; -- dbms_output.put_line('Nb lignes traites : '|| i); end; /
call consulteTable();
07- Trigger 1. Excutez le script 07-trigBefore.txt dans la calculette slq_plus. 2. Affichez le code pris en compte (mme principe que pour les procdures et les fonctions)
Col text format A80 Select line, text From user_source where name = TBU_SAL_EMP;
3. Affichez les erreurs : trouvez dans les vues publiques la table correspondante et listez son contenu. On pourra se contenter des attributs : name, line, position, text. On fera en sorte que laffichage soit lisible.
Col text format A80 col name format a15 Select name, line, position, text from user_errors;
5. Vrifiez que le trigger fonctionne correctement : augmenter un salaire de 10%. Affichez les salaires.
update emp set sal = 5500 where empno = 7839;
6. Ouvrez une deuxime session SQL-PLUS pour lutilisateur TPSELECT. Regardez ltat des salaires. Que constatez-vous ? Regardez ltat des variables denvironnement (SHOW ALL). Comment expliquez-vous la situation ? Dans la premire session : validez la transaction. Vrifiez sa prise en compte dans la deuxime session.
Dans la deuxime session, on constate que la modification napparat pas : Select * from emp where where empno = 7839; Le SHOW ALL montre le AUTOCOMMIT OFF Pour valider la transaction dans la premire session : Commit ; Dans la 2me session : on constate que la modification a t prise en compte : Select * from emp where where empno = 7839;