所以我是PL-SQL的小伙子,现在我正在努力学习它。在阅读有关触发器时,我很震惊的问题是,在插入之前是否可以使用触发器来填充插入的列。
EX。以经典员工表为例。假设有人调用INSERT并传递所有列的值。这意味着它们为员工ID提供了值。是否可以使用一个触发器来忽略用户放置的员工ID,而是插入下一个增量ID? IE浏览器。如果有人传入的ID为202,但最后一个ID为173,则触发器会将给定的ID更改为174。
我来自半强编程背景,但我不确定如何更改用户给定员工ID的值,因为我们没有明确地将其作为参数传递。
很抱歉,如果这是一个问号,但我还没有找到谷歌的答案。
答案 0 :(得分:3)
我使用了流行的Oracle默认表格" emp"。它曾作为HR schema: SCOTT`的演示表在旧数据库版本中使用过。
您可以使用带有Oracle Sequence对象的简单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
对象。
开发人员经常依赖这些来保持他们的理智,因为它是唯一性的守门人。无论请求来自何处或同时调用此对象多少次,它都会发出一次序列值。一旦你创建它就试试吧:
SELECT emp_seq.nextval FROM DUAL;
这里有一些样式选择,因为Oracle 11gR2及更高版本已经在编码语法中发布了一些原始限制......
不需要使用SELECT INTO...
分配新的序列值。 Oracle 11g允许直接分配序列值,例如:
v_somevar:= emp_seq.nextval;
将此与触发操作耦合是可选的,但它可以让您完成自动分配字段值的任务。
运行而没有触发器的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;
在insert命令中不提及列值与为其分配NULL值相同。这是触发器中包含的IF-THEN-ELSE块的含义。
原始请求:
要完成OP的功能,您需要重新排列条件块,以考虑通过针对表发出的EMPNO
语句分配给主键INSERT
的实际输入值。
使用在执行insert命令之前执行的代码是正确的选择。这意味着管理自动增量序列分配需要BEFORE INSERT TRIGGER。
在触发器代码中需要密切注意的值是分配给 BEFORE 和 AFTER 触发器状态的值,标记为NEW
和{ {1}}。带前缀的&#34;冒号&#34; (&#34;:&#34;)是语法所必需的。
触发器引用的表格中的每一列都可以使用OLD
和:NEW
表示法作为前缀,如::OLD
或:NEW.empno
。
如果是:NEW.ename
触发器,则没有BEFORE INSERT
个值。 (请参阅链接参考,或自行搜索)。不应引用或分配它们(:OLD
值)。 :OLD
表示在:NEW
语句中分配的值,并且可以在执行插入之前在触发器中进一步更改。