Atualização table por uma trigger?
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
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
Gracias.
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
ENDGracias.
Adriano Dolce
Curtidas 0
Respostas
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
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
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!
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
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?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!
Obrigado pela ajuda.
GOSTEI 0
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.
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
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