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

Reply via email to