Hello Paola,
Friday, May 14, 2010, 8:36:08 PM, you wrote:
PB> en un principio, m�s o menos ten�a esa estructura.. luego agrup� todas PB> las sentencias en un procedimiento y ah� fue el l�o. PB> Dentro de ese procedimiento, las sentencias no est�n dentro del PB> try/except.. est�n unas a continuaci�n de otras. PB> Quiz�s, esa no es la forma m�s correcta de hacerlo... PB> Seg�n tu ejemplo, entonces si agrupo todo ser�a algo as�.??
Hmmm, parecido, ya que al ser una funci�n tienes dos opciones para hacerlo, usando try..except impl�cito para cada execute, o dejando que las excepciones en grupo funcionen. Puedes hacerlo de estos dos modos:
if grabar() then begin
connection.commit
end else begin
connection.rollback;
end;
function grabar(): boolean
begin
try
SQL.Execute; //Lo que sea, insert, sp, delete...
except
result:= false;
Exit;
end;
try
SQL.Execute;
except
result:= false;
Exit;
end;
result:= true;
end;
Tiene la "ventaja" de que puedes reaccionar diferente a cada excepci�n si fuera necesario, o bien:
try
grabar()
connection.commit;
except
connection.rollback;
end;
procedure grabar();
begin
SQL.Execute; //Lo que sea, insert, sp, delete...
SQL.Execute;
[...]
SQL.Execute;
end;
Si cualquiera de las 3 execute dispara una excepci�n se ejecuta el bloque except sin pasar por la linea de commit, con el consiguiente rollback del grupo except.
El "truco" est� en usar el mismo sistema en todos los grupos de actuaciones. Muchas veces necesitamos hacer un insert de muuuuchos registros, esto ralentiza todo si est� en una transacci�n, por lo tanto a veces hay que armarse de paciencia para buscar la combinaci�n de �rdenes de insert para maximizar la velocidad sin comprometer la estructura de los datos.
Un ejemplo, supongamos que queremos crear un hist�rico, pero este hist�rico puede tener millones de registros. Si los metemos todos en una trasacci�n, esto llevar� horas, mientras que si hacemos un commit cada 10000 registros, lo podemos meter en la base de datos en 10 minutos. En este caso tenemos que vendernos al control manual de las transacciones y usar alg�n truco para saber todo lo que hemos metido por si se necesita borrar. Si la BBDD la dise�amos nosotros a�adimos un campo "Verificado" como GUID, lo que nos servir� de control de la transacci�n y har�amos algo como:
var
j: integer;
MyTrans: TGUID;
begin
MyTrans:=GUIDCreate();
j:=0
while not DatosEntrada.EOF do begin
SQL.FieldByName('GUID').asLoQueSea:=MyTrans;
SQL.FieldByName('Otro').asInteger=DatosEntrada.Loquesea;
try
SQL.Insert;
if j>10000 then begin
SQL.Commit;
j:=0;
end;
except
SQL.Rollback;
SQL.SQL.Text:='DELETE FROM HISTORICO WHERE GUID='+MyTrans;
try
SQL.Execute;
SQL.Commit;
except
MessageBox('Algo muy malo ha pasado');
//Guardamos el GUID en un fichero local, para hacer un borrado
//m�s tarde, cuando se sepa por que no ha funcionado la
//excepci�n.
end;
end;
end;
end;
La contrapartida de esto es que tenemos que acordarnos de que todos los SQL que consulten el hist�rico han de disponer de un "AND GUID is NULL" en el where o donde corresponda.
Best regards,
Jos�