问题描述
嗨,团队,
我必须创建一个触发器,该触发器将在插入的情况下记录旧值和新值。情况是,我有一个应用程序和前端部分,每当发生一些变化,然后xyz_id被改变。在后端,我可以看到插入正在发生。我想在一个历史表中记录旧的xyz_id和新的xyz_id。因此,每当我检查该历史记录表时,我就知道这是旧的xyz_id,并且已更改为新的xyz_id。
请看我正在使用的代码:
当我运行这个代码和在前端应用程序插入发生,然后xyzID_log这个表的输出如下:
Xyz _ id _ 旧xyz _ id _ 新
NULL 7
我希望列xyz_id_old也应该有一个值而不是NULL。
我知道,在插入的情况下,我们只能获得新值,旧值将为NULL。但这是我的任务。
我向你解释一种情况:
让我们假设xyz_ID = 5的值
在应用程序中,每当我做一些事情,比如改变一个程序的时间,它的xyz_ID被从5更改为7。因此,在这种情况下,旧的xyz_ID = 5,新的xyz_ID = 7。检查跟踪文件后,我可以看到这种类型的更改发生了插入。
所以在上面的xyzID_log表,对于列xyz_id_old我想它的值应该显示5不为空。
我不能使用滞后函数,因为
就我而言,情况并非如此。例如:
当有人执行应用程序时,xyz_id上会发生一些插入,下面是值
所以在我的情况下,每当Insert发生时,after_insert值就不会成为before_insert值。这是因为在我们的应用程序中,我们为不同的时间安排了不同的程序。所有程序都有xyz_id。有时插入发生在程序A上,有时发生在程序B上等,因此插入值不同。例如,插入发生在程序A上,然后xyz_id的旧值为20,插入后为30。
一段时间或几天后,程序C上发生了插入,然后xyz_id的旧值为50,插入后为10。
此外,我必须在触发器中实现此功能。我被困住了,无法弄清楚如何实现这一目标。
请引导我。
提前感谢 :)
我必须创建一个触发器,该触发器将在插入的情况下记录旧值和新值。情况是,我有一个应用程序和前端部分,每当发生一些变化,然后xyz_id被改变。在后端,我可以看到插入正在发生。我想在一个历史表中记录旧的xyz_id和新的xyz_id。因此,每当我检查该历史记录表时,我就知道这是旧的xyz_id,并且已更改为新的xyz_id。
请看我正在使用的代码:
CREATE TABLE xyzID_log(
xyz_id_old number(11,0),
xyz_id_new number(11,0)
);
CREATE OR REPLACE PACKAGE audit_PKG AS
PROCEDURE CHECK_VAL( TAB_NAME IN VARCHAR2,COL_NAME IN VARCHAR2, NEW_VAL IN VARCHAR2,
OLD_VAL IN VARCHAR2 ) ;
END;
/
CREATE OR REPLACE PACKAGE BODY audit_PKG AS
PROCEDURE CHECK_VAL( TAB_NAME IN VARCHAR2, COL_NAME IN VARCHAR2, NEW_VAL IN VARCHAR2, OLD_VAL IN VARCHAR2 )
IS
BEGIN
IF ( NEW_VAL <> OLD_VAL OR
(NEW_VAL IS NULL AND OLD_VAL IS NOT NULL) OR
(NEW_VAL IS NOT NULL AND OLD_VAL IS NULL) )
THEN
INSERT INTO xyzID_log (xyz_id_old,xyz_id_new)
VALUES (OLD_VAL,NEW_VAL);
END IF;
END;
END audit_PKG;
/
CREATE OR REPLACE TRIGGER xyzAUDTRG_after
AFTER INSERT OR DELETE OR UPDATE ON Department FOR EACH ROW
DECLARE
V_TABLE_NAME VARCHAR2(50);
V_COL_NM VARCHAR2(50);
BEGIN
V_TABLE_NAME:='Department';
V_COL_NM:=xyz_ID;
audit_pkg.check_val('Department', 'xyz_ID', :new.xyz_ID, :old.xyz_ID);
END;
/
当我运行这个代码和在前端应用程序插入发生,然后xyzID_log这个表的输出如下:
Xyz _ id _ 旧xyz _ id _ 新
NULL 7
我希望列xyz_id_old也应该有一个值而不是NULL。
我知道,在插入的情况下,我们只能获得新值,旧值将为NULL。但这是我的任务。
我向你解释一种情况:
让我们假设xyz_ID = 5的值
在应用程序中,每当我做一些事情,比如改变一个程序的时间,它的xyz_ID被从5更改为7。因此,在这种情况下,旧的xyz_ID = 5,新的xyz_ID = 7。检查跟踪文件后,我可以看到这种类型的更改发生了插入。
所以在上面的xyzID_log表,对于列xyz_id_old我想它的值应该显示5不为空。
我不能使用滞后函数,因为
就我而言,情况并非如此。例如:
当有人执行应用程序时,xyz_id上会发生一些插入,下面是值
Before_Insert_xyz_id After_insert_xyz_id Date 20 30 18 Apr 50 10 19 Apr 40 15 21 Apr
所以在我的情况下,每当Insert发生时,after_insert值就不会成为before_insert值。这是因为在我们的应用程序中,我们为不同的时间安排了不同的程序。所有程序都有xyz_id。有时插入发生在程序A上,有时发生在程序B上等,因此插入值不同。例如,插入发生在程序A上,然后xyz_id的旧值为20,插入后为30。
一段时间或几天后,程序C上发生了插入,然后xyz_id的旧值为50,插入后为10。
此外,我必须在触发器中实现此功能。我被困住了,无法弄清楚如何实现这一目标。
请引导我。
提前感谢 :)
专家解答
让我强调一下...对于 * 每个 * 插入,: old值为null,因为 * 没有 * old行。
您在触发器中拥有的唯一信息是:
插入-仅新增
更新-旧的和新的
仅删除旧
这是可能的,你的前端应用程序 * 重新解释 * 什么用户 * 感知 * 正在发生,例如,屏幕可能表明一个值正在 “更新”,但代码可能正在做删除-然后-插入来实现它。或者它可能会标记现有记录是 “不再被看到” (通过应用程序),然后插入一个新的 “活动” 记录等。
但是在数据库级别,* 永远不会 * 插入一个旧值-因为它是正在创建的 * 新 * 记录。
您需要将应用程序正在做的事情映射到数据库正在做的事情,以便正确地呈现审计跟踪。
您在触发器中拥有的唯一信息是:
插入-仅新增
更新-旧的和新的
仅删除旧
这是可能的,你的前端应用程序 * 重新解释 * 什么用户 * 感知 * 正在发生,例如,屏幕可能表明一个值正在 “更新”,但代码可能正在做删除-然后-插入来实现它。或者它可能会标记现有记录是 “不再被看到” (通过应用程序),然后插入一个新的 “活动” 记录等。
但是在数据库级别,* 永远不会 * 插入一个旧值-因为它是正在创建的 * 新 * 记录。
您需要将应用程序正在做的事情映射到数据库正在做的事情,以便正确地呈现审计跟踪。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




