trigger parametros
Boa tarde galera,
Estou com um problema, alguém pode ajudar?
Preciso criar uma trigger que vai fazer atualização em uma linha de uma tabela toda vez que tiver um insert ou update.
O problema é que tenho que usar informações dessa mesma linha para gerar o select com o calculo para da update no campo.
Já vi que não é possível passar um parâmetro para trigger.
Estou com um problema, alguém pode ajudar?
Preciso criar uma trigger que vai fazer atualização em uma linha de uma tabela toda vez que tiver um insert ou update.
O problema é que tenho que usar informações dessa mesma linha para gerar o select com o calculo para da update no campo.
Já vi que não é possível passar um parâmetro para trigger.
Eduardo Silva
Curtidas 0
Respostas
Deivison Melo
20/08/2013
uma TRIGGER para que antes de deletar, inserir ou atualizar
fazer linha a linha a verificação e de acordo com o a
operação fazer alguma coisa:
CREATE OR REPLACE TRIGGER three_for_the_price_of_one
BEFORE DELETE OR INSERT OR UPDATE ON account_transaction
FOR EACH ROW
BEGIN
-- track who created the new row
IF INSERTING
THEN
:NEW.created_by := USER;
:NEW.created_date := SYSDATE;
-- track deletion with special audit program
ELSIF DELETING
THEN
audit_deletion(USER,SYSDATE);
-- track who last updated the row
ELSIF UPDATING
THEN
:NEW.UPDATED_BY := USER;
:NEW.UPDATED_DATE := SYSDATE;
END IF;
END;
Posta seu objeto e explica detalhadamente o que deseja, dentro de trigger podemos usar várias situações:
Chamadas para procedures, Jobs, criação de tabelas, usar cursores e etc...
Qualquer dúvida estou à disposição!!!
fazer linha a linha a verificação e de acordo com o a
operação fazer alguma coisa:
CREATE OR REPLACE TRIGGER three_for_the_price_of_one
BEFORE DELETE OR INSERT OR UPDATE ON account_transaction
FOR EACH ROW
BEGIN
-- track who created the new row
IF INSERTING
THEN
:NEW.created_by := USER;
:NEW.created_date := SYSDATE;
-- track deletion with special audit program
ELSIF DELETING
THEN
audit_deletion(USER,SYSDATE);
-- track who last updated the row
ELSIF UPDATING
THEN
:NEW.UPDATED_BY := USER;
:NEW.UPDATED_DATE := SYSDATE;
END IF;
END;
Posta seu objeto e explica detalhadamente o que deseja, dentro de trigger podemos usar várias situações:
Chamadas para procedures, Jobs, criação de tabelas, usar cursores e etc...
Qualquer dúvida estou à disposição!!!
GOSTEI 0
Eduardo Silva
20/08/2013
Opá, tudo bem...
o código é esse:
CREATE OR REPLACE TRIGGER tracumuladomesesanteriores
after INSERT OR UPDATE OF valor_acumulado_12_meses_antes,valor_acumulado_6_meses_antes, valor_acumulado_3_meses_antes ON VALOR
declare
vlr_acumulado_12_meses number;
vlr_acumulado_6_meses NUMBER;
vlr_acumulado_3_meses NUMBER;
BEGIN
SELECT
(SELECT Sum(TRUNC(valvalor,2)) FROM valor vp WHERE vp.valdata
BETWEEN ADD_MONTHS( val.valdata,-11)
AND val.valdata AND sk_metadados = psk_metadados)
,
(SELECT Sum(TRUNC(valvalor,2)) FROM valor vp WHERE vp.valdata
BETWEEN ADD_MONTHS( val.valdata,-5)
AND val.valdata AND sk_metadados = psk_metadados)
,
(SELECT Sum(TRUNC(valvalor,2)) FROM valor vp WHERE vp.valdata
BETWEEN ADD_MONTHS( val.valdata,-2)
AND val.valdata AND sk_metadados = psk_metadados)
INTO vlr_acumulado_12_meses, vlr_acumulado_6_meses,vlr_acumulado_3_meses
FROM valor val
where sk_metadados = NEW.SK_METADADOS;
update valor set valor_acumulado_12_meses_antes = vlr_acumulado_12_meses ,
valor_acumulado_6_meses_antes = vlr_acumulado_6_meses,
valor_acumulado_3_meses_antes = vlr_acumulado_3_meses
where valdata=NEW.VALDATA AND
sk_metadados = NEW.SK_METADADOS AND
sk_territorio = NEW.SK_TERRITORIO;
commit;
END;
/
o código é esse:
CREATE OR REPLACE TRIGGER tracumuladomesesanteriores
after INSERT OR UPDATE OF valor_acumulado_12_meses_antes,valor_acumulado_6_meses_antes, valor_acumulado_3_meses_antes ON VALOR
declare
vlr_acumulado_12_meses number;
vlr_acumulado_6_meses NUMBER;
vlr_acumulado_3_meses NUMBER;
BEGIN
SELECT
(SELECT Sum(TRUNC(valvalor,2)) FROM valor vp WHERE vp.valdata
BETWEEN ADD_MONTHS( val.valdata,-11)
AND val.valdata AND sk_metadados = psk_metadados)
,
(SELECT Sum(TRUNC(valvalor,2)) FROM valor vp WHERE vp.valdata
BETWEEN ADD_MONTHS( val.valdata,-5)
AND val.valdata AND sk_metadados = psk_metadados)
,
(SELECT Sum(TRUNC(valvalor,2)) FROM valor vp WHERE vp.valdata
BETWEEN ADD_MONTHS( val.valdata,-2)
AND val.valdata AND sk_metadados = psk_metadados)
INTO vlr_acumulado_12_meses, vlr_acumulado_6_meses,vlr_acumulado_3_meses
FROM valor val
where sk_metadados = NEW.SK_METADADOS;
update valor set valor_acumulado_12_meses_antes = vlr_acumulado_12_meses ,
valor_acumulado_6_meses_antes = vlr_acumulado_6_meses,
valor_acumulado_3_meses_antes = vlr_acumulado_3_meses
where valdata=NEW.VALDATA AND
sk_metadados = NEW.SK_METADADOS AND
sk_territorio = NEW.SK_TERRITORIO;
commit;
END;
/
GOSTEI 0
Deivison Melo
20/08/2013
Muito cuidado com trigger...
Evite trigger mutating... (Tarefa de casa de hoje: Pesquisar sobre trigger mutating)
Abaixo segue um outro exemplo:
CREATE OR REPLACE TRIGGER instructor_aud
AFTER UPDATE OR DELETE ON INSTRUCTOR
DECLARE
v_type VARCHAR2(10);
BEGIN
IF UPDATING THEN
v_type := 'UPDATE';
ELSIF DELETING THEN
v_type := 'DELETE';
END IF;
UPDATE statistics
SET transaction_user = USER,
transaction_date = SYSDATE
WHERE table_name = 'INSTRUCTOR'
AND transaction_name = v_type;
IF SQL%NOTFOUND THEN
INSERT INTO statistics
VALUES ('INSTRUCTOR', v_type, USER, SYSDATE);
END IF;
END;
Abração e bons códigos!!!
Evite trigger mutating... (Tarefa de casa de hoje: Pesquisar sobre trigger mutating)
Abaixo segue um outro exemplo:
CREATE OR REPLACE TRIGGER instructor_aud
AFTER UPDATE OR DELETE ON INSTRUCTOR
DECLARE
v_type VARCHAR2(10);
BEGIN
IF UPDATING THEN
v_type := 'UPDATE';
ELSIF DELETING THEN
v_type := 'DELETE';
END IF;
UPDATE statistics
SET transaction_user = USER,
transaction_date = SYSDATE
WHERE table_name = 'INSTRUCTOR'
AND transaction_name = v_type;
IF SQL%NOTFOUND THEN
INSERT INTO statistics
VALUES ('INSTRUCTOR', v_type, USER, SYSDATE);
END IF;
END;
Abração e bons códigos!!!
GOSTEI 0
Deivison Melo
20/08/2013
Vou modificar sua trigger e enviar novamente!
PS. Por favor, remover o commit das trigger, nas triggers não há necessidade, vc já está "deitado" no banco...
PS. Por favor, remover o commit das trigger, nas triggers não há necessidade, vc já está "deitado" no banco...
GOSTEI 0
Deivison Melo
20/08/2013
Sua trigger rodou??? rsrsrs
Veja o código abaixo:
CREATE OR REPLACE TRIGGER tracumuladomesesanteriores
after INSERT OR UPDATE OF valor_acumulado_12_meses_antes,
valor_acumulado_6_meses_antes,
valor_acumulado_3_meses_antes ON VALOR
declare
cursor cQuery(Psk_metadados in varchar2) is
select
(select sum(trunc(valvalor,2)) from valor vp where vp.valdata
between add_months( val.valdata,-11)
and val.valdata and sk_metadados = psk_metadados)
,
(select sum(trunc(valvalor,2)) from valor vp where vp.valdata
between add_months( val.valdata,-5)
and val.valdata and sk_metadados = psk_metadados)
,
(select sum(trunc(valvalor,2)) from valor vp where vp.valdata
between add_months( val.valdata,-2)
and val.valdata and sk_metadados = psk_metadados);
vlr_acumulado_12_meses number;
vlr_acumulado_6_meses number;
vlr_acumulado_3_meses number;
BEGIN
open cQuery(new.sk_metadados);
fetch cQuery into vlr_acumulado_12_meses, vlr_acumulado_6_meses,vlr_acumulado_3_meses
close cQuery
update valor
set valor_acumulado_12_meses_antes = vlr_acumulado_12_meses ,
valor_acumulado_6_meses_antes = vlr_acumulado_6_meses,
valor_acumulado_3_meses_antes = vlr_acumulado_3_meses
where valdata = NEW.VALDATA
and sk_metadados = NEW.SK_METADADOS
and sk_territorio = NEW.SK_TERRITORIO;
-- commit; -- isso não é permitido dá erro e/ou problemas na transação!!
END;
/
Não testei peguei sua query e coloquei em um cursor, pois no cursor ele já trata as informações que vierem nulas e o select into vc não fez isso!!!
Sempre que for tratar alguma exceção no oracle use:
DECLARE
--declarações
BEGIN
--bloco de código
EXCEPTION
WHEN Others THEN
-- aqui tudo q for exceção
Raise_Application_Error(-20999,'Erro genérico');
END;
Veja o código abaixo:
CREATE OR REPLACE TRIGGER tracumuladomesesanteriores
after INSERT OR UPDATE OF valor_acumulado_12_meses_antes,
valor_acumulado_6_meses_antes,
valor_acumulado_3_meses_antes ON VALOR
declare
cursor cQuery(Psk_metadados in varchar2) is
select
(select sum(trunc(valvalor,2)) from valor vp where vp.valdata
between add_months( val.valdata,-11)
and val.valdata and sk_metadados = psk_metadados)
,
(select sum(trunc(valvalor,2)) from valor vp where vp.valdata
between add_months( val.valdata,-5)
and val.valdata and sk_metadados = psk_metadados)
,
(select sum(trunc(valvalor,2)) from valor vp where vp.valdata
between add_months( val.valdata,-2)
and val.valdata and sk_metadados = psk_metadados);
vlr_acumulado_12_meses number;
vlr_acumulado_6_meses number;
vlr_acumulado_3_meses number;
BEGIN
open cQuery(new.sk_metadados);
fetch cQuery into vlr_acumulado_12_meses, vlr_acumulado_6_meses,vlr_acumulado_3_meses
close cQuery
update valor
set valor_acumulado_12_meses_antes = vlr_acumulado_12_meses ,
valor_acumulado_6_meses_antes = vlr_acumulado_6_meses,
valor_acumulado_3_meses_antes = vlr_acumulado_3_meses
where valdata = NEW.VALDATA
and sk_metadados = NEW.SK_METADADOS
and sk_territorio = NEW.SK_TERRITORIO;
-- commit; -- isso não é permitido dá erro e/ou problemas na transação!!
END;
/
Não testei peguei sua query e coloquei em um cursor, pois no cursor ele já trata as informações que vierem nulas e o select into vc não fez isso!!!
Sempre que for tratar alguma exceção no oracle use:
DECLARE
--declarações
BEGIN
--bloco de código
EXCEPTION
WHEN Others THEN
-- aqui tudo q for exceção
Raise_Application_Error(-20999,'Erro genérico');
END;
GOSTEI 0
Deivison Melo
20/08/2013
Vou lançar um curso de PL/SQL e boas práticas de programação usando essa linguagem!
Já estou acertando com o pessoal!
Já estou acertando com o pessoal!
GOSTEI 0
Eduardo Silva
20/08/2013
Deivison, muito obrigado pela ajuda.... agora está apresentando o seguinte erro:
"Line";"Pos";"Text"
1;;Create trigger, executed in 84 ms
24;56;"PL/SQL: ORA-00904: ""NEW"".""VALDATA"": invalid identifier"
10;1;PL/SQL: SQL Statement ignored
33;13;PLS-00201: identifier 'NEW.SK_METADADOS' must be declared
33;1;PL/SQL: SQL Statement ignored
43;21;"PL/SQL: ORA-00904: ""NEW"".""SK_TERRITORIO"": invalid identifier"
37;1;PL/SQL: SQL Statement ignored
;;Total execution time 88 ms
"Line";"Pos";"Text"
1;;Create trigger, executed in 84 ms
24;56;"PL/SQL: ORA-00904: ""NEW"".""VALDATA"": invalid identifier"
10;1;PL/SQL: SQL Statement ignored
33;13;PLS-00201: identifier 'NEW.SK_METADADOS' must be declared
33;1;PL/SQL: SQL Statement ignored
43;21;"PL/SQL: ORA-00904: ""NEW"".""SK_TERRITORIO"": invalid identifier"
37;1;PL/SQL: SQL Statement ignored
;;Total execution time 88 ms
GOSTEI 0
Alessandro Yamasaki
20/08/2013
Deivison, será excelente o curso de PL/SQL.
Eduardo, acredito que faltou o caracter ":" antes da palavra NEW
Eduardo, acredito que faltou o caracter ":" antes da palavra NEW
GOSTEI 0
Deivison Melo
20/08/2013
Eduardo,
O Alessandro está correto, os valores que são referenciados através de New (novo) e Old (anterior ou antigo) deverão serem precedidos de ":".
Qualquer dúvida estou á disposição!
Alessandro que bom que gostou da ideia!
Abração e bons Códigos!!!
O Alessandro está correto, os valores que são referenciados através de New (novo) e Old (anterior ou antigo) deverão serem precedidos de ":".
Qualquer dúvida estou á disposição!
Alessandro que bom que gostou da ideia!
Abração e bons Códigos!!!
GOSTEI 0
Eduardo Silva
20/08/2013
Valeu mesmo, desculpe-me pois sou iniciante...rs
obrigado.
obrigado.
GOSTEI 0