<?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_Transaccions._Exercicis_proposats</id>
	<title>DAI-C8-EC: Transaccions. Exercicis proposats - 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_Transaccions._Exercicis_proposats"/>
	<link rel="alternate" type="text/html" href="http://wiki.joanillo.org/index.php?title=DAI-C8-EC:_Transaccions._Exercicis_proposats&amp;action=history"/>
	<updated>2026-08-30T09:10:28Z</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:_Transaccions._Exercicis_proposats&amp;diff=247913&amp;oldid=prev</id>
		<title>Joan: /* Desenvolupament */</title>
		<link rel="alternate" type="text/html" href="http://wiki.joanillo.org/index.php?title=DAI-C8-EC:_Transaccions._Exercicis_proposats&amp;diff=247913&amp;oldid=prev"/>
		<updated>2011-11-16T15:47:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Desenvolupament&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 4. Transaccons&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;
Codi vist a classe:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Control de Transaccions&lt;br /&gt;
=======================&lt;br /&gt;
Transacció: conjunt d’operacions que es realitzen a la base de dades.&lt;br /&gt;
Oracle garanteix la consistencia de les dades en una transacció en termes de TOT VAL o NO VAL RES, és a dir, s’executen totes les operacions que composen una transacció o bé no se n’executa ninguna.&lt;br /&gt;
&lt;br /&gt;
La transacció finalitza amb un COMMIT, un ROLLBACK, una ordre SQL del tipus DDL (definició de dades), o bé quan acaba la sessió.&lt;br /&gt;
&lt;br /&gt;
COMMIT: dóna per acabada la transacció actual i fa definitius els canvis efectuats, alliberant les files bloquejades. Només després del Commit els usuaris tenen accés a les dades modificades.&lt;br /&gt;
&lt;br /&gt;
ROLLBACK: Dóna per conclosa la transacció actual i desfà els canvis que es puguin haver produït en la mateixa, alliberant les files bloquejades. S’utilitza especialment quan no es pot concloure una transacció perque s’ha aixecat una excepció.&lt;br /&gt;
&lt;br /&gt;
ROLLBACK implícit: Quan un subprograma falla i no es controla l’excepció que produeix l’errada, es realitza un Rollback automàtic de tots els canvis que ha prodiït el subprograma, a no ser quehi hagi un commit per confirmar els canvis produïts.&lt;br /&gt;
&lt;br /&gt;
SAVEPOINT: S’utilitza per posar marques o punts de salvaguarda en procesar transaccions. S’utilitza juntament amb el ROLLBACK TO, i serveix per a desfer una part d’una transacció.&lt;br /&gt;
Executar el següeNt procediment (crear prèviament la taula temp1):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE temp1(col1 VARCHAR2(15));&lt;br /&gt;
&lt;br /&gt;
create or replace procedure prova_savepoint(num_files positive)&lt;br /&gt;
As&lt;br /&gt;
Begin&lt;br /&gt;
	Savepoint ninguna;&lt;br /&gt;
	Insert into temp1(col1) values ('primera fila');&lt;br /&gt;
	Savepoint una;&lt;br /&gt;
	Insert into temp1(col1) values ('segona fila');&lt;br /&gt;
	Savepoint dos;&lt;br /&gt;
	&lt;br /&gt;
	If num_files=1 then&lt;br /&gt;
		Rollback to una;&lt;br /&gt;
	Elsif num_files=2 then&lt;br /&gt;
		Rollback to dos;&lt;br /&gt;
	Else&lt;br /&gt;
		Rollback to ninguna;&lt;br /&gt;
	End if;&lt;br /&gt;
	Commit;&lt;br /&gt;
Exception&lt;br /&gt;
	When others then&lt;br /&gt;
		Rollback;&lt;br /&gt;
End;&lt;br /&gt;
/&lt;br /&gt;
&lt;br /&gt;
delete from temp1;&lt;br /&gt;
execute prova_savepoint(1)&lt;br /&gt;
select * from temp1;&lt;br /&gt;
&lt;br /&gt;
delete from temp1;&lt;br /&gt;
execute prova_savepoint(2)&lt;br /&gt;
select * from temp1;&lt;br /&gt;
&lt;br /&gt;
delete from temp1;&lt;br /&gt;
execute prova_savepoint(3)&lt;br /&gt;
select * from temp1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Recordem que fer un DELETE, INSERT o UPDATE en la consola del sqlplus no és cap garantia de què les noves dades estiguin disponibles. No serà la primera vegada que un alumne fa un INSERT, vol veure la fila amb una SELECT, i es torna mico perquè no la veu (no és habitual, però passa...).&lt;br /&gt;
&lt;br /&gt;
Fés la següent prova:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select count(*) from emple;&lt;br /&gt;
delete from emple;&lt;br /&gt;
select count(*) from emple;&lt;br /&gt;
rollback;&lt;br /&gt;
select count(*) from emple;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
En aquest cas, en fer el ''delete from emple'' has obert una transacció implícita, que no està tancada, i per tant tens temps de fer un ROLLBACK.&lt;br /&gt;
&lt;br /&gt;
===solucions===&lt;br /&gt;
1. Escribir un procedimiento que suba el sueldo de todos los empleados que ganen menos que el salario medio de su oficio. La subida será de el 50% de la diferencia entre el salario del empleado y la media de su oficio. Se deberá asegurar que la transacción no se quede a medias, y se gestionarán los posibles errores.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE PROCEDURE pujada_50pct&lt;br /&gt;
AS&lt;br /&gt;
	CURSOR c_ofi_sal IS&lt;br /&gt;
		SELECT ofici, AVG(salari) salari FROM emple&lt;br /&gt;
	GROUP BY ofici;&lt;br /&gt;
CURSOR c_emp_sal IS&lt;br /&gt;
		SELECT ofici, salari FROM emple E1&lt;br /&gt;
		WHERE salari &amp;lt; &lt;br /&gt;
&lt;br /&gt;
(SELECT AVG(salari) FROM emple E2&lt;br /&gt;
	WHERE E2.ofici = E1.ofici)&lt;br /&gt;
	ORDER BY ofici, salari FOR UPDATE OF salari;&lt;br /&gt;
	&lt;br /&gt;
vr_ofi_sal c_ofi_sal%ROWTYPE;&lt;br /&gt;
vr_emp_sal c_emp_sal%ROWTYPE;	&lt;br /&gt;
v_increment emple.salari%TYPE;&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
BEGIN&lt;br /&gt;
	COMMIT;&lt;br /&gt;
 	OPEN c_emp_sal;&lt;br /&gt;
	FETCH c_emp_sal INTO vr_emp_sal;&lt;br /&gt;
OPEN c_ofi_sal;&lt;br /&gt;
	FETCH c_ofi_sal INTO vr_ofi_sal;&lt;br /&gt;
	WHILE c_ofi_sal%FOUND AND c_emp_sal%FOUND LOOP	&lt;br /&gt;
&lt;br /&gt;
		/* calcular increment */&lt;br /&gt;
&lt;br /&gt;
v_increment :=&lt;br /&gt;
 (vr_ofi_sal.salari - vr_emp_sal.salari) / 2;&lt;br /&gt;
&lt;br /&gt;
		/* actualitzar */		&lt;br /&gt;
UPDATE emple SET salari = salari + v_increment&lt;br /&gt;
  WHERE CURRENT OF c_emp_sal;		&lt;br /&gt;
&lt;br /&gt;
		/* següent empleat */		&lt;br /&gt;
FETCH c_emp_sal INTO vr_emp_sal;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* comprovar si és un altre ofici */&lt;br /&gt;
IF c_ofi_sal%FOUND and &lt;br /&gt;
	  vr_ofi_sal.ofici &amp;lt;&amp;gt; vr_emp_sal.ofici THEN&lt;br /&gt;
FETCH c_ofi_sal INTO vr_ofi_sal;&lt;br /&gt;
		END IF;&lt;br /&gt;
	END LOOP; &lt;br /&gt;
	CLOSE c_emp_sal;&lt;br /&gt;
	CLOSE c_ofi_sal;&lt;br /&gt;
&lt;br /&gt;
	COMMIT;&lt;br /&gt;
EXCEPTION&lt;br /&gt;
	WHEN OTHERS THEN&lt;br /&gt;
	  	ROLLBACK WORK;&lt;br /&gt;
		RAISE;&lt;br /&gt;
END pujada_50pct;&lt;br /&gt;
/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
2. Crear la tabla T_liquidacio con las columnas apellido, departamento, oficio, salario, trienios, comp_responsabilidad, comisión y total; y modificar la aplicación anterior para que en lugar de realizar el listado directamente en pantalla, guarde los datos en la tabla. Se controlarán todas las posibles incidencias que puedan ocurrir durante el proceso.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE t_liquidacio (&lt;br /&gt;
 COGNOM  		VARCHAR2(10),&lt;br /&gt;
 DEPARTAMENT		NUMBER(2),&lt;br /&gt;
 OFICI    		VARCHAR2(10),&lt;br /&gt;
 SALARI   		NUMBER(10),&lt;br /&gt;
 TRIENIS		NUMBER(10),&lt;br /&gt;
 COMP_RESPONSABILITAT	NUMBER(10),&lt;br /&gt;
 COMISSIO  		NUMBER(10),&lt;br /&gt;
&lt;br /&gt;
 TOTAL 			NUMBER(10)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE FUNCTION anys_dif (&lt;br /&gt;
data1 DATE,&lt;br /&gt;
	data2 DATE)&lt;br /&gt;
RETURN NUMBER&lt;br /&gt;
AS&lt;br /&gt;
	v_anys_dif NUMBER(6);&lt;br /&gt;
BEGIN&lt;br /&gt;
	v_anys_dif := ABS(TRUNC(MONTHS_BETWEEN(data2,data1)&lt;br /&gt;
 / 12));&lt;br /&gt;
&lt;br /&gt;
	RETURN v_anys_dif;&lt;br /&gt;
END anys_dif;&lt;br /&gt;
/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE FUNCTION trienis (&lt;br /&gt;
data1 DATE, data2 DATE)&lt;br /&gt;
RETURN NUMBER&lt;br /&gt;
AS&lt;br /&gt;
	v_trienis NUMBER(6);&lt;br /&gt;
BEGIN&lt;br /&gt;
	v_trienis := TRUNC(anys_dif(data1,data2) / 3);&lt;br /&gt;
&lt;br /&gt;
 	RETURN v_trienis;&lt;br /&gt;
END;&lt;br /&gt;
/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE PROCEDURE liquidar2&lt;br /&gt;
AS&lt;br /&gt;
	CURSOR c_emp IS&lt;br /&gt;
 	SELECT cognom, emp_no, ofici, salari,&lt;br /&gt;
 		NVL(comissio,0) comissio, dept_no, data_alt&lt;br /&gt;
	 	FROM emple&lt;br /&gt;
	 	ORDER BY cognom;&lt;br /&gt;
	vr_emp c_emp%ROWTYPE;&lt;br /&gt;
&lt;br /&gt;
	v_trien NUMBER(9) DEFAULT 0;&lt;br /&gt;
	v_comp_r NUMBER(9);&lt;br /&gt;
	v_total NUMBER(10);&lt;br /&gt;
BEGIN&lt;br /&gt;
	COMMIT WORK;&lt;br /&gt;
	FOR vr_emp in c_emp LOOP&lt;br /&gt;
&lt;br /&gt;
		/* Calcular trienis. Crida a la funció trienis creada en un exercici anterior */ &lt;br /&gt;
&lt;br /&gt;
	v_trien := trienis(vr_emp.data_alt,SYSDATE)*5000;&lt;br /&gt;
  		&lt;br /&gt;
		/* Calcular complement de responsabilitat. Es tanca en un bloc doncs aixecarà NO_DATA_FOUND*/&lt;br /&gt;
BEGIN&lt;br /&gt;
			SELECT COUNT(*) INTO v_comp_r	&lt;br /&gt;
	  			FROM EMPLE WHERE DIR = vr_emp.emp_no;&lt;br /&gt;
&lt;br /&gt;
			v_comp_r := v_comp_r *10000;&lt;br /&gt;
		EXCEPTION&lt;br /&gt;
	   		WHEN NO_DATA_FOUND THEN&lt;br /&gt;
	     			v_comp_r:=0;&lt;br /&gt;
END; &lt;br /&gt;
&lt;br /&gt;
/* Calcular el total de l'empleat */&lt;br /&gt;
v_total := vr_emp.salari + vr_emp. comissio + v_trien + v_comp_r;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		/* Insertar les dades en la tabla T_liquidacio */&lt;br /&gt;
		INSERT INTO t_liquidacio (COGNOM,OFICI, SALARI, TRIENIS,  COMP_RESPONSABILITAT, COMISSIO, TOTAL)   	&lt;br /&gt;
		  VALUES (vr_emp.cognom, vr_emp.ofici, vr_emp.salari, v_trien, v_comp_r, vr_emp.comissio, v_total);&lt;br /&gt;
&lt;br /&gt;
	END LOOP;&lt;br /&gt;
EXCEPTION&lt;br /&gt;
	WHEN OTHERS THEN&lt;br /&gt;
	  ROLLBACK WORK;&lt;br /&gt;
END liquidar2;&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_NA4.sql i DAI2AXX_NA4.log. Si has treballat per parelles: DAI2AXXXX_script_NA4.sql i DAI2AXXXX_NA4.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>