为视图创建触发器。甲骨文

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

为视图创建一个触发器,在视图所基于的表中的数据第一次更改(UPDATE、DELETE、INSERT、MERGE)时,将使用视图中的信息将 USER 和 TIME 列添加到正在修改的表中正在修改的有关用户和更改时间的行。在后续访问已创建列的表时,触发器必须更正 USER 和 TIME 列中的信息。你只需要创建一个触发器

这是我的解决方案,但是当我在表上使用 UPDATE、DELETE、INSERT 时,不会添加新列。根据任务,需要为视图创建触发器,并操作表

CREATE OR REPLACE TRIGGER audit_changes_trg INSTEAD OF INSERT OR UPDATE OR DELETE ON EMP_VIEWDOP5 DECLARE PRAGMA AUTONOMOUS_TRANSACTION; v_column_exists NUMBER; BEGIN
SELECT COUNT(*)
INTO v_column_exists
FROM user_tab_columns
WHERE table_name = 'EMPLOYEESDOP5'
AND column_name = 'USERAUDIT';

IF v_column_exists = 0 THEN
    EXECUTE IMMEDIATE 'ALTER TABLE EMPLOYEESDOP5 ADD (
        USERaudit VARCHAR2(30),
        TIMEaudit TIMESTAMP)';
END IF;

IF INSERTING THEN
    EXECUTE IMMEDIATE 
    'INSERT INTO EMPLOYEESDOP5 (EMP_ID, EMP_NAME, EMP_SALARY, DEPT_ID, USERaudit, TIMEaudit)
     VALUES (:1, :2, :3, :4, :5, :6)'
    USING :NEW.EMP_ID, :NEW.EMP_NAME, :NEW.EMP_SALARY, :NEW.DEPT_ID, USER, SYSTIMESTAMP;
END IF;

IF UPDATING THEN
    EXECUTE IMMEDIATE 
    'UPDATE EMPLOYEESDOP5 
     SET EMP_NAME = :1, 
         EMP_SALARY = :2, 
         DEPT_ID = :3,
         USERaudit = :4,
         TIMEaudit = :5
     WHERE EMP_ID = :6'
    USING :NEW.EMP_NAME, :NEW.EMP_SALARY, :NEW.DEPT_ID, USER, SYSTIMESTAMP, :OLD.EMP_ID;
END IF;

IF DELETING THEN
    EXECUTE IMMEDIATE 
    'DELETE FROM EMPLOYEESDOP5 WHERE EMP_ID = :1'
    USING :OLD.EMP_ID;
END IF;
END;
sql oracle plsql
1个回答
0
投票

...当我在表上使用 UPDATE、DELETE、INSERT 时,没有添加新列。

你没有解释这是什么意思。添加到哪里?如果您检查了视图,当然不会添加它们,因为视图定义是在触发器第一次运行之前设置的。但是,如果您检查了该表,审核表应该存在。 这是一个基于 Scott 示例架构的演示,其

emp

表。

测试台:

SQL> CREATE TABLE emp_test 2 AS 3 SELECT empno, 4 ename, 5 job, 6 sal 7 FROM emp 8 WHERE deptno = 10; Table created.

基于该表的视图:

SQL> CREATE OR REPLACE VIEW v_emp_test 2 AS 3 SELECT * FROM emp_test; View created.

触发;请注意,它最后需要 
commit

,因为它是一个自治事务:

SQL> CREATE OR REPLACE TRIGGER audit_changes_trg
  2     INSTEAD OF INSERT OR UPDATE OR DELETE
  3     ON v_emp_test
  4  DECLARE
  5     PRAGMA AUTONOMOUS_TRANSACTION;
  6     v_column_exists  NUMBER;
  7  BEGIN
  8     SELECT COUNT (*)
  9       INTO v_column_exists
 10       FROM user_Tab_columns
 11      WHERE     table_name = 'EMP_TEST'
 12            AND column_name = 'USERAUDIT';
 13
 14     IF v_column_exists = 0
 15     THEN
 16        EXECUTE IMMEDIATE 'alter table emp_test add (useraudit varchar2(30), timeaudit date)';
 17     END IF;
 18
 19     IF INSERTING
 20     THEN
 21        EXECUTE IMMEDIATE 'insert into emp_test (empno, ename, job, sal, useraudit, timeaudit)
 22      values (:1, :2, :3, :4, :5, :6)'
 23           USING :new.empno,
 24                 :new.ename,
 25                 :new.job,
 26                 :new.sal,
 27                 USER,
 28                 SYSDATE;
 29     ELSIF UPDATING
 30     THEN
 31        EXECUTE IMMEDIATE 'update emp_test set
 32        ename = :1, job = :2, sal = :3, useraudit = :4, timeaudit = :5
 33        where empno = :6'
 34           USING :new.ename,
 35                 :new.job,
 36                 :new.sal,
 37                 USER,
 38                 SYSDATE,
 39                 :new.empno;
 40     ELSIF DELETING
 41     THEN
 42        EXECUTE IMMEDIATE 'delete from emp_test where empno = :1'
 43           USING :old.empno;
 44     END IF;
 45
 46     COMMIT;
 47  END;
 48  /

Trigger created.

测试:表格内容:

SQL> SELECT * FROM emp_test; EMPNO ENAME JOB SAL ---------- ---------- --------- ---------- 7782 CLARK MANAGER 2450 7839 KING PRESIDENT 5000 7934 MILLER CLERK 1300

查看内容:

SQL> SELECT * FROM v_emp_test; EMPNO ENAME JOB SAL ---------- ---------- --------- ---------- 7782 CLARK MANAGER 2450 7839 KING PRESIDENT 5000 7934 MILLER CLERK 1300

让我们更新一下视图;触发器应该触发并将审核列添加到表
(而不是视图!):

SQL> UPDATE v_emp_test 2 SET sal = 2000 3 WHERE job = 'CLERK'; 1 row updated.

表格新增内容;正如你所看到的,工资已经提高,并且添加了新的栏目:
SQL> SELECT * FROM emp_test;

     EMPNO ENAME      JOB              SAL USERAUDIT                      TIMEAUDIT
---------- ---------- --------- ---------- ------------------------------ -------------------
      7782 CLARK      MANAGER         2450
      7839 KING       PRESIDENT       5000
      7934 MILLER     CLERK           2000 SCOTT                          09.10.2024 08:16:31

风景怎么样?什么都没有(除了反映工资变化的事实之外):
SQL> SELECT * FROM v_emp_test;

     EMPNO ENAME      JOB              SAL
---------- ---------- --------- ----------
      7782 CLARK      MANAGER         2450
      7839 KING       PRESIDENT       5000
      7934 MILLER     CLERK           2000

如果您还想向视图添加新列,则必须
重新创建
视图:

SQL> CREATE OR REPLACE VIEW v_emp_Test 2 AS 3 SELECT * FROM emp_test; View created. SQL> SELECT * FROM v_emp_test; EMPNO ENAME JOB SAL USERAUDIT TIMEAUDIT ---------- ---------- --------- ---------- ------------------------------ ------------------- 7782 CLARK MANAGER 2450 7839 KING PRESIDENT 5000 7934 MILLER CLERK 2000 SCOTT 09.10.2024 08:16:31 SQL>


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