Atualização table por uma trigger?

Firebird

24/02/2012

Pessoal estou usando o firebird 1.5 e tenho aqui uma tabela chamada vendas que dispara uma trigger cfe, a condição de um campo, a tirgger dispara cfe esta condição aqui

 IF (NEW.TIPO IS NULL) then


Este campo quando é uma venda ele fica NULL e funciona a trigger normalmente, só que as vezes estes campo TIPO tem um valor Orçamento e ai não deve disparar a trigger cfe condição, até ai tudo ok.

O problema está quando eu transformo um orçamento em vendas, o campo fica NULL, mais a trigger não é executada, mudei a trigger para o AFTER e mesmo assim não insere os dados na tabela CLIENTES_CREDITOS


Segue a trigger

CREATE OR ALTER TRIGGER VENDAS_BU FOR VENDAS
ACTIVE BEFORE UPDATE POSITION 0
AS
DECLARE VARIABLE V_PAGAMENTO INTEGER;
DECLARE VARIABLE TOTAL_ATUAL INTEGER;
DECLARE VARIABLE CREDITO_ATUAL FLOAT;
DECLARE VARIABLE CREDITO_USADO FLOAT;

DECLARE VARIABLE CAIXA_MOVIMENTACAO_ATUAL INTEGER;

BEGIN

  NEW.CODIGO_CAIXA = OLD.CODIGO_CAIXA;

  IF (NEW.CANCELADO = Sim) then
         update VENDAS_ITENS set ITEM_CANCELADO = Sim where CODIGO = OLD.CODIGO;


   /*apartir daqui*/
  CAIXA_MOVIMENTACAO_ATUAL = NEW.CODIGO_CAIXA;
  NEW.CODIGO_CAIXA = OLD.CODIGO_CAIXA;

  /* Atuliza o créditos do cliente caso ele tenha usado */
  IF (NEW.TIPO IS NULL) then
  BEGIN

    IF ( NEW.VALOR_EM_CREDITOS_USADOS > 0 ) THEN
    BEGIN

      CREDITO_USADO = ( OLD.VALOR_EM_CREDITOS_USADOS - NEW.VALOR_EM_CREDITOS_USADOS );

      IF ( CREDITO_USADO < 0 ) THEN
        CREDITO_USADO = CREDITO_USADO * -1;

      IF ( CREDITO_USADO > 0 ) THEN
      BEGIN

        /* Atualiza o Crédito do Cliente */
        INSERT
        INTO CLIENTES_CREDITOS
            ( CODIGO_CLIENTE,
              TIPO_MOVIMENTACAO,
              VALOR_ALTERADO,
              CODIGO_USUARIO,
              ORIGEM,
              CODIGO_VENDA,
              CODIGO_CAIXA )
            VALUES
            ( NEW.CODIGO_CLIENTE,
              -,
              :CREDITO_USADO,
              NEW.CODIGO_USUARIO,
              Débito no Frente de Caixa,
              NEW.CODIGO,
              :CAIXA_MOVIMENTACAO_ATUAL );

      END

    END

  END

 END


Gracias.
Adriano Dolce

Adriano Dolce

Curtidas 0

Respostas

Adriano Dolce

Adriano Dolce

24/02/2012

O forum destorce todo meu codigo... vou tentar postar a trigger de novo


CREATE OR ALTER TRIGGER VENDAS_BU FOR VENDAS
ACTIVE BEFORE UPDATE POSITION 0
AS
DECLARE VARIABLE V_PAGAMENTO INTEGER;
DECLARE VARIABLE TOTAL_ATUAL INTEGER;
DECLARE VARIABLE CREDITO_ATUAL FLOAT;
DECLARE VARIABLE CREDITO_USADO FLOAT;

DECLARE VARIABLE CAIXA_MOVIMENTACAO_ATUAL INTEGER;

BEGIN

NEW.CODIGO_CAIXA = OLD.CODIGO_CAIXA;

IF (NEW.CANCELADO = Sim) then
update VENDAS_ITENS set ITEM_CANCELADO = Sim where CODIGO = OLD.CODIGO;


/*apartir daqui*/
CAIXA_MOVIMENTACAO_ATUAL = NEW.CODIGO_CAIXA;
NEW.CODIGO_CAIXA = OLD.CODIGO_CAIXA;

/* Atuliza o créditos do cliente caso ele tenha usado */
IF (NEW.TIPO IS NULL) then
BEGIN

IF ( NEW.VALOR_EM_CREDITOS_USADOS > 0 ) THEN
BEGIN

CREDITO_USADO = ( OLD.VALOR_EM_CREDITOS_USADOS - NEW.VALOR_EM_CREDITOS_USADOS );

IF ( CREDITO_USADO < 0 ) THEN
CREDITO_USADO = CREDITO_USADO * -1;

IF ( CREDITO_USADO > 0 ) THEN
BEGIN

/* Atualiza o Crédito do Cliente */
INSERT
INTO CLIENTES_CREDITOS
( CODIGO_CLIENTE,
TIPO_MOVIMENTACAO,
VALOR_ALTERADO,
CODIGO_USUARIO,
ORIGEM,
CODIGO_VENDA,
CODIGO_CAIXA )
VALUES
( NEW.CODIGO_CLIENTE,
-,
:CREDITO_USADO,
NEW.CODIGO_USUARIO,
Débito no Frente de Caixa,
NEW.CODIGO,
:CAIXA_MOVIMENTACAO_ATUAL );

END

END

END

END
GOSTEI 0
Diego Lusa

Diego Lusa

24/02/2012

Acredito que o problema que você está tendo encontra-se em alguns dos testes que são feitos até se chegar no insert.
Faça o seguinte:

Inicialize as variáveis. É uma boa prática;
Crie um exception genérica com uma mensagem vazia: (create expcetion generica ;);
Utilize a exception criada para depurar a trigger, movendo-a em pontos de debug específicos, escrevendo o valor das variáveis utilizadas nos testes (exception generica Variavel a = ||VARIAVEL_A);

Boa sorte!
GOSTEI 0
Adriano Dolce

Adriano Dolce

24/02/2012

Acredito que o problema que você está tendo encontra-se em alguns dos testes que são feitos até se chegar no insert.
Faça o seguinte:

Inicialize as variáveis. É uma boa prática;
Crie um exception genérica com uma mensagem vazia: (create expcetion generica ;);
Utilize a exception criada para depurar a trigger, movendo-a em pontos de debug específicos, escrevendo o valor das variáveis utilizadas nos testes (exception generica Variavel a = ||VARIAVEL_A);

Boa sorte!
Olá, então, tentei entender sua resposta, mais confesso não ter conseguido entender o que vc quis dizer. Poderia exemplificar?

Obrigado pela ajuda.
GOSTEI 0
Adriano Dolce

Adriano Dolce

24/02/2012

Acho que ja achei o problema, debuguei linha a linha entrando nos códigos até achar uma maldita variável que criaram que esta pegando o primeiro que é selecionado.

Vi que fizeram assim: No oncreate do form ja vem selecionado ou Vendas ou Pedidos ou Orçamento, ai é populado esta variável, pois bem estavariavel recebe este valor e fica ali e cada vez que passava pra gravar gravava somente o primeiro que recebeu.
No caso se eu selecionar Orçamento e fechar como Orçamento, e depois mudar para Vendas como a variável não sabia que tinha mudado continuava como orçamento, mais agora fiz com que a variavel recebe o valor correto quando mudar de venda para orçamento ou pedido ou vice versa...

Mais ainda estou fazendo os testes, amanha quero ver se vai dar certo, mais pelo primeiros testes que fiz ja estava funcionando.

Então o problema não era na trigger como achei que era e sim no modo que era feito a forma de gravar os dados.
GOSTEI 0
Diego Lusa

Diego Lusa

24/02/2012


Olá Adriano.


O uso de exception serve para o programador lançar mensagens de erro personalizadas a partir da base de dados.
Por exemplo, você poderia ter uma trigger para validar o saldo bancário de um correntista e, atravéz dela, controlar se ele tem ou não
dinheiro suficiente para uma transferência. Se não houver dinheiro suficiente, você lança uma exceção para a aplicação com uma mensagens do tipo
Saldo insuficiente para a operação.

Eu utilizo exceções também para debugar triggers ou procedures mais complexas. Vou tentar explicar:
Primeiro você cria uma exceção na base, com o comando create exception. Pode dar o nome que quiser a ela. Vou utilizar generica.
O comando ficaria assim: CREATE EXCEPTION GENERICA Minha mensagem.

Depois disso basta colocar o compando EXCEPTION <nome da exceção> <mensagem> na posição que você deseja que tenha um ponto de debug. Utilizei um trecho da
tua trigger e adicionei o comando para tentar exemplificar.

Interpretar os resultado é fácil (baseado na posição do comando na tua trigger). Se não der erro ao efetuar um update, significa que não entrou no IF. Se der, vai mostrar
o valor da variável CREDITO_USADO no console.

A partir daí você pode mover o comando exception para dentro dos IFs e verificar onde está o problema.



CREATE OR ALTER TRIGGER VENDAS_BU FOR VENDAS
ACTIVE BEFORE UPDATE POSITION 0
AS
DECLARE VARIABLE V_PAGAMENTO INTEGER;
DECLARE VARIABLE TOTAL_ATUAL INTEGER;
DECLARE VARIABLE CREDITO_ATUAL FLOAT;
DECLARE VARIABLE CREDITO_USADO FLOAT;

DECLARE VARIABLE CAIXA_MOVIMENTACAO_ATUAL INTEGER;

BEGIN

.....

IF ( NEW.VALOR_EM_CREDITOS_USADOS > 0 ) THEN
BEGIN

CREDITO_USADO = ( OLD.VALOR_EM_CREDITOS_USADOS - NEW.VALOR_EM_CREDITOS_USADOS );

--quando chegar aqui a trigger irá abortar com a mensagem de erro informada.
EXCEPTION GENERICA Credito usado tem o valor de || CREDITO_USADO;




IF ( CREDITO_USADO < 0 ) THEN
CREDITO_USADO = CREDITO_USADO * -1;

IF ( CREDITO_USADO > 0 ) THEN
BEGIN

/* Atualiza o Crédito do Cliente */
INSERT
INTO CLIENTES_CREDITOS
( CODIGO_CLIENTE,
TIPO_MOVIMENTACAO,
VALOR_ALTERADO,
CODIGO_USUARIO,
ORIGEM,
CODIGO_VENDA,
CODIGO_CAIXA )
VALUES
( NEW.CODIGO_CLIENTE,
-,
:CREDITO_USADO,
NEW.CODIGO_USUARIO,
Débito no Frente de Caixa,
NEW.CODIGO,
:CAIXA_MOVIMENTACAO_ATUAL );

END

END

END

END



GOSTEI 0
POSTAR