使用自动增量 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 是您管理自动递增序列分配所需要的。
在触发代码中需要密切注意的值是分配给标记为NEW 和OLD 的BEFORE 和AFTER 触发状态的值.前缀“冒号”(“:”)是语法所必需的。
触发器引用的表中的每一列都可以用:NEW 和:OLD 表示法作为前缀,如::NEW.empno 或:NEW.ename。
在BEFORE INSERT 触发器的情况下,没有:OLD 值。 (请参阅链接参考,或自行搜索)。不应引用或分配它们(:OLD 值)。 :NEW 表示在 INSERT 语句中分配的值,并且可以在执行插入之前在触发器内进一步更改。