如何知道 Oracle 中更新、删除或插入了哪些记录

发布于 2024-11-10 13:47:33 字数 1178 浏览 0 评论 0原文

我正在做一个 LogTable,其中保存在 RealTable 上修改的数据。

我所说的数据是指我需要恢复整个记录的 :new:old 值。所以我有一个触发器,可以对是否有插入、删除或更新做出反应。

所以我的问题是:我如何知道哪条记录被更改以及如何恢复其内容?

示例:

create table t1(
    a integer,
    b integer
)

create table LogT1(
    new_a integer, 
    old_a integer,
    new_b integer,
    old_b integer
)

假设 t1 上有一条记录,其值为 a=1、b=2,并且 t1 获得更新,因此该记录将值更改为 a=3、b=4

因此该更新会激活触发器,并且它必须

  1. :记录被修改。
  2. 恢复该记录。
  3. 获取“之前”和“之后”的 an 和 b 值
  4. 将这些值作为 old_a、new_a、old_b、new_b 插入 LogT1,

结果作为 LogT1 上的插入,值 new_a=3、old_a=1、new_b=4、old_b=2

CREATE or REPLACE TRIGGER tr001
  AFTER INSERT OR UPDATE OR DELETE ON t1

DECLARE

    a integer;
    b integer;
    a2 integer;
    b2 integer;

BEGIN

    IF DELETING THEN 

        *Recover the row that changed* 

        *Then use that row*
        a2:= :new.a ;
        b2:= :new.b ;
        a:= :old.a ;
        b:= :old.b ;
        insert into LogT1 (new_a integer, old_a integer, new_b integer, old_b integer) 
values (a2,a,b2,b);

    END IF;

....

END tr001;

我是新手,所以如果我的问题不恰当,我表示最诚挚的歉意。

I'm doing a LogTable, where I save the data that was modified on the RealTable.

By data I mean that I need to recover the whole record's :new and :old values. So I have a trigger that reacts whether there's an insert, delete or update.

So my question is: How do I know which record was changed and how do I recover it's contents?

example:

create table t1(
    a integer,
    b integer
)

create table LogT1(
    new_a integer, 
    old_a integer,
    new_b integer,
    old_b integer
)

Let's say there's a record on t1 with the values a=1, b=2 and t1 gets an update so the record changes the values to a=3, b=4

So that update activates the trigger and it must:

  1. Know which record was modified.
  2. Recover that record.
  3. Get the "before" and "after" an and b values
  4. Insert those values into LogT1 as old_a, new_a, old_b, new_b

resulting as an insert on LogT1 with the values new_a=3, old_a=1, new_b=4, old_b=2

CREATE or REPLACE TRIGGER tr001
  AFTER INSERT OR UPDATE OR DELETE ON t1

DECLARE

    a integer;
    b integer;
    a2 integer;
    b2 integer;

BEGIN

    IF DELETING THEN 

        *Recover the row that changed* 

        *Then use that row*
        a2:= :new.a ;
        b2:= :new.b ;
        a:= :old.a ;
        b:= :old.b ;
        insert into LogT1 (new_a integer, old_a integer, new_b integer, old_b integer) 
values (a2,a,b2,b);

    END IF;

....

END tr001;

I'm new at this so my most sincere apology if my question is not proper.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

墨小沫ゞ 2024-11-17 13:47:33

据我记得,您可以将触发器声明为 FOR EACH ROW ,以便为删除|插入|更新的每一行触发它,然后 :new 和 :old 包含特定的行值。希望这有帮助。

CREATE or REPLACE TRIGGER tr001 
  AFTER INSERT OR UPDATE OR DELETE 
  ON t1
  FOR EACH ROW
DECLARE
...

As far as I remember you might declare the trigger as FOR EACH ROW so that it is fired for each row that is deleted|inserted|updated, then the :new and :old contain the specific row values. Hope this helps.

CREATE or REPLACE TRIGGER tr001 
  AFTER INSERT OR UPDATE OR DELETE 
  ON t1
  FOR EACH ROW
DECLARE
...
赠意 2024-11-17 13:47:33

如果您有 11g,则可以使用 闪回数据存档 为此,

If you have 11g, you can use Flashback Data Archive to do this,

权谋诡计 2024-11-17 13:47:33

这是我在项目中使用的一些 PL/SQL,几乎可以完成您想要的事情。

我简化了我的脚本(它正在执行一些其他功能):

create or replace trigger rtt.course_log
       after insert or update or delete
       on rtt.TRAINING_COURSE
       for each row

declare msg varchar2(255);

begin
        if updating then
           msg := 'updating course: ' ||  :new.name || 'at: ' || :new.updated_at;
        elsif inserting then
           msg := 'creating course: ' ||  :new.name || 'at: ' || :new.updated_at;
        elsif deleting then
           msg := 'deleting course: ' ||  :new.name || 'at: ' || :new.updated_at;
        end if;
        insert into rtt.TRAINING_LOG (message, created_at) values (msg, SYSDATE);
end;

This is some PL/SQL I use in a project to do pretty much the exact thing you want.

I've simplified my script (it was doing some other functionality):

create or replace trigger rtt.course_log
       after insert or update or delete
       on rtt.TRAINING_COURSE
       for each row

declare msg varchar2(255);

begin
        if updating then
           msg := 'updating course: ' ||  :new.name || 'at: ' || :new.updated_at;
        elsif inserting then
           msg := 'creating course: ' ||  :new.name || 'at: ' || :new.updated_at;
        elsif deleting then
           msg := 'deleting course: ' ||  :new.name || 'at: ' || :new.updated_at;
        end if;
        insert into rtt.TRAINING_LOG (message, created_at) values (msg, SYSDATE);
end;
献世佛 2024-11-17 13:47:33

实际上,如果您知道所需数据的时间,则可以恢复旧数据,而无需使用以下查询创建日志表。它可能会满足您的要求。

SELECT * FROM TABLE_NAME AS OF TIMESTAMP

(提供所需记录的时间作为时间戳)

Actually you can recover the old data, if you know the time at which the data required, without creating the log table using following query. It may satisfy your requirement.

SELECT * FROM TABLE_NAME AS OF TIMESTAMP

(Provide the time at which time the records required as the timestamp)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文