e股脑电脑教程网
  • 首 页
  • 操作系统
  • 应用软件
  • 下载工具
  • 影音视频
  • 办公软件
  • 媒体制作
  • 网站建设
  • 平面设计
  • 数据库
  • 程序开发
  • 视频教程
编辑推荐: | 文章搜索:
您现在的位置: e股脑 >> 数据库 >> DB2教程 >> INSTEAD OF 触发器 >> 教程正文
 
教程搜索
 
 
相关教程
  • 数据挖掘器: 警告 — 及时采取行动
  • UNIX、Linux 和 Windows 的生动简介
  • “总览图”: IBM DB2 通用数据库和信息
  • DB2 大事记
  • 数据管理部门副总裁兼 CTO:Don Hader
  • IBM 联邦数据库技术
  • 唐纳德.海德勒(Donald J. Haderle)
  • 数据库未来展望
  • 哪一个分布式 DB2 UDB V8 版本适合您?
  • 从数据管理到信息集成: 自然的演变
  • 联邦 - 数据库互操作性(第 1 部分)
  • 成功是必然的(中)
  • 成功是必然的(上)
  • 成功是必然的(下)
  • DB2 信息集成: 总览图
  • IBM 杰出工程师兼信息集成主管 Nelson
 
 

图文教程


  • Windows抢了谁的饭碗 非主流操作系统To

  • 地球还是火星 平常心看“非主流”

  • 综合运用Office 2007批量制作奖状

  • 没有系统盘如何才能修复受损系统?

  • 巧妙运用Excel中边界的附加功能!
 
 
赞 助 商
 
 
INSTEAD OF 触发器
  • 来源:e股脑
  • 点击次数:
  • 更新时间:2007-8-9

Serge Rielau

DB2 SQL 查询编译器开发, IBM 多伦多实验室

2003 年 8 月

视图通常用来区分 DB2 逻辑模式和物理模式。本文估计哪些视图是可以自我更新的,然后为 DB2 通用数据库 V8.1 引入一个新的功能部件: INSTEAD OF 触发器,它使所有的视图都可以更新。

简介

视图通常用来区分逻辑数据库模式和物理模式。遗憾的是,在 UPDATE、DELETE 或 INSERT 操作中通常都达不到预期的透明度,因为除了最简单的视图之外所有的视图都不可更新。本文评估哪些视图自己是可更新的,然后引入 INSTEAD OF 触发器 - 这是 DB2® Universal Database™ V8.1 for Linux、UNIX® 和 Windows® 的新功能,它使所有视图都可以更新。

先决条件

本文中的许多示例都使用 SQL 过程化语言(SQL Procedural Language,SQL PL)。由于 SQL PL 在其主体中使用分号( ; )来分隔各个语句,所以对 CLP 或命令中心(Command Center)必须使用另一个定界符。在本篇文章中我将使用美元符号( $ )来给语句定界。

要启动 CLP 会话以使用本文中的示例,请从 shell 输入: db2 -td$ 。对于命令中心,通过单击 Tools -> ToolsSettings -> Use statement termination character 来设置并激活定界符。

纵览可更新视图

在我们向您完整地介绍可更新视图之前,我们需要基本了解一下“可更新”是什么意思以及 DB2(或就这一点而言的任何数据库管理系统)必须解决哪些基本问题才能通过视图更新数据库中的行。首先,缺省情况下 DB2 所拥有的全部视图信息就是视图的定义,即指定由该视图派生出的表的查询。

为了精确起见,我们需要区别三个级别的可更新能力:

可删除 :为了从视图中删除一行,DB2 必须能够将视图中指定的那一行映射到基本表中有且仅有的一行。 可更新 :为了更新视图中的列,DB2 必须不仅能够将视图中指定的一行映射到基本表中的一行,它还必须能够将要更新的一列映射到基本表中的一列。因此,根据定义所有可更新的视图必须是可删除的。 可插入 :为了将行插入到视图中,DB2 必须能将新的行映射到一张表中并能够将指定的所有列映射到该表中的列。因此所有可插入的视图要定义成是可更新的,从而也是可删除的。 现在让我们定义一些表,然后研究这些表的各种视图的可更新能力: CREATE TABLE T1(c1 INT, c2 FLOAT)$ INSERT INTO T1 VALUES (5, 6.0), (6, 7.0), (5, 6.0)$ CREATE TABLE T2(c1 INT, c2 FLOAT)$ INSERT INTO T2 VALUES (5, 9.0), (5, 4.0), (7, 5.0)$ 对于本文中的所有示例,让我们假设提供了下列数据。示例不应该相互影响。可以通过在 CLP 中使用 +c option

或从命令中心取消激活 Options -> Execution -> Automatically Commit 来关闭(OFF)自动提交,从而使它们不相互影响。在每个示例结束时使用 ROLLBACK 命令。 示例 1:

CREATE VIEW V1(c1) AS SELECT c1 FROM T1 WHERE c2 > 0$

这是一个非常简单的视图。派生的表包含了 T1 的行子集和列子集。这个视图是可删除的,因为 DB2 可以跟踪每一行的起源并在基本表中删除各自的行。

DELETE FROM V1 WHERE c1 = 6$

但是请注意,如果有人执行了定位删除并删除 V1.c1 等于 5 的那一行,那么就看不出将删除 T1.c1 等于 5 的那两行中的哪一行。

视图也是可更新的:

UPDATE V1 SET c1 = c1 + 5 WHERE c1 = 5$

可以直接将 V1.c1 映射到 T1.c1。

INSERT 会怎么样呢?显然,应当将插入到 V1 中的任意行插入到 T1 中。为 V1.c1 指定的值应当用于 T1.c1。但是 T1.c2 呢?将使用哪些值?毕竟,视图并不知道这一列,因此用户不能为它指定值。

INSERT INTO V1 VALUES (8)$

这里需要一个定义,而 SQL 标准已经提供了该定义:将每个未提供的列值初始化成该列的隐式缺省值或显式缺省值。由于没有为 T1.c2 指定显式缺省值,所以选择值 NULL 并将(8, NULL)插入到 T1 中。

示例 2:

当有表达式时会是怎样?

CREATE VIEW V2(c1, c2) AS SELECT c1, c2 * c2 FROM T1$

与第一个示例相比较,在可删除性方面没什么改变。DB2 仍然知道视图中的某一行是由基本表中的哪一行生成的。V2.c1 列是可更新的,因此该视图也是可更新的。

但是,V2.c2 是不可更新的。原因是从任何给定的 V2.c2 无法确定 T1.c2 的值。DB2 可以设法使用除法操作来查找匹配值;但是,这个简单的示例恰恰阐明这样的数学方法只能在用在最为简单的情形中。这个小小的尝试用来说明这样的算法的功能和限制,显示出这个算法缺乏可用性。

那么对于可插入性这到底又意味着什么呢?在 DB2 V8 之前,为使视图可插入,就要求视图的所有列都是可更新的。在 DB2 V8 中,只要有一个可更新的列就足够了。只要没有指定其它列,那么就可以忽略它们。

INSERT INTO V2(c1) VALUES (7)$

系统将把(7, NULL)插入到 T1 中。请注意,即使没有一列是可更新的,视图也是可删除的。同理,反对将不可更新的列插入到视图中的唯一理由就是在不是单一列的情况下既没有定义 VALUES 也没有定义 SELECT。


示例 3:

CREATE VIEW V3(c1, c2, c3) AS SELECT T1.c1, T1.c2, T2.c2 FROM T1, T2 WHERE T1.c1 = T2.c1$

这个视图是从连接(join)派生出的。在本例中,其结果是:

SELECT * FROM V3 ORDER BY c1, c2, c3$ C1 C2 C3 -- --- --- 5 6.0 4.0 5 6.0 4.0 5 6.0 9.0 5 6.0 9.0

这个视图是不可删除的。该视图中的每一行都可以追溯到表 T1 和 T2 中的某一行,通过删除 T1 和 T2 中的各自行来删除第一行(5, 6.0, 4.0),那么也会间接删除第二行(5, 6.0, 4.0)和两个(5, 6.0, 9.0)行中的一行。这个行为不是很直观,对于不知道视图查询的用户尤为如此。

有的时候在视图中删除一行导致基本表中也删除一行,同时并没有对视图造成不希望出现的影响。例如,如果 T1.c1 和 T2.c1 都是唯一的,就属于上述情况。DB2 现在不考虑这种特殊情况。

由于 V3 是不可删除的,因此它也是不可更新的。再次声明,如果您想更新视图中的某一行,会发生令人奇怪的事情;如果想更新 V1.c1,以使视图中不同行拥有不同的值,那么情况会更糟糕。

同样,INSERT 的语义不清楚。根据为基本表插入操作选择的语义,添加另一行(5, 6.0, 9.0)会产生不同的结果。这是否意味着可更新视图不能引用另一张表?并非如此。如 示例 2所讨论的那样,带有表达式的视图具有很好的可更新性。因此标量子查询就非常适合。

示例 4:

CREATE VIEW V4(c1, c2) AS SELECT c1, c2 FROM T1 UNION ALL SELECT c1, c2 FROM T2$

V4 中的每一行明显源自特定表中的某一行。因此,基于 UNION ALL 的视图是可删除的。如果列没有基于表达式,那么该列也是可更新的。但是,该视图是不可插入的,原因很明显:它不能确定任何给定的行应当插入到哪一张基本表中。允许将某一行同时插入到两张基本表中并不合适,因为随后从视图中进行选择将两次显示该行。为允许通过 UNION ALL 进行 INSERT,需要对基本表进行约束:只能将任一给定行分派给一张表。

请参阅 http://www.ibm.com/developerworks/cn/db2/library/techarticles/0209rielau/0209rielau.html以获取有关通过 UNION ALL 视图进行 INSERT 的更多详细情况。

对通过 UNION ALL 得到的视图有一些限制,应当加以注意。UNION ALL 视图的列是不可更新的,即使 DB2 自身已插入了表达式也是如此。


1 2 3 4 5 6 下一页
  • 上一篇教程: Terry Purcell 谈外连接(第二部分)
  • 下一篇教程: 使用连接的应用程序标识
  •  

    关于本站 | 广告联系 | 版权声明 | 使用帮助

    Copyright © 2004-2008 www.egunao.com All rights reserved.