如何使用触发器插入数据

how to insert data using trigger

我有关于使用触发器插入数据的问题,例如,我有两个 table,第二个 table 有属性和记录 table,除了另外两个属性,如下所示:

CREATE TABLE dept
( 
    DEPTNO NUMBER(3) PRIMARY KEY,
    DNAME VARCHAR2(16),
    LOC VARCHAR2(16) 
);

CREATE TABLE dept_shadow
( 
    DEPTNO  NUMBER(3) PRIMARY KEY,
    DNAME   VARCHAR2(16),
    LOC     VARCHAR2(16),
    USER    VARCHAR2(32),
    MODTIME CHAR(17)
);

我想创建一个触发器来跟踪 table.

中的所有插入

令人惊讶的是,我在创建 table 时遇到错误:

Error starting at line : 11 in command -
CREATE TABLE dept_shadow
( 
    DEPTNO  NUMBER(3) PRIMARY KEY,
    DNAME   VARCHAR2(16),
    LOC     VARCHAR2(16),
    USER    VARCHAR2(32),
    MODTIME CHAR(17)
)
Error report -
ORA-00904: : invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:

我不知道这个错误,有谁能告诉我如何通过创建触发器来完成这项工作吗?由于没有要插入的实际记录!任何建议表示赞赏

好的,所以你得到的错误是因为 oracle(像所有数据库一样)有一些保留字。现在我不是 100% 确定,因为我不倾向于经常使用 Oracle DB,但我认为您不能出于这个原因使用 USER 这个词。尝试使用 USERNAMEUSERDESCRIPTION 或类似的东西。

现在触发:

CREATE OR REPLACE TRIGGER trg_shadow
   BEFORE INSERT OR UPDATE OR DELETE
   ON dept_shadow
   REFERENCING NEW AS NEW OLD AS OLD
   FOR EACH ROW
DECLARE
   MODTIME   char (17);
BEGIN
   IF INSERTING
   THEN
      -- do something
   ELSIF UPDATING
   THEN
      -- do something
   ELSIF DELETING
   THEN
      -- do something
   END IF;

从那里,您可以通过 :NEW 访问 "new" 数据,通过 :OLD.

访问 "old" 数据

编辑:

BEFOREAFTER 触发器的区别在于它们何时被执行并且都具有有效用途。

BEFORE 触发器可用于在插入或更新之前验证数据。因此,例如,如果您不想更新 x 列中值为 0 的行。

AFTER 触发器可用于在插入后验证新数据。因此,例如,如果您要删除列 x.

中现在值为 0 的所有行

虽然你的情况并不重要。

希望对您有所帮助!

错误是因为您在 dept_shadow table 中使用的列名 (user)。 USER 是预定义的,这就是为什么它不能作为 table 中的列名。将其重命名为 'audit_user' 或您想要的任何名称,这不是关键字。它将无缝运行。

并为触发器

CREATE OR REPLACE TRIGGER dept_trigger
AFTER INSERT
   ON dept
   FOR EACH ROW

DECLARE
   v_username varchar2(10);

BEGIN
   -- Find username of person performing the INSERT into the table
   SELECT user INTO v_username
   FROM dual;

   -- Insert record into shadow table
   INSERT INTO dept_shadow
   ( DEPTNO,
     DNAME,
     LOC,
     AUDIT_USER,
     MODTIME )
   VALUES
   ( :new.DEPTNO,
     :new.DNAME,
     :new.LOC,
     v_username, 
     :new.MODTIME
   );
END;
/

希望这对你有用。