alguém PODE ME AJUDAR EM UMA TRIGGER QUE FAZ UPDATE?

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
emer_rosa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Sáb, 28 Ago 2010 10:45 am
Localização: Torres-RS
Emerson E. Rosa

OLÁ, PRECISO FAZER UMA TRIGGER QUE FAÇA O SEGUINTE:

TENHO A TABELA TGFPAR QUE É A TABELA DE CLIENTES, NESTA TABELA TENHO DOIS CAMPOS O CAMPO BLOQUEAR E O CAMPO AD_BLOQPRAZO, AMBOS SÃO 'S' OU 'N', EU PRECISO DE UMA TRIGGER QUE AO MUDAR UM DOS DOIS CAMPOS ELE MUDE O OUTRO, O CAMPO BLOQUEAR SEMPRE TEM QUE SER IGUAL AO AD_BLOQPRAZO, E VICE VERSA, FIZ A SEGUINTE TRIGGER SO QUE NÃO FUNCIONA:

Selecionar tudo

CREATE OR REPLACE TRIGGER TESTE_UPD_BLOQPRAZO
BEFORE UPDATE
ON TGFPAR 
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
      IF UPDATING('BLOQUEAR') then
      :NEW.AD_BLOQPRAZO := :NEW.BLOQUEAR;
      END IF;
      
      IF UPDATING('AD_BLOQPRAZO') then
      :NEW.BLOQUEAR := :NEW.AD_BLOQPRAZO;
      END IF;
END;
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

Selecionar tudo


IF :NEW.AD_BLOQPRAZO <> :OLD.AD_BLOQPRAZO  then 
   :NEW.BLOQUEAR := :NEW.AD_BLOQPRAZO; 
ELSEIF :NEW.BLOQUEAR <> :OLD.BLOQUEAR then 
   :NEW.AD_BLOQPRAZO := :NEW.BLOQUEAR; 
END IF;
      
emer_rosa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Sáb, 28 Ago 2010 10:45 am
Localização: Torres-RS
Emerson E. Rosa

Não deu certo, ele compila certinho, mais quando testo os campos ele não altera o outro, aparentemente ta certinho, mais não funciona, muito intrigante.

Selecionar tudo

CREATE OR REPLACE TRIGGER TESTE_UPD_BLOQPRAZO
BEFORE INSERT OR UPDATE
ON TGFPAR 
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF :NEW.BLOQUEAR <> :OLD.BLOQUEAR  THEN 
   :NEW.BLOQUEAR := :NEW.AD_BLOQPRAZO; 

IF :NEW.AD_BLOQPRAZO <> :OLD.AD_BLOQPRAZO  THEN 
   :NEW.AD_BLOQPRAZO := :NEW.BLOQUEAR; 
END IF;
END;
Com o ELSEIF deu erro de compilação.
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

acho q a logica não tava certa... vê agora

Selecionar tudo

IF :NEW.BLOQUEAR <> :OLD.BLOQUEAR  THEN 
   :NEW.AD_BLOQPRAZO:= :NEW.BLOQUEAR; 

IF :NEW.AD_BLOQPRAZO <> :OLD.AD_BLOQPRAZO  THEN 
   :NEW.BLOQUEAR := :NEW.AD_BLOQPRAZO; 
END IF; 
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

Estava invertido quando você estava setando os valores...

Selecionar tudo

CREATE OR REPLACE TRIGGER TESTE_UPD_BLOQPRAZO
BEFORE INSERT OR UPDATE OF BLOQUEAR, AD_BLOQPRAZO
ON TGFPAR
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF :NEW.BLOQUEAR <> :OLD.BLOQUEAR  THEN
   :NEW.AD_BLOQPRAZO := :NEW.BLOQUEAR;

IF :NEW.AD_BLOQPRAZO <> :OLD.AD_BLOQPRAZO  THEN
   :NEW.BLOQUEAR := :NEW.AD_BLOQPRAZO;
END IF;
END; 
emer_rosa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Sáb, 28 Ago 2010 10:45 am
Localização: Torres-RS
Emerson E. Rosa

Não tem jeito, compila certinho mais não meche nos Campos quando altero um ou outro, deu erro de compilação, ai coloquei END IF; no meio.

Sera que não tem que ser AFTER em vez de BEFORE, so que se simplesmente mudar para AFTER ele da o seguinte erro:

Error at line 1
ORA-04084: não pode alterar valores NEW para este tipo de gatilho

e SE EU TIRAR os NEW ele não compila.

Segue cod

Selecionar tudo

CREATE OR REPLACE TRIGGER TESTE_UPD_BLOQPRAZO 
BEFORE INSERT OR UPDATE OF BLOQUEAR, AD_BLOQPRAZO 
ON TESTE.TGFPAR 
REFERENCING NEW AS NEW OLD AS OLD 
FOR EACH ROW
BEGIN 
IF :NEW.BLOQUEAR <> :OLD.BLOQUEAR  THEN 
   :NEW.AD_BLOQPRAZO := :NEW.BLOQUEAR; 
END IF;
IF :NEW.AD_BLOQPRAZO <> :OLD.AD_BLOQPRAZO  THEN 
   :NEW.BLOQUEAR := :NEW.AD_BLOQPRAZO; 
END IF;
END;
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Esses IFs não vão dar verdadeiros nunca se o campo for NULL.

Tem que testar com NVL ou IS NULL:

Selecionar tudo

IF nvl(:NEW.BLOQUEAR, 'x') <> nvl(:OLD.BLOQUEAR, 'x')
...
...
emer_rosa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Sáb, 28 Ago 2010 10:45 am
Localização: Torres-RS
Emerson E. Rosa

Os campos sempre são 'S' ou 'N', o tipo do campo já é esse.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

De qualquer forma... minha sugestão é não usar trigger. É melhor (indispensável na verdade) criar check constraints com a regra e garantir a integridade das colunas. A trigger pode falhar e ser desabilitada, comprometendo os seus dados. A check constraint não falha:

Selecionar tudo

SQL> -- criando tabela -- colunas not null e com domínio por check constraint
SQL> CREATE TABLE TGFPAR (BLOQUEAR     VARCHAR2(1) NOT NULL check (bloquear in ('Y', 'N')),
  2                       AD_BLOQPRAZO VARCHAR2(1) NOT NULL check (ad_bloqprazo in ('Y', 'N')));
 
Table created
SQL> -- garantindo a integridade das colunas por check constraint
SQL> ALTER TABLE tgfpar ADD CONSTRAINT ck_bloquear_igual_ad_bloqprazo
  2        CHECK (bloquear = ad_bloqprazo);
 
Table altered
SQL> -- verificando checks de integridade - vai dar erro
SQL> INSERT INTO tgfpar (bloquear, ad_bloqprazo) values ('S', null);
 
INSERT INTO tgfpar (bloquear, ad_bloqprazo) values ('S', null)
 
ORA-01400: cannot insert NULL into ("CMZA"."TGFPAR"."AD_BLOQPRAZO")
SQL> INSERT INTO tgfpar (bloquear, ad_bloqprazo) values ('S', 'N');
 
INSERT INTO tgfpar (bloquear, ad_bloqprazo) values ('S', 'N')
 
ORA-02290: check constraint (CMZA.CK_BLOQUEAR_IGUAL_AD_BLOQPRAZO) violated
A aplicação deveria estar ciente que só pode inserir valores iguais para as duas colunas. Ela não deveria ser "enganada", ao tentar mexer no valor, ficar na expectativa de ter feito uma modificação, e na realidade ter acontecido outra coisa diferente por baixo dos panos.
emer_rosa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Sáb, 28 Ago 2010 10:45 am
Localização: Torres-RS
Emerson E. Rosa

o Problema é que essa é uma Tabela do ERP eu não posso mexer nela, ou Recriar, excelente solução usar check constraint, mais não tenho como mexer.

Eu já reclamei pois o Campo AD_BLOQUEAR é um Campo Adicional da Tabela, deveriam ter usado na implantação do sistema o Campo NATIVO BLOQEUAR e não o Campo Adicional, segundo o programador que criou o campo Adicional para esta informação teria que ser assim.

Ai meu problema é que os usuarios mudam o campo nativo e não mudam o adicional, ai os Vendedores na rua conseguem digitar Venda a Prazo nos Pedidos e quando o sistema vai importar da erro pois o campo nativo esta marcado para Bloquear a Venda a prazo, então quando mecher em um, teria que mudar o outro, já tentei varios modelos de trigger e não consigo fazer funcionar.

Se alguém tiver uma sugestão melhor eu agradeço.

Abraço a todos.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 4 visitantes