南大通用GBase8s 常用SQL语句(105)

视图上的 INSTEAD OF 触发器

使用 INSTEAD OF 触发器在视图上执行指定的触发操作,而不是执行触发 INSERT 、DELETE 、MERGE 或 UPDATE 语句。

语法

 

视图上的触发器

 

元素

描述

限制

语法

correlation

触发操作中限定的旧或新列值的名称( correlation.column

在此语句中必须唯一

标识符

trigger

在此为触发器声明的名称

必须在数据库中的触发器名称中是唯一的

标识符

view

触发视图的名称或同义词。可以包含 owner. qualifier 。

视图或同义词必须存在于当前数据库中

标识符

您可以使用触发操作更新视图下的表,在某些情况下更新一般“不可更新”的视图。当 INSERT 、DELETE 或 UPDATE 语句引用数据库中的特定列时,您还可以使用 INSTEAD OF 触发器替换其它操作。

在 INSTEAD OF UPDATE 触发器的可选的 REFERENCING 子句中,相关性名称可以出现在相关性名称之前或之后。

在 GBase 8s 中,CREATE FUNCTION 和 CREATE PROCEDURE 的语句中支持同一 REFERENCING OLD 和 REFERENCING NEW 语法,以在触发例程中定义相关性名称。可以在 REATE FUNCTION 或 CREATE PROCEDURE 语句(定义触发器例程)的 FOR 子句中指定的视图上的 INSTEAD OF 触发器的 Action 子句中调用触发器例程。

指定的视图有时称为触发视图。此图表的左侧部分(包含视图 规范)定义触发事件。该图表的剩余部分定义相关性名称和触发操作

示例

假设 dept 和 emp 是列出部门和员工的表:

CREATE TABLE dept (

        deptno INTEGER PRIMARY KEY,

        deptname CHAR(20),

        manager_num INT

        );

        CREATE TABLE emp (

        empno INTEGER PRIMARY KEY,

        empname CHAR(20),

        deptno INTEGER REFERENCES dept(deptno),

        startdate DATE

        );

ALTER TABLE dept ADD CONSTRAINT(FOREIGN KEY (manager_num)

        REFERENCES emp(empno));

下一语句定义 manager_info,它是 dept 和 emp 表中的列构成的视图,包含每个部门中所有的经理:

CREATE VIEW manager_info AS

            SELECT d.deptno, d.deptname, e.empno, e.empname

            FROM emp e, dept d WHERE e.empno = d.manager_num;

以下 CREATE TRIGGER 语句创建 manager_info_insert,它是设计为向 manager_info 视图中的 dept 和 emp 表插入行 INSTEAD OF 触发器:

CREATE TRIGGER manager_info_insert

     INSTEAD OF INSERT ON manager_info    --defines trigger event

     REFERENCING NEW AS n              --new manager data

     FOR EACH ROW                         --defines trigger action

     EXECUTE PROCEDURE instab(n.deptno, n.empno));

                

CREATE PROCEDURE instab (dno INT, eno INT)

      INSERT INTO dept(deptno, manager_num) VALUES(dno, eno);

      INSERT INTO emp (empno, deptno) VALUES (eno, dno);

END PROCEDURE;

表、视图、触发器和 SPL 例程创建完成之后,数据库服务器将以下 INSERT 语句作为触发事件:

INSERT INTO manager_info(deptno, empno) VALUES (08, 4232);

此触发 INSERT 语句不会执行,但是该事件会导致触发操作被执行,同时调用 instab( ) SPL 例程。SPL 例程中的 INSERT 语句向 manager_info 视图中的 emp 和 dept 基本表同时都插入新值。

INSTEAD OF 触发器的 Action 子句

当遇到指定视图的触发事件时,执行触发操作的 SQL 语句,而不是触发语句。视图上定义的触发器在操作子句中支持以下语法。

INSTEAD OF 触发操作

 

这与表上触发器的触发操作的语法不完全相同,如触发操作部分所述。由于不支持 WHEN (condition) ,因此每当遇到 INSTEAD OF 触发事件时都执行同一个触发操作,且只能指定一个操作列表,而不是为每个 condition 指定独立的列表。

视图上 INSTEAD OF 触发器的限制

您必须是视图的所有者,或者处于 DBA 状态,以便在视图上创建 INSTEAD OF 触发器。简单视图(仅基于一个表)的所有者具有 Insert 、Update 和 Delete 特权。关于触发器所有者的特权和其它用户的特权间的关系信息,请参阅执行触发操作的特权。

如果多个表在视图下面,则仅其所有者能创建触发器,但是该所有者能将视图上的 DML 特权授权给其他用户。

视图上定义的 INSTEAD OF 触发器不能违反触发器上的限制并且必须遵循以下附加规则:

  1. 仅可在视图上定义 INSTEAD OF 触发器,而非在表上。
  2. 视图必须对当前数据库是本地的。
  3. 视图不能是可更新的视图 WITH CHECK OPTION。
  4. INSTEAD OF 触发器中没有有效的 SELECT 事件或 WHEN 子句。
  5. INSTEAD OF 触发器中没有有效的 BEFORE 和 AFTER 操作。
  6. 在 INSTEAD OF UPDATE 触发器中 OF column 子句都是无效的。
  7. 每个 INSTEAD OF 触发器都必须指定 FOR EACH ROW。
  8. 通过 INSTEAD OF 触发器调用的触发例程不能引用保存点。

视图可以具有任意数量的 INSTEAD OF 触发器以用于定义每种类型的事件(INSERT 、DELETE 或 UPDATE)。

如果 SPL 的 ON EXCEPTION 语句是从 INSTEAD OF 触发器的 Action 子句发出,则它不会生效。

就像表上的触发器,INSTEAD OF 触发器的触发操作向 BIGSERIAL 、SERIAL 或 SERIAL8 列插入序列值,不能更新 SQL 通信区域结构的 sqlca.sqlerrd[1] 字段。已触发的 INSERT 操作可以成功的递增该列的序列数目,但是 sqlca.sqlerrd[1] 字段的值仍为零,而不会重置为序列值。sqlca.sqlerrd[1] 自动可以显示您通过更新的视图直接插入的新的序列值,但是该字段不能显示系列列上的 INSTEAD OF Insert 触发器的操作。

更新视图

只有定义视图的 SELECT 语句的以下所有条件都为真,则 INSERT 、DELETE 或 UPDATE 语句可以直接修改视图:

  1. 视图中的所有列都来自单个表。
  2. 投影列表中的列都不是聚集值。
  3. SELECT 投影列表中没有 UNIQUE 或 DISTINCT 关键字。
  4. 视图定义中没有 GROUP BY 子句和 UNION 运算符。
  5. 查询不选择计算值和文字值。

但是,如果触发操作修改基本表,则您可以通过使用 INSTEAD OF 触发器绕过视图上的这些限制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值