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 pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral