我在工作中遇到了一个问题,这个问题已经困扰了服务部门几个星期了。我已经写了一个触发器,试图抓住起源或一个错误。但这就像大海捞针
有没有办法在var中包含DML事务,以便我可以看到激活触发器的实际事务?
就像想象一下:
CREATE OR REPLACE TRIGGER SYSADM.WOW_TRIGGER
AFTER UPDATE
ON SYSADM.TABLE1 REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
WHEN (
NEW.COLUMN1 is null and new.COLUMN2 is not null and NEW.COLUMN in ('A','B')
)
DECLARE
[...]
V_catch clob;
begin
[...]
end;
===>如何在V_catch中注册此事务:update table1 set column2 = "WHATEVER" where COLUMN15555 = 1
在客户点击软件后发生了什么?
我试着在它上面做一些讨厌的工作,在每一列上写自定义if条件,试图得到改变的值:
if :NEW.column1 is not null then
v_catch := v_catch || :NEW.column1;
end if;
if :NEW.column2 is not null then
v_catch := v_catch || :NEW.column2;
end if;
[...]
这实际上并不像我们预期的那样工作,因为我们经常收到bug的通知,在报告中,v_catch返回的是非贵重值,而bug仍然无法定位。
我很确定有一种方法可以做到这一点,但我仍然是一个初学者,在PLSQL和SQL for Oracle中自学。也许我忽略了什么,也许这是唯一存在的方法。有哪位老前辈能帮我解决这个问题吗?
1条答案
按热度按时间ca1c2owp1#
审计绝对是正确的答案。但是,如果您有一个使用审计的限制,那么触发器是您的下一个最佳选择。
问题是,除了DDL/系统事件触发器或细粒度审计(分别可以使用
original_sql_txt
和SYS_CONTEXT('USERENV','CURRENT_SQL')
)之外,我认为不可能以干净的方式在DML触发器中获得触发SQL。虽然您认为可以查询v$session.sql_id
,但这样做的查询将用它本身替换它。然而,这里有一个可以接近的黑客,通过查看会话打开的游标以及在过去一秒内活动的游标。它可能返回多行,但其中只有一行是正确的SQL。另外,为了减少结果,假设DML将命名表(而不是通过视图或同义词)。您可能需要更改
dbms_output
以插入到日志表中沿着提供有用的会话标识信息。显然,这是粗略的,可以调整,但它给出了基本的想法。