【问题标题】:how to insert data using trigger如何使用触发器插入数据
【发布时间】:2019-08-20 03:24:37
【问题描述】:

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

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:

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

【问题讨论】:

  • user 是保留关键字。不要将其用作列(或表)名称。

标签: sql oracle plsql ddl


【解决方案1】:

好的,所以你得到的错误是因为 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 访问“新”数据,通过 :OLD 访问“旧”数据。

编辑:

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

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

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

不过,这对你来说并不重要。

希望有帮助!

【讨论】:

  • 确实,USER 是保留字。见this
  • @Xaphas 非常感谢您的回答!是的,属性名称有问题
  • @Xaphas,非常感谢您在这个问题上的帮助。因此,在这种情况下,如果触发器将重复记录连同执行插入的 USER 的信息以及插入的日期/时间一起插入到 DEPT_SHADOW 表中,我如何在 MM 中跟踪日期/时间/DD/YY hh:mm:ss 格式?
  • @SteveShi 检查this 日期时间格式。
【解决方案2】:

错误是因为您在dept_shadow 表中使用的列名(user)。 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;
/

希望这对你有用。

【讨论】:

  • 这真的很有道理!非常感谢!
  • @Arif Sher Khan 另一个问题:与@Xaphas 的回答相比,我可以问你们一个问题:为什么你在之后使用,但 Xaphas 在之前使用?
  • 触发器的位置在 SQL Server 数据库的表定义中?
  • @SteveShi 它基本上定义了何时触发触发器。您可以参考link 进行深入了解。
  • @KubaDo 虽然我不确定SQL Server,但我知道它们是单独定义的,而不是在表定义中。
猜你喜欢
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多