Oracle PL/SQL:通用且统一的日志触发器,无需在触发器中硬编码列

问题描述 投票:0回答:1

在我的 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;
sql oracle plsql triggers dynamic-sql
1个回答
0
投票

您确定要自己执行此操作吗? Oracle 提供通过 Flashback Data Archive/ Flashback Time Travel 自动跟踪表更改的功能。 这比您自己编写触发器的性能要高得多。

您确定要如何存储数据吗? 以 JSON 格式保存历史信息将生成大量数据,查询起来非常困难。 JSON 格式需要比关系数据库更多的空间来存储数据,因为您可能会在每个 JSON 中重复列名。 尝试在日志表上创建足够的 JSON 索引以使审计查询以可接受的速度运行将是一个巨大的挑战。

如果您确实想推出自己的解决方案并且致力于以这种方式存储数据,那么最好的选择是编写一些动态生成触发器定义的代码。 您将在该代码中循环访问

user_tab_columns
,每次在表中添加或删除列时都必须调用该代码,因为实际上您无法在运行时执行此操作。 如果您确实需要,您可以拥有一个 DDL 触发器,该触发器将提交一个作业,该作业将在每次添加列时重新生成触发器。 当然,您必须在生成触发器的代码中嵌入如何将表的一行转换为 JSON 的逻辑。 因此,如果您想更改该逻辑,则需要在一处更改它,然后在所有表上重新生成触发器。

© www.soinside.com 2019 - 2024. All rights reserved.