GARANTIR DESCONTO

Fórum Funcao que Bloco de Transacao - START TRANSACTION #376469

28/04/2010

0

Olá PessoAll,

Preciso de um auxilio para entender o que está acontecendo ....

Bem, ...
Estou tentando executar uma funcao com um bloco de transação ( FUNCAO 1),  e logo após eu inserir um registro de "endereço" ( sem dar o COMMIT ),  eu chamo uma função que associa o "endereço" inserido ao registro do cliente. No momento de execução dessa função ocorre o erro abaixo.

Alguem saberia informar como eu faço para implementar e resolver esse problema ?  

O objetivo aqui é inserir o registro na tabela de endereços,  e na sequencia associar esse registro a um registro de cliente via chamada da função f_assign_address. Se ocorre algum problema na associação,  eu preciso desfazer a inclusão do registro feita na tabela de "endereço".

Obrigado pela ajuda.  JAIRO RODRIGUES


"ERROR: SPI_execute_plan failed executing query "START TRANSACTION": SPI_ERROR_TRANSACTION
 CONTEXT: PL/PgSQL function "f_assign_address" line 7 at SQL statement

----------------  FUNCAO 1 ---------------
declare
     iNroRegistrosProcessados integer;
     idNewRecAddress BIGINT;
     iRet BIGINT;
BEGIN

START TRANSACTION ;

SAVEPOINT sp1;

    idNewRecAddress := nextval('sequence_id_endereco');

    INSERT INTO endereco
    VALUES ( idNewRecAddress,rua,
        nro, bairro, cidade, cep,
        uf, pais, complemento,
        local_endereco,
        longitude,
        latitude,
        CURRENT_DATE, CURRENT_DATE);


    GET DIAGNOSTICS iNroRegistrosProcessados = ROW_COUNT;

    IF iNroRegistrosProcessados = 1 THEN
        iRet = f_assign_address ( idNewRecAddress, id_reg, tipo_endereco );   --  FUNCAO 2 ----
        if iRet > 0 then
             COMMIT;
             iRet = idNewRecAddress ;   
        else
            rollback to sp1;
        end if;
    ELSE
        rollback to sp1;
        iRet = -1;
    END IF;

    return iRet;

END;


-----------------  FUNCAO  2 -  f_assign_address  ---------------

declare
     iNroRegistrosProcessados integer;
     ret integer;
  
BEGIN

START TRANSACTION;

ret = 0;
iNroRegistrosProcessados := 0;
 
IF tipo_endereco = 'ECV' THEN
   INSERT INTO endereco_ecv VALUES ( id_reg, id_new_address );
ELSIF tipo_endereco = 'VIRTUALTEF' then
   INSERT INTO virtualtef2_endereço VALUES ( id_reg, id_new_address );
ELSIF tipo_endereco = 'ADQUIRENTE' THEN
   INSERT INTO adquirente_endereco VALUES ( id_reg, id_new_adress );
ELSIF tipo_endereco = 'PARCEIRO' THEN
   INSERT INTO endereco_parceiro VALUES ( id_new_adress, id_reg );
ELSE
   -- Tipo de endereco nao reconhecido
   ret = -10;
end if;

commit;
RETURN ret;    

END;

Jairo Oliveira

Jairo Oliveira

Responder

Posts

09/06/2010

Saulo Benvenutti

Jairo na plpgsql você não precisa de controle transacional, pois o PostgreSQL subentende que a operação e transacionada ..., ou seja, sendo mais específico, basta vc retirar os start transaction ... das duas funcoes e controlar com raise exception ou com o retorno da funcao chamada ...
ex.: fdeclare      iNroRegistrosProcessados integer;
     idNewRecAddress BIGINT;
     iRet BIGINT;
BEGIN


    idNewRecAddress := nextval('sequence_id_endereco');

    INSERT INTO endereco
    VALUES ( idNewRecAddress,rua,
        nro, bairro, cidade, cep,
        uf, pais, complemento,
        local_endereco,
        longitude,
        latitude,
        CURRENT_DATE, CURRENT_DATE);


    GET DIAGNOSTICS iNroRegistrosProcessados = ROW_COUNT;

    IF iNroRegistrosProcessados = 1 THEN
        iRet = f_assign_address ( idNewRecAddress, id_reg, tipo_endereco );   --  FUNCAO 2 ----
        if iRet < 0 then             Return -1;             RAISE EXCEPTION 'ERRO DE VÍNCULO %',iRet;
        else
            iRet = idNewRecAddress;
        end if;
    ELSE
         RAISE EXCEPTION 'ERRO DE VÍNCULO %',iRet;         iRet = -1;
    END IF;

    return iRet;

END;


-----------------  FUNCAO  2 -  f_assign_address  ---------------

declare 
     iNroRegistrosProcessados integer;
     ret integer;
   
BEGIN


ret = 0;
iNroRegistrosProcessados := 0;
  
IF tipo_endereco = 'ECV' THEN
   INSERT INTO endereco_ecv VALUES ( id_reg, id_new_address );
ELSIF tipo_endereco = 'VIRTUALTEF' then
   INSERT INTO virtualtef2_endereço VALUES ( id_reg, id_new_address );
ELSIF tipo_endereco = 'ADQUIRENTE' THEN
   INSERT INTO adquirente_endereco VALUES ( id_reg, id_new_adress );
ELSIF tipo_endereco = 'PARCEIRO' THEN
   INSERT INTO endereco_parceiro VALUES ( id_new_adress, id_reg );
ELSE
   -- Tipo de endereco nao reconhecido
   ret = -10;
end if;


RETURN ret;     

END;


Espero ter ajudado
Responder

Gostei + 0

07/07/2010

Jairo Oliveira

Saulo,  obrigado pela ajuda ! ...  Eu demorei pra responder pois acabamos mudando a estratégia do projeto.  Fizemos a opção pelo SQL Server,   mas continuo trabalhando em outros projetos com o Postgres.

Um abraço e muito obrigado !

Jairo
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar