触发器的基本分类
1.行触发器:数据库表中的每一行有变化都会触发一次触发器代码
2.语句触发器:与语句所影响的行数无关,仅触发一次
3.BEFORE触发器:在DML语句执行之前触发
4.ALFTER触发器:在DML语句执行之后触发
DML触发器基本定义:
CREATE [OR REPLACE] TRIGGER [schema.] trigger
{BEFORE|AFTER} verb_list ON [schema.]table
[FOR EACH ROW]
[WHEN (condition)]
BEGIN
.................
END;
创建一个行级触发器如下:
CREATE OR REPLACE TRIGGER TRIG_R_WIP_TRACKING_T
BEFORE UPDATE OR INSERT OR DELETE
ON SFCRUNTIME.R_WIP_TRACKING_T
FOR EACH ROW
BEGIN
IF INSERTING
THEN
INSERT INTO SFCRUNTIME.R_WO_BASE (ID,
WORKORDERNO,
WO_TYPE,
SKUNO,
SKU_VER,
SKU_NAME,
SKU_DESC)
VALUES ('002',
:new.mo_number,'normal',
:new.model_name,
:new.version_code,
:new.model_name,
:new.model_name);
ELSIF UPDATING
THEN
UPDATE R_WO_BASE
SET PLANT= :new.serial_number
WHERE WORKORDERNO= :new.mo_number;
ELSIF DELETING
THEN
DELETE FROM R_WO_BASE
WHERE WORKORDERNO=:old.mo_number;
END IF;
END;
注:执行上述触发器会报错--->[Error] ORA-01031 (10: 30): PL/SQL: ORA-01031: insufficient privileges
原因及解决:我登陆数据库用的是SYSTEM,而建立的触发器是基于SFCRUNTIME账户下的表,故会报无权限的错误
解决->创建触发器时触发器的名字前面也加上用户名前缀
最终正确触发器如下
CREATE OR REPLACE TRIGGER SFCRUNTIME.TRIG_R_WIP_TRACKING_T
BEFORE UPDATE OR INSERT OR DELETE
ON SFCRUNTIME.R_WIP_TRACKING_T
FOR EACH ROW
BEGIN
IF INSERTING
THEN
INSERT INTO SFCRUNTIME.R_WO_BASE (ID,
WORKORDERNO,
WO_TYPE,
SKUNO,
SKU_VER,
SKU_NAME,
SKU_DESC)
VALUES ('002',
:new.mo_number,'normal',
:new.model_name,
:new.version_code,
:new.model_name,
:new.model_name);
ELSIF UPDATING
THEN
UPDATE R_WO_BASE
SET PLANT= :new.serial_number
WHERE WORKORDERNO= :new.mo_number;
ELSIF DELETING
THEN
DELETE FROM R_WO_BASE
WHERE WORKORDERNO=:old.mo_number;
END IF;
END;
关于OLD和NEW谓词的几点说明
1.只有行触发器才可以使用OLD NEW谓词来获取语句执行前和执行后的记录
2.当在INSET语句上激发触发器时,OLD结构不包含任何值
3.UPDATE语句激发触发器,OLD结构包含之前旧的记录的值 NEW包含更新后的值
4.DELETE语句激发触发器,NEW不包含任何值,OLD包含已经被删除的值