Fórum DESTIVAR UMA TRIGGER - URGENTE #42308
12/02/2004
0
ALTER TRIGGER nome_da_trigger INACTIVE;
Na própria base de dados dentro de uma trigger eu mando desativar outra.
Sendo ela
as
begin
[b:3623b6440e]ALTER TRIGGER PRODUTO_AFTER_UPDATE INACTIVE;[/b:3623b6440e]
UPDATE PRODUTO SET
UNIDADE = UNIDADE
WHERE CODIGO = NEW.PRODUTO_CODIGO;
[b:3623b6440e]ALTER TRIGGER PRODUTO_AFTER_UPDATE ACTIVE;[/b:3623b6440e]
end
só que está DANDO O SEGUINTE ERRO
[i:3623b6440e]Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 5, char 3.
ALTER.[/i:3623b6440e]
Maicon Loffi
Curtir tópico
+ 0Posts
17/02/2004
Afarias
Comandos q alteram objetos do banco de dados (DDL) não são aceitos -- sendo assim, vc não pode ativar ou desativar uma Trigger desta forma.
T+
Gostei + 0
17/02/2004
Maicon Loffi
Mas eu já tinha resolvido este problema através de uma StorProcedure que é executada pelo sistema, após cada alteração na ficha de produtos onAfterPost e onAfterDelete.
Através da minha teimozia, eu tinha percebido que o banco de dados não deixa desativar triggers dentro dele mesmo, só por comandos executados externamente.
Embora entendo isso como uma falha, pois teoricamente deveria funcionar. (as execuções deveriam ser em forma de pilha).
Também já percebi que o modo UPDATE CASCADE (foreingkey) deveria ser executado em cada tabela ligada, sem ativar as triggers ligada a tabela.
por exemplo,
caso eu trabalho com varias empresas, e ambas devem possuir seu codigo com o respectivo produto que terá uma certa quantidade em estoque. Esse caso me ocorreu porque o cliente gostaria de mudar o código do produto. Aí bagunça todo o estoque, por mexer nas tabelas de entrada, saída e estoque. É que as foreingkeys são atualizadas por um update, então todas as triggers serão ativadas, onde não deveriam.
Mas valeu pela resposta técnica!
T+
Gostei + 0
17/02/2004
Afarias
Stored Procedure??? Pelo q eu saiba, Stored Procs (como disse na mensagem anterior) tb não suportam comandos DDL
|Embora entendo isso como uma falha, pois teoricamente deveria
|funcionar. (as execuções deveriam ser em forma de pilha).
Não é uma falha. Apenas q por definição, o SQL de Stored Procs e Triggers está restrito a comandos DML -- vc não pode mexer na estrutura do banco atravez deles.
Ok, alguns bancos permitem isso, sendo assim, quem acha q isto é uma funcionalidade importante, pode realmente contar como algo q não existe no IB
|Também já percebi que o modo UPDATE CASCADE (foreingkey) deveria
|ser executado em cada tabela ligada, sem ativar as triggers ligada a
|tabela. {...}
Não sei se entendi o q vc está fazendo. Mas ao q está parecendo talvês suas Triggers não estejam ´bem´ definidas. Se vc puder postar uma explicação detalhada do problema e os códigos envolvidos quem sabe não chegamos a uma solução?!
O fato dos updates (em cascata) dispararem suas triggers a princípio não deveria lhe causar maiores problemas -- e me parece algo correto.
Ainda assim, vc pode sempre fazer como vc fez, desabilitar as triggers antes do processo -- esse é um motivo pelo qual é possível desabilitar triggers:: quando vai se realizar um processo de ´correção´ do banco.
T+
Gostei + 0
17/02/2004
Maicon Loffi
Mas eu já tinha resolvido este problema através de uma StorProcedure
Stored Procedure??? Pelo q eu saiba, Stored Procs (como disse na mensagem anterior) tb não suportam comandos DDL
[b:824673bae2]Sim, mas eu respondi que esta alteração é executado pelo Sistema (Software) que trabalha na base de dados, (Lá no delphi), na base eu também tinha tentado desativar a StorProcedure, mas sei que não funciona.[/b:824673bae2]
|Embora entendo isso como uma falha, pois teoricamente deveria
|funcionar. (as execuções deveriam ser em forma de pilha).
Não é uma falha. Apenas q por definição, o SQL de Stored Procs e Triggers está restrito a comandos DML -- vc não pode mexer na estrutura do banco atravez deles.
[b:824673bae2]Tudo bem, mas o que eu quis me referir é que quem criou o interbase, não pensou nesta possibilidade, até porque vai exigir mais complexidade. Também nem tenho idéia de como é feito um SGDB. (linguagem de baixo nível), deve ser coisa de maluco! Prefiro trabalhar com ele, até porque facilita e muito no desenvolvimento de Softwares.[/b:824673bae2]
|Também já percebi que o modo UPDATE CASCADE (foreingkey) deveria
|ser executado em cada tabela ligada, sem ativar as triggers ligada a
|tabela. {...}
Não sei se entendi o q vc está fazendo. Mas ao q está parecendo talvês suas Triggers não estejam ´bem´ definidas. Se vc puder postar uma explicação detalhada do problema e os códigos envolvidos quem sabe não chegamos a uma solução?!
O fato dos updates (em cascata) dispararem suas triggers a princípio não deveria lhe causar maiores problemas -- e me parece algo correto.
Ainda assim, vc pode sempre fazer como vc fez, desabilitar as triggers antes do processo -- esse é um motivo pelo qual é possível desabilitar triggers:: quando vai se realizar um processo de ´correção´ do banco.
[b:824673bae2]Não seria uma correção, apenas uma alteração.[/b:824673bae2]
Mas vamos la, vc pode testar isso e ver se o que eu estou falando vai ocorrer ou não.
Por Exemplo.
Vc tem uma tabela de [b:824673bae2]produtos [/b:824673bae2]que possui o campo [b:824673bae2]estoque[/b:824673bae2]
Vc Tem uma tabela de [b:824673bae2]Entrada [/b:824673bae2]que possui as triggers que atualizam a [b:824673bae2]entrada[/b:824673bae2] no [b:824673bae2]estoque[/b:824673bae2]
AfterInsert
UPDATE PRODUTO SET
ESTOQUE = ESTOQUE + NEW.QUANTIDADE
WHERE CODIGO = NEW.PRODUTO_CODIGO;
AfterUpdate[b:824673bae2]
UPDATE PRODUTO SET
ESTOQUE = ESTOQUE - NEW.QUANTIDADE
WHERE CODIGO = OLD.PRODUTO_CODIGO;
UPDATE PRODUTO SET
ESTOQUE = ESTOQUE + NEW.QUANTIDADE
WHERE CODIGO = NEW.PRODUTO_CODIGO;
[/b:824673bae2]
AfterDelete
UPDATE PRODUTO SET
ESTOQUE = ESTOQUE - NEW.QUANTIDADE
WHERE CODIGO = OLD.PRODUTO_CODIGO;
Vc Tem uma tabela de Saida que possui as triggers que atualizam a saida
Igualmente as triggers da entrada, só que com o sinal ao contrario, ou seja, no lugar de somar, vai diminuir.
Blz.
O Problema está na trigger AfterUpdate, porque?
No que pude perceber ocorre o seguinte.
Quando altero o codigo do produto na tabela de produto, esta vai atualizar as foreingkeys ligadas a ela.
Será executada a AfterUpdate na tabela de Entrada, então a opção que volta o valor [b:824673bae2]velho, será descartada[/b:824673bae2], pelo fato de na tabela de produto já ter sido modificado o código, então será executado só a soma das entradas lá no estoque.
Depois será executado a alteração na tabela de Saidas, onde o processo será o inverso. então confira o estoque, ele não terá mais o mesmo valor.
Ao ser cadastrado o produto, o valor do estoque será [b:824673bae2]zero[/b:824673bae2]
[i:824673bae2]Não sei que metodo usar, pode ser que o meu esteja errado, mas quem sabe o amigo pode me ajudar.[/i:824673bae2]
T+
Gostei + 0
18/02/2004
Afarias
|sabe o amigo pode me ajudar
Na verdade o método q vc está usando (desativar as triggers) está correto. Mas, realmente neste caso específico fica ´chato´ pois pode tratar-se de algo normal no sistema (alterar o código do produto)
Sendo assim, vc poderia adotar uma solução, alterando o after update para algo como::
if (exists(select 1 from produtos where codigo=old.produto_codigo)) then
begin
{ seus códigos de update de estoque }
end
outra dica (com foco apenas em reduzir processos desnecessários), seria em todas as triggers vc verificar apenas se houve mudança nos campos realmente de interesse, ex::
if (new.produto_codigo<>old.produto_codigo or new.quantidade<>old.quantidade) then
begin
{ seus códigos }
end
bom, quanto a esta forma do IB agir, eu não sei dizer agora se foi alterado no FB (ou nas versões mais recentes do IB) -- mas, se vc for usar um ou outro, pode enviar para seus grupos de desenvolvimento sua verificação desta ocorrência e sugestão para q nos casos de cascade updates as triggers não sejam disparadas -- talves este seja um conceito a ser avaliado.
T+
Gostei + 0
18/02/2004
Maicon Loffi
if (exists(select 1 from produtos where codigo=old.produto_codigo)) then
begin
{ seus códigos de update de estoque }
end
[b:3eebceafe3]sabe que eu não tinha pensado nesta possibilidade![/b:3eebceafe3]
Sabes me dizer o e-mail do grupo que desenvolve o IB?
T+
Gostei + 0
18/02/2004
Afarias
www.borland.com ou www.borland.com.br
lá vc pode procurar a página de suporte ou os grupos de usuários (NewsGroups)
Mas, se vc está com o IB 6 e pretende continuar com uma solução OpenSource, procure o grupo de desenvolvimento do FIREBIRD (e passe o quanto antes a usar o Firebird 1.0 no lugar do IB 6.0)
http://www.firebirdsql.org/
vc pode tb se inscrever na lista de suporte do FB
firebird-support@yahoogroups.com
T+
Gostei + 0
18/02/2004
Maicon Loffi
T+
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)