Olá,
Para dar a minha contribuição, eis como trabalho com a Zeos no Delphi
com o Postgresql:
Criei a função abaixo.
function FpnZTransact( ZConn: TZConnection; ZQue: TZQuery;
ASql: array of string;
lBegin: boolean = true;
lCommit: boolean = true ): boolean;
var ix: integer;
aPre: array [0..2] of string;
emsg: string;
scur: TCursor;
cmtstate: boolean;
procedure FpnZTransExec( TxSql: string );
begin
ZQue.SQL.Clear;
ZQue.SQL.Add( TxSql );
ZQue.ExecSQL;
end;
begin
scur := Screen.Cursor;
// Screen.Cursor := crHourGlass;
Screen.Cursor := crSQLWait;
result := true;
aPre[0] := 'ROLLBACK;';
aPre[1] := 'BEGIN TRANSACTION;';
aPre[2] := 'SET TRANSACTION ISOLATION LEVEL ' +
'READ COMMITTED;';
cmtstate := ZConn.AutoCommit;
ZConn.AutoCommit := false;
try
// processa inicialização da transação
if lbegin then
for ix := 0 to 2 do
FpnZTransExec( aPre[ix] );
// processa comandos recebidos
for ix := 0 to high( aSql ) do
FpnZTransExec( aSql[ix] );
// processa encerramento da transação
if lCommit then
begin
FpnZTransExec( 'COMMIT TRANSACTION;' );
ZQue.SQL.Clear;
ZConn.AutoCommit := cmtstate;
Screen.Cursor := scur;
end
else
begin
ZQue.SQL.Clear;
ZConn.AutoCommit := cmtstate;
end;
Screen.Cursor := scur;
except
on E: Exception do
begin
emsg := E.ClassName + #10;
emsg := emsg + E.Message + '.' + #10 + #10;
FpnZTransExec( 'ROLLBACK TRANSACTION;' );
ZQue.SQL.Clear;
ZConn.AutoCommit := cmtstate;
Screen.Cursor := scur;
// SetPnMsgFreq('', nil, [], PNMSG_CENTER);
// PnMsg( emsg, 'TRANSAÇÃO ABORTADA!' );
result := false;
end;
end;
end;
Como uso:
Incluo uma TZquery (sem DataSource correspondente) que uso como
parametro da função e escrevo as instruções em uma string:
Ex: s := 'INSERT INTO .....;';
FpnZTransact( dm.ZConn, dm.ZqAux, s );
Se tiver muitas instruções, coloco-as em um array dinâmico:
Ex: var: a: array of string;
s: string;
i: integer;
bt, ok: boolean;
begin
ok := true;
bt := true; // para Begin Transaction
SetLength( a, 0 );
s := 'UPDATE tabela SET ...
SetLength( a, i + 1);
a[i] := s;
inc(i);
if (i = 50) then
begin
ok := FpnZTransact( dm.ZConn, dm.ZqAux, a, bt, false); //
inicia transação
if ok then
begin
i := 0;
bt := false;
SetLength( a, 0 );
end
else
exit;
...
// para terminar/commitar (se 'bt' ainda for true, também faz
begin)
if ok then
ok := FpnZTransact( dm.ZConn, dm.ZqAux, a, bt, true);
...
Com essa função posso executar qualquer comando sql (que não retorna
dados) no postgres:
basta usar false para para o begin e o commit.
Quem achar que lhe serve, pode usar a vontade. Quem tiver sugestões para
melhorar a função,
por favor, me envie.
Alias, tenho uma dúvida: tem/qual limite(quantidade) de instruções para
mandar ao servidor antes
de commitar?
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral