Sql 如何使用触发器插入数据

Sql 如何使用触发器插入数据,sql,oracle,plsql,ddl,Sql,Oracle,Plsql,Ddl,我有一个关于使用触发器插入数据的问题,例如,我有两个表,第二个表有属性和表中的记录,除了另外两个属性,如下所示: 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),

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

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)
);
我想创建一个触发器来跟踪表中的所有插入

令人惊讶的是,我在创建表时出错:

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
。尝试使用
USERNAME
USERDESCRIPTION
或类似的方法

现在是触发器:

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
访问“新”数据,通过
:old
访问“旧”数据

编辑:

触发器之前的
和之后的
的区别在于它们在执行时都有有效的用途

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

AFTER
触发器可用于在插入后验证新数据。因此,例如,如果要删除列x中现在值为0的所有行

但这对你来说并不重要


希望有帮助

该错误是由于您在
部门阴影
表中使用的列名(
user
)造成的。 用户是预定义的,这就是为什么它不能作为表中的列名使用。将其重命名为“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;
/

希望这对您有用。

事实上,
USER
是一个保留字。看。@Xapas非常感谢你的回答!是属性的名称是problem@Xaphas,非常感谢您在这个问题上的帮助。因此,在这种情况下,如果触发器在DEPT_SHADOW表中插入一条重复的记录,以及执行插入的用户的信息,以及插入的日期/时间,那么我如何以MM/DD/YY hh:MM:ss格式跟踪日期/时间?@SteveShi检查datetime格式。这真的很有意义!非常感谢你!@Arif Sher Khan另一个问题:与@Xaphas的答案相比,我可以问你们关于这个问题的问题:为什么你们使用after,而Xaphas使用before?触发器的位置在SQL server数据库的表定义中?@SteveShi它基本上定义了触发的时间。您可以深入参考。@KubaDo虽然我不确定SQL Server,但我知道它们是单独定义的,不在表定义中。
user
是保留关键字。不要将其用作列(或表)名称。