<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ca">
	<id>http://wiki.joanillo.org/index.php?action=history&amp;feed=atom&amp;title=DAI-C8-EC%3A_Exercicis_de_classe</id>
	<title>DAI-C8-EC: Exercicis de classe - Historial de revisió</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.joanillo.org/index.php?action=history&amp;feed=atom&amp;title=DAI-C8-EC%3A_Exercicis_de_classe"/>
	<link rel="alternate" type="text/html" href="http://wiki.joanillo.org/index.php?title=DAI-C8-EC:_Exercicis_de_classe&amp;action=history"/>
	<updated>2026-08-30T10:22:46Z</updated>
	<subtitle>Historial de revisió per a aquesta pàgina del wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>http://wiki.joanillo.org/index.php?title=DAI-C8-EC:_Exercicis_de_classe&amp;diff=3840&amp;oldid=prev</id>
		<title>Joan: /* Objectius */</title>
		<link rel="alternate" type="text/html" href="http://wiki.joanillo.org/index.php?title=DAI-C8-EC:_Exercicis_de_classe&amp;diff=3840&amp;oldid=prev"/>
		<updated>2009-11-04T09:24:18Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Objectius&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pàgina nova&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Objectius==&lt;br /&gt;
Unitat Didàctica: UD 2. Cursors&lt;br /&gt;
&lt;br /&gt;
L'alumne ja haurà instal.lat l'Oracle (client o servidor) en el seu ordinador, i podrà treballar en local o en el servidor 192.168.0.10. Així mateix, s'espera que ja estigui en condicions per poder treballar a casa.&lt;br /&gt;
&lt;br /&gt;
==Desenvolupament==&lt;br /&gt;
Els exercicis vistos a classe són:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NO oblidar-se de la instrucció&lt;br /&gt;
SQL&amp;gt;SET SERVEROUTPUT ON&lt;br /&gt;
per poder visualitzar la sortida, ni de la &amp;quot;/&amp;quot; per a executar el bloc anònim.&lt;br /&gt;
&lt;br /&gt;
DECLARE&lt;br /&gt;
CURSOR cur1 IS&lt;br /&gt;
	SELECT dnom,loc FROM depart;&lt;br /&gt;
	v_nom VARCHAR2(14);&lt;br /&gt;
	v_localitat VARCHAR2(14);&lt;br /&gt;
BEGIN&lt;br /&gt;
	OPEN cur1;&lt;br /&gt;
	LOOP&lt;br /&gt;
	FETCH cur1 INTO v_nom, v_localitat;&lt;br /&gt;
	EXIT WHEN cur1%NOTFOUND;&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE (v_nom || '*' || v_localitat);&lt;br /&gt;
	END LOOP;&lt;br /&gt;
	CLOSE cur1;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
Atributs del cursor:&lt;br /&gt;
%FOUND: torna TRUE si l'últim FETCH ha retornat algun valor&lt;br /&gt;
%NOTFOUND: el contrari. S'utilitza com a condició de sortida dels bucles.&lt;br /&gt;
%ROWCOUNT: torna el número de files recuperades fins el moment pel cursor.&lt;br /&gt;
%ISOPEN: torna TRUE si el cursor està obert.&lt;br /&gt;
&lt;br /&gt;
Els cursors es declaren, s'obren (OPEN), es recorren mitjançant un bucle i la clàusula FETCH, i finalment es tanquen&lt;br /&gt;
El mateix exemple utilitzant WHILE:&lt;br /&gt;
&lt;br /&gt;
DECLARE&lt;br /&gt;
CURSOR cur1 IS&lt;br /&gt;
	SELECT dnom,loc FROM depart;&lt;br /&gt;
	v_nom VARCHAR2(14);&lt;br /&gt;
	v_localitat VARCHAR2(14);&lt;br /&gt;
BEGIN&lt;br /&gt;
OPEN cur1;&lt;br /&gt;
FETCH cur1 INTO v_nom, v_localitat;&lt;br /&gt;
WHILE cur1%FOUND LOOP&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE (v_nom || '*' || v_localitat);&lt;br /&gt;
	FETCH cur1 INTO v_nom, v_localitat;&lt;br /&gt;
END LOOP;&lt;br /&gt;
CLOSE cur1;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
Variables d'acoblament en l'ús de cursors&lt;br /&gt;
&lt;br /&gt;
CREATE OR REPLACE PROCEDURE veure_empleat_per_dept(dep NUMBER)&lt;br /&gt;
AS&lt;br /&gt;
v_dept NUMBER(2);&lt;br /&gt;
CURSOR c1 IS&lt;br /&gt;
	SELECT cognom FROM emple WHERE dept_no=v_dept;&lt;br /&gt;
	v_cognom VARCHAR2(10);&lt;br /&gt;
BEGIN&lt;br /&gt;
	v_dept := dep;&lt;br /&gt;
	OPEN c1;&lt;br /&gt;
	FETCH c1 INTO v_cognom;&lt;br /&gt;
	WHILE c1%FOUND LOOP&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE(v_cognom);&lt;br /&gt;
	FETCH c1 INTO v_cognom;&lt;br /&gt;
	END LOOP;&lt;br /&gt;
	CLOSE c1;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
SQL&amp;gt;EXECUTE  veure_empleat_per_dept(30)&lt;br /&gt;
&lt;br /&gt;
Cursor FOR...LOOP&lt;br /&gt;
&lt;br /&gt;
DECLARE&lt;br /&gt;
	CURSOR cur2 IS&lt;br /&gt;
		SELECT cognom, ofici, comissio FROM emple WHERE comissio &amp;gt; 100;&lt;br /&gt;
BEGIN&lt;br /&gt;
	FOR v_reg IN cur2 LOOP&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE(v_reg.cognom || '*' || v_reg.ofici || '*' ||TO_CHAR(v_reg.comissio,'999,999'));&lt;br /&gt;
	END LOOP;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
Exemple: escriure un bloc PL/SQL que visualitzi el cognom i data d'alta de l'empresa ordenats per data d'alta,mitjançant un cursor FOR...LOOP i mitjançant un cursor amb bucle WHILE.&lt;br /&gt;
a) FOR..LOOP&lt;br /&gt;
&lt;br /&gt;
DECLARE&lt;br /&gt;
	CURSOR c_emple IS&lt;br /&gt;
		SELECT cognom, ofici, data_alt FROM emple ORDER BY data_alt;&lt;br /&gt;
BEGIN&lt;br /&gt;
	FOR v_reg_emp IN c_emple LOOP&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE(v_reg_emp.cognom || '*' || v_reg_emp.ofici || '*' || v_reg_emp.data_alt);&lt;br /&gt;
	END LOOP;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
b) WHILE&lt;br /&gt;
&lt;br /&gt;
DECLARE&lt;br /&gt;
	CURSOR c_emple IS&lt;br /&gt;
		SELECT cognom,ofici,data_alt FROM emple ORDER BY data_alt;&lt;br /&gt;
	v_reg_emp c_emple%ROWTYPE;&lt;br /&gt;
BEGIN&lt;br /&gt;
	OPEN c_emple;&lt;br /&gt;
	FETCH c_emple INTO v_reg_emp;&lt;br /&gt;
	WHILE c_emple%FOUND LOOP&lt;br /&gt;
		DBMS_OUTPUT.PUT_LINE(v_reg_emp.cognom || '*' || v_reg_emp.ofici || '*' || v_reg_emp.data_alt);&lt;br /&gt;
		FETCH c_emple INTO v_reg_emp;&lt;br /&gt;
	END LOOP;&lt;br /&gt;
	CLOSE c_emple;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
Cursors amb paràmetres&lt;br /&gt;
&lt;br /&gt;
El cursor es declara amb paràmetres, que es passen quan l'obrim amb OPEN: OPEN nom_cursor [(parametre1,parametre2,...)]; En aquest exemple, creem un procediment que li passem 2 paràmetres, que alhora aquests paràmetres se li passen al cursor:&lt;br /&gt;
&lt;br /&gt;
CREATE OR REPLACE PROCEDURE veure_per_dept_i_ofici(vdept NUMBER,Vofici VARCHAR DEFAULT 'DIRECTOR')&lt;br /&gt;
AS&lt;br /&gt;
	v_departament emple.dept_no%TYPE;&lt;br /&gt;
	v_ofici emple.ofici%TYPE;&lt;br /&gt;
	v_cognom emple.cognom%TYPE;&lt;br /&gt;
	v_salari emple.salari%TYPE;&lt;br /&gt;
	CURSOR cur1(v_departament NUMBER, v_ofici VARCHAR2 DEFAULT 'DIRECTOR')&lt;br /&gt;
		IS SELECT cognom,salari FROM EMPLE WHERE dept_no = v_departament AND ofici=v_ofici;&lt;br /&gt;
BEGIN&lt;br /&gt;
	OPEN cur1(vdept,vofici);&lt;br /&gt;
	FETCH cur1 INTO v_cognom, v_salari;&lt;br /&gt;
	WHILE cur1%FOUND LOOP&lt;br /&gt;
		DBMS_OUTPUT.PUT_LINE(v_cognom || '*' || v_salari);&lt;br /&gt;
		FETCH cur1 INTO v_cognom, v_salari;&lt;br /&gt;
	END LOOP;&lt;br /&gt;
	CLOSE cur1;&lt;br /&gt;
END veure_per_dept_i_ofici;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
SQL&amp;gt;EXECUTE veure_per_dept_i_ofici(30,'VENEDOR')&lt;br /&gt;
SQL&amp;gt;EXECUTE veure_per_dept_i_ofici(30)&lt;br /&gt;
&lt;br /&gt;
per obrir el cursor:&lt;br /&gt;
OPEN nom_cursor [(par1, par2,...)]&lt;br /&gt;
En el nostre exemple:&lt;br /&gt;
OPEN cur1(v_dep); --la variable v_dep ha de tenir un valor inicialitzat&lt;br /&gt;
OPEN cur1(v_dep,v_ofici);&lt;br /&gt;
OPEN cur1(20,'VENEDOR');&lt;br /&gt;
&lt;br /&gt;
Atributs en cursors implícits&lt;br /&gt;
&lt;br /&gt;
Oracle obre de forma implícita un cursor quan processa una comanda SQL que no està associada a un cursor explícit.&lt;br /&gt;
El cursor implícit (cursor SQL) ens proporciona informació en les comandes SELECT INTO, INSERT, UPDATE i DELETE.&lt;br /&gt;
Els atributs del cursor SQL són:&lt;br /&gt;
&lt;br /&gt;
SQL%NOTFOUND: dóna TRUE si l'últim INSERTM, UPDATE, DELETE o SELECT INTO han fallat (no han afectat a cap fila).&lt;br /&gt;
SQL%FOUND&lt;br /&gt;
SQL%ROWCOUNT: número de files afectades&lt;br /&gt;
SQL%ISOPEN: sempre retorna FALS&lt;br /&gt;
&lt;br /&gt;
DECLARE&lt;br /&gt;
	v_dept DEPART.DNOM%TYPE;&lt;br /&gt;
	v_loc DEPART.LOC%TYPE;&lt;br /&gt;
BEGIN&lt;br /&gt;
	v_dept := 'MARKETING'; --no existeix MARKETING&lt;br /&gt;
	UPDATE DEPART SET loc='SEVILLA' WHERE dnom=v_dept; --fallarà&lt;br /&gt;
	IF SQL%NOTFOUND THEN&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE('Error dactualització');&lt;br /&gt;
	END IF;&lt;br /&gt;
	SELECT loc INTO v_loc FROM depart WHERE dnom=v_dept; --fallarà i s'aixeca l'excepció NO_DATA_FOUND&lt;br /&gt;
	IF SQL%NOTFOUND THEN&lt;br /&gt;
	DBMS_OUTPUT.PUT_LINE('mai passa per aquí');&lt;br /&gt;
	END IF;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
CURSOR FOR UPDATE&lt;br /&gt;
&lt;br /&gt;
Els cursors no només serveixen per seleccionar files d’una select, sino que també podem utilitzar el nom del cursor que apunta a una fila per realitzar una operació d’actualització en aquesta fila.&lt;br /&gt;
La sintaxi queda reflexada en el següent exemple:&lt;br /&gt;
&lt;br /&gt;
create or replace procedure pujar_salari_departament(&lt;br /&gt;
vp_num_dpt NUMBER,&lt;br /&gt;
vp_pct_pujada NUMBER)&lt;br /&gt;
as&lt;br /&gt;
	cursor c_emple is select ofici,salari from emple &lt;br /&gt;
	where dept_no=vp_num_dpt FOR UPDATE;&lt;br /&gt;
	&lt;br /&gt;
	vc_reg_emple c_emple%rowtype;&lt;br /&gt;
	v_inc number(8,2);&lt;br /&gt;
begin&lt;br /&gt;
	open c_emple;&lt;br /&gt;
	fetch c_emple into vc_reg_emple;&lt;br /&gt;
	while c_emple%found loop&lt;br /&gt;
		v_inc := vc_reg_emple.salari/100 * vp_pct_pujada;&lt;br /&gt;
	update emple set salari=salari + v_inc where current of c_emple;&lt;br /&gt;
	fetch c_emple into vc_reg_emple;&lt;br /&gt;
	end loop;&lt;br /&gt;
end pujar_salari_departament;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
SQL&amp;gt; SELECT cognom, salari from emple where dept_no=20;&lt;br /&gt;
SQL&amp;gt; EXECUTE  pujar_salari_departament(20,5)&lt;br /&gt;
SQL&amp;gt; SELECT cognom, salari from emple where dept_no=20;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
A partir d'aquest codi vist a classe, hauràs d'implementar un script que executi tot aquest codi, i també hauràs de fer un fitxer amb la sortida del log.&lt;br /&gt;
&lt;br /&gt;
A més, implementaràs el procediment ''pujar_salari_antiguitat'' que es mostra a continuació:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
REM Enunciat: Pujar el salari dels empleats un 5% + (anys d'antiguitat)*0,5% &lt;br /&gt;
REM Aquest exercici ha de servir de model per als exercicis que es fan a classe, i és la manera de procedir que es demanarà per a l'examen.&lt;br /&gt;
&lt;br /&gt;
REM El_Teu_Nom num: dai2axx&lt;br /&gt;
&lt;br /&gt;
REM la resolució d'un problema, tal com es demanarà en l'examen, consta de:&lt;br /&gt;
REM 1. enunciat&lt;br /&gt;
REM 2. pensar el problmea&lt;br /&gt;
REM 3. codificació - compilació&lt;br /&gt;
REM 4. depuració dels errors&lt;br /&gt;
REM 5. Joc de proves que mostri les diferents causístiques de l'enunciat&lt;br /&gt;
REM 6. Ampliació del problema, si s'escau.&lt;br /&gt;
&lt;br /&gt;
REM enunciat (exercici sobre cursors)&lt;br /&gt;
1. Pujar el salari dels empleats un 5% + (anys d'antiguitat)*0,5%&lt;br /&gt;
&lt;br /&gt;
REM proves prèvies&lt;br /&gt;
&lt;br /&gt;
update emple set salari=salari*(1.05);&lt;br /&gt;
rollback;&lt;br /&gt;
&lt;br /&gt;
select data_alt, trunc((sysdate-data_alt)/365) num_anys from emple;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
SET SERVEROUTPUT ON&lt;br /&gt;
&lt;br /&gt;
REM farem l'exercici de dues maneres: cursor normal i 'cursor for update'&lt;br /&gt;
REM la idea és que recorrem el cursor fila a fila, i en cada fila fem un update personalitzat segons els anys d'antiguitat de l'empleat en qüestió&lt;br /&gt;
&lt;br /&gt;
REM 1a manera&lt;br /&gt;
&lt;br /&gt;
CREATE OR REPLACE PROCEDURE pujar_salari_antiguitat&lt;br /&gt;
AS&lt;br /&gt;
	CURSOR cur1 IS&lt;br /&gt;
	SELECT EMP_NO,SALARI,trunc((sysdate-data_alt)/365) FROM EMPLE;&lt;br /&gt;
	v_emp_no emple.emp_no%TYPE;&lt;br /&gt;
	v_salari emple.salari%TYPE;&lt;br /&gt;
	v_anys_antiguitat NUMBER(2);&lt;br /&gt;
	v_salari_nou NUMBER(6,2);&lt;br /&gt;
BEGIN&lt;br /&gt;
	OPEN cur1;&lt;br /&gt;
	LOOP&lt;br /&gt;
	FETCH cur1 INTO v_emp_no ,v_salari,v_anys_antiguitat;&lt;br /&gt;
	EXIT WHEN cur1%NOTFOUND;&lt;br /&gt;
	v_salari_nou:=v_salari*(1.05)+v_salari*0.005* v_anys_antiguitat;&lt;br /&gt;
	UPDATE EMPLE SET SALARI=v_salari_nou WHERE EMP_NO=v_emp_no;&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('num empleat: ' || v_emp_no);&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('salari antic: ' || v_salari);&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('salari nou: ' || v_salari_nou);&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('--------------------');&lt;br /&gt;
	END LOOP;&lt;br /&gt;
	CLOSE cur1;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
--execute pujar_salari_antiguitat&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
REM 2a manera. Cursor for update&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CREATE OR REPLACE PROCEDURE pujar_salari_antiguitat2&lt;br /&gt;
AS&lt;br /&gt;
	CURSOR cur1 IS&lt;br /&gt;
	SELECT EMP_NO,SALARI,trunc((sysdate-data_alt)/365) FROM EMPLE FOR UPDATE;&lt;br /&gt;
	v_emp_no emple.emp_no%TYPE;&lt;br /&gt;
	v_salari emple.salari%TYPE;&lt;br /&gt;
	v_anys_antiguitat NUMBER(2);&lt;br /&gt;
	v_salari_nou NUMBER(6,2);&lt;br /&gt;
BEGIN&lt;br /&gt;
	OPEN cur1;&lt;br /&gt;
	LOOP&lt;br /&gt;
	FETCH cur1 INTO v_emp_no ,v_salari,v_anys_antiguitat;&lt;br /&gt;
	EXIT WHEN cur1%NOTFOUND;&lt;br /&gt;
	v_salari_nou:=v_salari*(1.05)+v_salari*0.005* v_anys_antiguitat;&lt;br /&gt;
	UPDATE EMPLE SET SALARI=v_salari_nou where current of cur1;&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('num empleat: ' || v_emp_no);&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('salari antic: ' || v_salari);&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('salari nou: ' || v_salari_nou);&lt;br /&gt;
	--DBMS_OUTPUT.PUT_LINE ('--------------------');&lt;br /&gt;
	END LOOP;&lt;br /&gt;
	CLOSE cur1;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
--execute pujar_salari_antiguitat2&lt;br /&gt;
&lt;br /&gt;
REM Joc de Proves&lt;br /&gt;
&lt;br /&gt;
prompt Salaris inicials&lt;br /&gt;
select emp_no, salari from emple where emp_no=7566 or emp_no=7654;&lt;br /&gt;
&lt;br /&gt;
pause&lt;br /&gt;
&lt;br /&gt;
execute pujar_salari_antiguitat2&lt;br /&gt;
&lt;br /&gt;
prompt Salaris després de la pujada&lt;br /&gt;
select emp_no, salari from emple where emp_no=7566 or emp_no=7654;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Entrega==&lt;br /&gt;
* entregar els fitxers DAI2AXX_script_NA3.sql i DAI2AXX_NA3.log. Si has treballat per parelles: DAI2AXXXX_script_NA3.sql i DAI2AXXXX_NA3.log, indicant a dins clarament el nom i el número de classe (comentaris amb REM). Exercici individual o per parelles.&lt;br /&gt;
* entregar al Moodle: http://192.168.0.15/moodle&lt;br /&gt;
&lt;br /&gt;
==Recursos==&lt;br /&gt;
En el Moodle també pots descarregar el codi per crear les taules, i el codi que s'ha vist a classe.&lt;br /&gt;
&lt;br /&gt;
==Durarda==&lt;br /&gt;
1,5 hores&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Autor}}, octubre 2009&lt;br /&gt;
[[Categoria: IES Jaume Balmes]]&lt;br /&gt;
[[Categoria: Pràctiques DAI-C8-EC]]&lt;/div&gt;</summary>
		<author><name>Joan</name></author>
		
	</entry>
</feed>