问题描述
嗨,团队,
我必须创建一个触发器,该触发器将在插入的情况下记录旧值和新值。情况是,我有一个应用程序和前端部分,每当发生一些变化,然后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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle DataGuard高可用性解决方案详解
孙莹
427次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
388次阅读
2025-04-15 17:24:06
墨天轮个人数说知识点合集
JiekeXu
365次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
358次阅读
2025-04-08 09:12:48
Oracle SQL 执行计划分析与优化指南
Digital Observer
330次阅读
2025-04-01 11:08:44
Oracle 19c RAC更换IP实战,运维必看!
szrsu
296次阅读
2025-04-08 23:57:08
风口浪尖!诚通证券扩容采购Oracle 793万...
Roger的数据库专栏
293次阅读
2025-03-24 09:42:53
切换Oracle归档路径后,不能正常删除原归档路径上的归档文件
dbaking
288次阅读
2025-03-19 14:41:51
oracle定时任务常用攻略
virvle
286次阅读
2025-03-25 16:05:19
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
281次阅读
2025-04-15 14:48:05