使用INSTEAD OF触发器在视图中插入、更新和删除数据
INSTEAD OF触发器是执行触发器,而不是激活触发器的INSERT、UPDATE或DELETE语句。 您只能在视图中定义这些触发器。 使用INSTEAD OF触发器在复杂视图中插入、更新和删除数据。
关于本任务
复杂视图是指在表达式或多个表格中定义的视图。 在某些情况下,这些观点只能阅读。 在这些情况下,INSTEAD OF触发器允许插入、更新和删除操作。 如果复杂视图不是只读的,您可以请求插入、更新或删除操作。 但是, Db2 会自动决定如何在视图中引用的基本表上执行该操作。 使用INSTEAD OF触发器,您可以精确定义 Db2 如何在视图中执行插入、更新或删除操作。 您无需再向 Db2 发送邮件来做出决定。
过程
使用INSTEAD OF触发器在视图中插入、更新或删除数据:
示例
假设您在示例表DSN8C10.EMP 和DSN8C10.DEPT 上创建了以下视图:
CREATE VIEW EMPV (EMPNO, FIRSTNME, MIDINIT, LASTNAME, PHONENO, HIREDATE,DEPTNAME)
AS SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, PHONENO, HIREDATE, DEPTNAME
FROM DSN8C10.EMP, DSN8C10.DEPT WHERE DSN8C10.EMP.WORKDEPT
= DSN8C10.DEPT.DEPTNO
假设您还定义了以下三个触发器:
CREATE TRIGGER EMPV_INSERT INSTEAD OF INSERT ON EMPV
REFERENCING NEW AS NEWEMP
FOR EACH ROW MODE DB2SQL
INSERT INTO DSN8C10.EMP (EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT,
PHONENO, HIREDATE)
VALUES(NEWEMP.EMPNO, NEWEMP.FIRSTNME, NEWEMP.MIDINIT, NEWEMP.LASTNAME,
COALESCE((SELECT D.DEPTNO FROM DSN8C10.DEPT AS D
WHERE D.DEPTNAME = NEWEMP.DEPTNAME),
RAISE_ERROR('70001', 'Unknown department name')),
NEWEMP.PHONENO, NEWEMP.HIREDATE)
CREATE TRIGGER EMPV_UPDATE INSTEAD OF UPDATE ON EMPV
REFERENCING NEW AS NEWEMP OLD AS OLDEMP
FOR EACH ROW MODE DB2SQL
BEGIN ATOMIC
UPDATE DSN8C10.EMP AS E
SET (E.FIRSTNME, E.MIDINIT, E.LASTNAME, E.WORKDEPT, E.PHONENO,
E.HIREDATE)
= (NEWEMP.FIRSTNME, NEWEMP.MIDINIT, NEWEMP.LASTNAME,
COALESCE((SELECT D.DEPTNO FROM DSN8C10.DEPT AS D
WHERE D.DEPTNAME = OLDEMP.DEPTNAME),
RAISE_ERROR ('70001', 'Unknown department name'))
NEWEMP.PHONENO, NEWEMP.HIREDATE)
WHERE NEWEMP.EMPNO = E.EMPNO;
UPDATE DSN8C10.DEPT D SET D.DEPTNAME=NEWEMP.DEPTNAME
WHERE D.DEPTNAME=OLDEMP.DEPTNAME;
END
CREATE TRIGGER EMPV_DELETE INSTEAD OF DELETE ON EMPV
REFERENCING OLD AS OLDEMP
FOR EACH ROW MODE DB2SQL
DELETE FROM DSN8C10.EMP AS E WHERE E.EMPNO = OLDEMP.EMPNO
因为视图是通过内连接查询的,所以视图是只读的。 然而,INSTEAD OF触发器使得插入、更新和删除操作成为可能。
下表描述了在EMPV视图中执行各种插入、更新和删除操作时发生的情况。
| SQL 语句 | 结果 |
|---|---|
|
EMPV_INSERT触发器被激活。 如果部门名称与DSN8C10.DEPT表中的 WORKDEPT列中的值匹配,则此触发器会将该行插入到基础表 DSN8C10.EMP 中。 否则会返回错误。 如果在INSERT语句中使用查询语句代替VALUES子句,则触发器主体将根据查询中的每一行进行处理。 |
|
EMPV_UPDATE触发器已激活。 该触发器更新 DSN8C10.DEPT中符合条件的行的DEPTNAME列。 |
|
EMPV_DELETE触发器已激活。 该触发器从 DSN8C10.EMP表中删除符合条件的行。 |