plsql触发器自动插入ID

Posted

技术标签:

【中文标题】plsql触发器自动插入ID【英文标题】:plsql trigger to auto insert id's 【发布时间】:2014-04-27 04:08:05 【问题描述】:

所以我是 PL-SQL 的菜鸟,目前正在努力学习它。在阅读有关触发器的内容时​​,我被一个问题打动了:是否可以在插入之前使用触发器来填充插入的列。

前。以经典的员工表为例。假设有人调用 INSERT 并传递所有列的值。这意味着他们为员工 ID 提供了一个值。是否有可能有一个触发器忽略用户作为员工 ID 放置的内容,而是插入下一个增量 ID? IE。如果某人传入的 ID 为 202,但最后给出的 ID 是 173,则触发器会将给定的 ID 更改为 174。

我来自半强编程背景,但我不确定如何更改用户给定员工 ID 的值,因为我们没有明确地将其作为参数传递。

对不起,如果这是一个初学者的问题,但我没有找到谷歌的答案。

【问题讨论】:

这可能已经是关于 SO 的一个涵盖主题,但如果不知道术语,可能不容易找到。作为 Oracle 数据库开发人员,我发布了自己多年来使用的方法... 【参考方案1】:

使用自动增量 PL/SQL 触发器维护唯一键

我使用了流行的 Oracle 默认表,称为“emp”。它以前在较旧的数据库版本中作为 HR schema: SCOTT` 的演示表的化身。

您可以使用带有 Oracle 序列对象的简单 PL/SQL 触发器来完成此任务。我在自己的表格设计中为自己剪切和粘贴的示例如下所示:

CREATE SEQUENCE   "EMP_SEQ"  MINVALUE 1 MAXVALUE 9999999999999999999999999999 
   INCREMENT BY 1 START WITH 8000 CACHE 20 NOORDER  NOCYCLE
/

CREATE OR REPLACE TRIGGER  "EMP_TRG1" 
          before insert on emp
          for each row
          begin
              if :new.empno is null then
                  select emp_seq.nextval into :new.empno from dual;
             end if;
          end;
/
ALTER TRIGGER  "EMP_TRG1" ENABLE
/

对于 PL/SQL 的新手...上面代码中引用的第一个模式对象是 Oracle PL/SQL SEQUENCE 对象。

Oracle PL/SQL 序列对象

开发人员经常依靠这些来保持理智,因为它是独特性的守门人。无论请求来自何处或对该对象进行了多少次同时调用,它都会发出一个序列值恰好一次。创建后尝试一下:

SELECT emp_seq.nextval FROM DUAL;

这里有一些样式选择,因为 Oracle 11gR2 及更高版本已经释放了编码语法中的一些原始限制...

无需使用SELECT INTO... 分配新的序列值。 Oracle 11g 允许直接分配一个序列值,例如:

v_somevar:= emp_seq.nextval;

将此与触发操作相结合是可选的,但它可以让您完成自动分配字段值的完整任务。

使用 Oracle PL/SQL 触发器分配唯一序列 ID

在没有触发器的情况下运行INSERT 命令如下所示:

INSERT INTO emp(empno, ename, job, mgr...)
SELECT emp_seq.nextval, 'XAVIER', 'ANALYST', ...
  FROM dual;

COMMIT;

如果您依赖触发器,则可以完全跳过 empno 值以获取自动分配的序列 ID。

INSERT INTO emp(ename, job, mgr,...)
VALUES ('XAVIER', 'ANALYST', ... );

COMMIT;

或者...

INSERT INTO emp(empno, ename, job, mgr, ...)
VALUES (null, 'XAVIER', 'ANALYST', ...);

COMMIT;

在插入命令中不提及列值与为其分配 NULL 值相同。这就是触发器中包含的 IF-THEN-ELSE 块的含义。

原始请求:

要完成 OP 的功能,您需要重新排列条件块以考虑分配给主键的实际输入值,EMPNO 由针对表发出的INSERT 语句发出。

PL/SQL 触发器编码中的一些内置约定(在插入触发器之前):

使用在插入命令执行之前起作用的代码是正确的选择。这意味着BEFORE INSERT TRIGGER 是您管理自动递增序列分配所需要的。

在触发代码中需要密切注意的值是分配给标记为NEWOLDBEFOREAFTER 触发状态的值.前缀“冒号”(“:”)是语法所必需的。

触发器引用的表中的每一列都可以用:NEW:OLD 表示法作为前缀,如::NEW.empno:NEW.ename

BEFORE INSERT 触发器的情况下,没有:OLD 值。 (请参阅链接参考,或自行搜索)。不应引用或分配它们(:OLD 值)。 :NEW 表示在 INSERT 语句中分配的值,并且可以在执行插入之前在触发器内进一步更改。

【讨论】:

以上是关于plsql触发器自动插入ID的主要内容,如果未能解决你的问题,请参考以下文章

PLSQL 触发器在插入后更新记录

PLSQL 触发器通过 SQL 加载器触发

基于时间plsql的触发器

每行设置 new.column 的 PLSQL 触发器不起作用

SQL记录-PLSQL触发器

如果 Column_X 更新,PLSQL 触发器记录对审计表的更新