在我的 Oracle 19c 数据库中,我想为每个表创建 1 个触发器,其中处理日志以进行插入、更新和删除。我希望每个表的每个触发器都相同,但名称和表引用除外。这样,我可以添加或更改列,而无需更改触发器。
日志表 _JN 由 OLD_VALUES 和 NEW_VALUES 列组成,可以以 JSON 形式存储在 CLOB 列中。日志信息列(如 sysdate 和 user)应仅添加到从触发器调用的 1 个过程中。这样,如果我想更改记录数据的方式,我只需更改 1 个过程。
我遇到了一些问题: 在我从触发器调用的过程中不能使用 :new 和 :old :new 和 :old 不能在动态 SQL 中使用 我可以使用 USER_TAB_COLUMNS 循环遍历列,但我还没有找到一种方法将 :new-value 传递到 JSON,而无需对列名称进行硬编码。
JSON 应包含列名称和插入的列值。
有人可以帮助我,给我正确的方向吗?
提前致谢, 阿拉德
程序就这么简单。应从放置触发器的所有表调用该过程。
create or replace package body alhi_test_pck is
procedure log( p_operation varchar2
, p_old_value CLOB --JSON
, p_new_value CLOB --JSON
)
is
begin
insert into alhi_test_jn
( operation
, date_modified
, old_value
, new_value
)
values
( p_operation
, sysdate
, p_old_value
, p_new_value
);
end log;
end alhi_test_pck;
您确定要自己执行此操作吗? Oracle 提供通过 Flashback Data Archive/ Flashback Time Travel 自动跟踪表更改的功能。 这比您自己编写触发器的性能要高得多。
您确定要如何存储数据吗? 以 JSON 格式保存历史信息将生成大量数据,查询起来非常困难。 JSON 格式需要比关系数据库更多的空间来存储数据,因为您可能会在每个 JSON 中重复列名。 尝试在日志表上创建足够的 JSON 索引以使审计查询以可接受的速度运行将是一个巨大的挑战。
如果您确实想推出自己的解决方案并且致力于以这种方式存储数据,那么最好的选择是编写一些动态生成触发器定义的代码。 您将在该代码中循环访问
user_tab_columns
,每次在表中添加或删除列时都必须调用该代码,因为实际上您无法在运行时执行此操作。 如果您确实需要,您可以拥有一个 DDL 触发器,该触发器将提交一个作业,该作业将在每次添加列时重新生成触发器。 当然,您必须在生成触发器的代码中嵌入如何将表的一行转换为 JSON 的逻辑。 因此,如果您想更改该逻辑,则需要在一处更改它,然后在所有表上重新生成触发器。