无法使用触发器审核表- Oracle数据库

cvxl0en2  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(114)

目标

我想在表Users上创建一个触发器audit_users,它在表users_audit中存储更改操作、旧数据和新数据。

Schemas目录

create table Users (
    username varchar2(30) not null constraint users_pk primary key,
    first_name varchar2(30) not null,
    last_name varchar2(30),
    age number not null
);
CREATE TABLE users_audit (
    new_first_name varchar2(30),
    old_first_name varchar2(30),
    new_last_name varchar2(30),
    old_last_name varchar2(30),
    new_age NUMBER,
    old_age NUMBER,
    action varchar2(30)
);

触发器

成功创建以下触发器

CREATE OR REPLACE TRIGGER audit_users
BEFORE INSERT OR DELETE OR UPDATE ON Users
FOR EACH ROW
BEGIN
    IF INSERTING THEN
        INSERT INTO users_audit VALUES(
            :NEW.first_name, NULL, 
            :NEW.last_name, NULL,
            :NEW.age, NULL,
            'insert'
        );
    ELSIF UPDATING THEN
        INSERT INTO users_audit VALUES(
            :NEW.first_name, :OLD.first_name, 
            :NEW.last_name, :OLD.last_name,
            :NEW.age, :OLD.age,
            'update'
        );
    ELSIF DELETING THEN
        INSERT INTO users_audit VALUES(
            NULL, :OLD.first_name, 
            NULL, :OLD.last_name,
            NULL, :OLD.age,
            'delete'
        );
    END IF;
END;
/

[ERROR]正在执行操作

我尝试运行以下代码

INSERT INTO Users VALUES ('jackie', 'Jackie', 'Chan', 60);
UPDATE Users SET age = 61 WHERE username = 'jackie';
DELETE FROM Users WHERE username = 'jackie';

但是对于每个DML状态,

ORA-04098: trigger 'SQL_HMENLXODFUUNAEXBEDJCPFQUV.USERS_AUDIT' is invalid and failed re-validation

环境

实时SQL(耶!对不起,我才刚开始学)

TL;DR

尝试

  • 创建一个触发器,该触发器在表users_audit中输入表users上的审计数据
  • 运行DML语句

预期

  • 在表格users_audit中创建新条目

实际结果

  • 收到错误信息
r1wp621o

r1wp621o1#

为了使事情更清楚一点,您可能需要考虑删除审计表中的旧列,并使用一个操作标志(I= UPDATE,U=UPDATE,D= UPDATE)。请参见下文。

ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';

create table Users ( 
 username varchar2(30) not null constraint users_pk primary key,
 first_name varchar2(30) not null,
 last_name varchar2(30), 
 age number not null
 );

CREATE TABLE  users_audit
(   
    aud_who VARCHAR2 (30),
    aud_when DATE,
    aud_operation VARCHAR2(1),  
    username varchar2(30),
    first_name varchar2(30),
    last_name varchar2(30), 
    age number
    );
/

create or replace
   trigger users_aud_trg
    after insert or update or delete on users 
    for each row
    declare
      l_operation varchar2(1) :=
          case when updating then 'U'
               when deleting then 'D'
               else 'I' end;
   begin
     if updating or inserting then
         insert into users_audit
           (aud_who,
           aud_when,
           aud_operation,
            username,
            first_name,
            last_name,
            age)
         values    (sys_context('USERENV', 'OS_USER'),
           sysdate,
           l_operation,            
         :new.username,                             
         :new.first_name,
         :new.last_name,
         :new.age );
     else
         insert into users_audit
           (aud_who,
           aud_when,
           aud_operation, 
            username,
            first_name,
            last_name,
            age)
         values  (sys_context('USERENV', 'OS_USER'),
           sysdate,
           l_operation,             
          :old.username,
          :old.first_name,
          :old.last_name,
          :old.age);
     end if;
  end
users_aud_trg;
/

INSERT INTO USERS VALUES('ME', 'John', 'Doe', 37);
     
UPDATE USERS SET AGE=40;

DELETE USERS WHERE USERNAME ='ME';

SELECT * FROM users_audit;

相关问题