CREATE VIEW 语句
CREATE VIEW 语句定义一个或多个表,视图或昵称上的视图。
调用
此语句可以嵌入在应用程序中,也可通过动态 SQL 语句来发出。 它是一个可执行语句,仅当 DYNAMICRULES 运行行为对于程序包有效时才能动态编译 (SQLSTATE 42509)。
权限
- 数据库上的 IMPLICIT_SCHEMA 权限 (如果视图的隐式或显式模式名称不存在)
- 对模式的 CREATEIN 特权 (如果视图的模式名称引用现有模式)
- 对模式的 SCHEMAADM 权限 (如果视图的模式名称引用现有模式)
- DBADM 权限
- 该表、视图或昵称的 CONTROL 特权
- 该表、视图或昵称的 SELECT 特权
- 包含该表、视图或昵称的模式的 SELECTIN 特权
- 包含该表、视图或昵称的模式的 DATAACCESS 权限
- DATAACCESS 权限
- 语句的授权标识必须与表层次结构的根表的定义者相同,或者
- 授权标识所拥有的特权必须包含对包含表层次结构的根表的模式的 SCHEMAADM 权限
- 授权标识所拥有的特权必须包含 DBADM 权限
- 语句的授权标识必须对子视图的底层表具有 SELECT WITH GRANT 特权,或者超视图不得向除视图定义者以外的任何用户授予 SELECT 特权,或者
- 包含子视图底层表的模式上的 ACCESSCTRL 权限以及下列其中一个权限:
- 对子视图的底层表的 SELECT 特权
- 对包含子视图底层表的模式的 SELECTIN 特权
- 对包含子视图底层表的模式的 DATAACCESS 权限
- DATAACCESS 权限
- 对该表或视图的 UPDATE 特权
- 对包含该表或视图的模式的 UPDATEIN 特权
- 对包含该表或视图的模式的 DATAACCESS 权限
- DATAACCESS 权限
对于 CREATE VIEW 语句中指定的任何表或视图,不考虑组特权。
在联合数据库昵称上定义视图时,不考虑特权。 处理查询时,将应用昵称所引用的表或视图的数据源的授权要求。 可以将语句的授权标识映射到其他远程授权标识。
要替换现有视图,该语句的授权标识必须是现有视图的所有者 (SQLSTATE 42501)。
语法
描述
- OR REPLACE
- 指定此项以替换视图的定义 (如果当前服务器上存在视图)。 在目录中替换新定义之前,将有效删除现有定义,但对视图授予的特权不受影响。 如果当前服务器上不存在视图的定义,那么将忽略此选项。 此选项只能由对象所有者指定。
- 视图名称
- 命名视图。 名称 (包括隐式或显式限定符) 不得标识目录中描述的表,视图,昵称或别名。 限定符不能是 SYSIBM、SYSCAT、SYSFUN 或 SYSSTAT (SQLSTATE 42939)。
该名称可以与不可用视图的名称相同 (请参阅 不可用视图)。 在这种情况下,在 CREATE VIEW 语句中指定的新视图将替换不可用的视图。 当替换不可操作的视图时,用户将收到警告 (SQLSTATE 01595)。 如果在绑定选项 SQLWARN 设置为 NO 的情况下绑定了应用程序,那么不会返回任何警告。
- 列名称
- 对视图中的列进行命名。 如果指定了列名称列表,那么它必须包含与全查询的结果表中的列数一样多的名称。 每个 column-name 必须唯一且未限定。 如果未指定列名列表,那么视图的列将继承全查询结果表的列名。
如果全查询的结果表具有重复的列名或未命名的列,那么必须指定列名列表 (SQLSTATE 42908)。 未命名的列是从未使用选择列表的 AS 子句命名的常量,函数,表达式或集合操作派生的列。
- OF type-name
- 指定视图的列基于由 type-name标识的结构化类型的属性。 如果指定 type-name 而不指定模式名称,那么将通过在 SQL 路径上搜索模式 (由静态 SQL 的 FUNCPATH 预处理选项和动态 SQL 的 CURRENT PATH 寄存器定义) 来解析类型名称。 类型名称必须是现有用户定义类型的名称 (SQLSTATE 42704) ,并且必须是可实例化的结构化类型 (SQLSTATE 428DP)。
- MODE DB2SQL
- 此子句用于指定带类型视图的方式。 这是当前支持的唯一有效方式。
- UNDER superview-name
- 指示视图是 superview-name的子视图。 超视图必须是现有视图 (SQLSTATE 42704) ,并且必须使用作为立即超类型 type-name (SQLSTATE 428DB) 的结构化类型来定义该视图。 view-name 和 superview-name 的模式名称必须相同 (SQLSTATE 428DQ)。 superview-name 标识的视图不得具有任何已使用 type-name 定义的现有子视图 (SQLSTATE 42742)。
视图的列包括超视图的对象标识列,其类型已修改为 REF (type-name) ,后跟基于 type-name 属性的列 (请记住,该类型包含其超类型的属性)。
- INHERIT SELECT PRIVILEGES
- 对超视图拥有 SELECT 特权的任何用户或组都将被授予对新创建的子视图的同等特权。 子视图定义程序被视为此特权的设保人。
- OID-列
- 定义带类型视图的对象标识列。
- REF IS OID-column-name USER GENERATED
- 指定在视图中将对象标识 (OID) 列定义为第一列。 视图层次结构的根视图需要 OID (SQLSTATE 428DX)。 该视图必须是不是子视图的带类型视图 (必须存在 OF 子句) (SQLSTATE 42613)。 该列的名称定义为 OID-column-name ,并且不能与结构化类型 type-name 的任何属性的名称相同 (SQLSTATE 42711)。 fullselect 中指定的第一列必须为 REF 类型 (type-name) (您可能需要对其进行强制类型转换,以使其具有相应的类型)。 如果未指定 UNCHECKED ,那么它必须基于通过索引 (主键,唯一约束,唯一索引或 OID-column) 强制实施唯一性的不可空列。 此列将称为 对象标识列 或 OID 列。 关键字 USER GENERATED 表示 OID 列的初始值必须由用户在插入行时提供。 插入行后,无法更新 OID 列 (SQLSTATE 42808)。
- UNCHECKED
- 定义带类型视图定义的对象标识列以假定唯一性,即使系统无法证明此唯一性也是如此。 这旨在与正在定义到带类型视图层次结构中的表或视图配合使用,其中用户知道数据符合此唯一性规则,但它不符合允许系统证明唯一性的规则。 UNCHECKED 选项对于跨多个层次结构或旧表或视图的视图层次结构是必需的。通过指定 UNCHECKED ,用户负责确保视图的每一行都具有唯一 OID。 如果用户未能确保此属性,并且视图包含重复的 OID 值,那么涉及其中一个非唯一 OID 值的路径表达式或 DEREF 运算符可能会导致错误 (SQLSTATE 21000)。
- with-options
- 定义适用于带类型视图的列的其他选项。
- column-name WITH OPTIONS
- 指定要为其指定其他选项的列的名称。 column-name 必须对应于视图的 type-name 中定义的属性的名称 (非继承者)。 该列必须是引用类型 (SQLSTATE 42842)。 它不能对应于超视图中也存在的列 (SQLSTATE 428DJ)。 列名只能出现在语句中的一个 WITH OPTIONS SCOPE 子句中 (SQLSTATE 42613)。
- 作用域
- 标识引用类型列的范围。 必须为旨在用作取消引用运算符的左操作数或用作 DEREF 函数的参数的任何列指定范围。
指定引用类型列的作用域可延迟到后续 ALTER VIEW 语句 (如果作用域未继承) 以允许定义目标表或视图,通常在相互引用视图和表的情况下。 如果没有为视图的引用类型列指定作用域,并且已限定底层表或视图列的作用域,那么底层列的作用域将由引用类型列继承。 如果底层表或视图列没有作用域,那么该列将保持未限定作用域。 有关作用域和引用类型列的更多信息,请参阅 注释 。
- typed-table-name
- 类型化表的名称。 该表必须已存在或与正在创建的表的名称相同 (SQLSTATE 42704)。 column-name 的数据类型必须为 REF(S),其中 S 是 typed-table-name 的类型 (SQLSTATE 428DM)。 不会检查 column-name 中的任何现有值,以确保这些值实际引用 类型表名称中的现有行。
- typed-view-name
- 类型视图的名称。 该视图必须已经存在或与正在创建的视图的名称相同 (SQLSTATE 42704)。 column-name 的数据类型必须为 REF(S),其中 S 是 typed-view-name 的类型 (SQLSTATE 428DM)。 不会检查 column-name 中的任何现有值,以确保这些值实际引用 类型-view-name中的现有行。
- 只读
- 将该列标识为只读列。 此选项用于强制列为只读,以便子视图定义可以为隐式只读的同一列指定表达式。
- AS
- 标识视图定义。
- WITH common-table-expression
- 定义一个公共表表达式,以便与下面的全查询配合使用。 定义带类型视图时,不能指定公共表表达式。
- fullselect
- 定义视图。 在任何时候,视图都由执行 SELECT 语句时将产生的行组成。 视图的列的数据类型不能是具有数据类型约束,数组类型,光标类型或行类型的单值类型。 全查询不得引用主变量,参数标记或已声明的临时表。 但是,可以将参数化视图创建为 SQL 表函数。
全查询不能在 FROM 子句中包含 SQL 数据更改语句 (SQLSTATE 428FL)。
如果使用 "SELECT *" 语句创建视图,那么将新列添加到基本表时不会更新该视图。
对于 "类型视图" 和 "子视图": 全查询 必须符合以下规则,否则将返回错误 (SQLSTATE 428EA ,除非另有指定)。- 全查询不得包含对 DBPARTITIONNUM 或 HASHEDVALUE 函数,非确定性函数或定义为具有外部操作的函数的引用。
- 视图的主体必须包含单个子查询,或者包含两个或多个子查询的 UNION ALL。 让直接参与视图主体的每个子查询称为视图的 分支 。 视图可能有一个或多个分支。
- 每个分支的 FROM 子句必须由单个表或视图 (不一定是类型) 组成,称为该分支的 底层 表或视图。
- 每个分支的底层表或视图必须位于单独的层次结构中 (即,视图不能有多个分支及其底层表或视图位于同一层次结构中)。
- 带类型视图定义的任何分支都不能指定 GROUP BY 或 HAVING。
- 如果视图主体包含 UNION ALL ,那么层次结构中的根视图必须为其 OID 列指定 UNCHECKED 选项。
对于视图和子视图的层次结构: 让 BR1 和 BR2 成为层次结构中视图定义中显示的任何分支。 让 T1 是 BR1的底层表或视图,让 T2 是 BR2的底层表或视图。 过去:- 如果 T1 和 T2 不在同一层次结构中,那么视图层次结构中的根视图必须为其 OID 列指定 UNCHECKED 选项。
- 如果 T1 和 T2 位于同一层次结构中,那么 BR1 和 BR2 必须包含足以保证其行集不分离的谓词或 ONLY 子句。
对于使用 EXTEND AS 定义的类型化子视图: 对于子视图主体中的每个分支:- 每个分支的底层表必须是直接超视图的某个底层表的 (不一定正确) 子表。
- SELECT 列表中的表达式必须可分配给子视图的非继承列 (SQLSTATE 42854)。
对于使用不带 EXTEND 的 AS 定义的类型化子视图:- 对于子视图主体中的每个分支, SELECT-list 中的表达式必须可分配给子视图的继承列和非继承列的声明类型 (SQLSTATE 42854)。
- 子视图中给定层次结构上的每个分支的 OID 表达式必须与根视图中同一层次结构上的分支中的 OID 表达式等效 (强制类型转换除外)。
- 在超视图中未定义 (隐式或显式) 为 READ ONLY 的列的表达式必须在其子视图中的同一底层层次结构上的所有分支中等效。
- WITH CHECK OPTION
- 指定通过视图插入或更新的每行必须符合视图定义的约束。 不符合视图定义的行是不满足视图搜索条件的行。如果满足下列任何条件,那么不得指定 WITH CHECK OPTION:
- 视图是只读的 (SQLSTATE 42813)。 如果对不允许插入的可更新视图指定了 WITH CHECK OPTION ,那么约束仅应用于更新。
- 该视图引用 DBPARTITIONNUM 或 HASHEDVALUE 函数,非确定性函数或具有外部操作的函数 (SQLSTATE 42997)。
- 昵称是视图的更新目标。
- 定义了 INSTEAD OF 触发器的视图是视图的更新目标 (SQLSTATE 428FQ)。
如果省略 WITH CHECK OPTION ,那么不会在检查使用该视图的任何插入或更新操作时使用该视图的定义。 如果视图直接或间接依赖于包含 WITH CHECK OPTION 的另一个视图,那么在插入或更新操作期间仍可能进行某些检查。 由于未使用视图的定义,因此可能会通过视图插入或更新不符合视图定义的行。- CASCADED
- 视图 V 上的 WITH CASCADED CHECK OPTION 约束表示 V 从 V 所依赖的任何可更新视图继承搜索条件作为约束。 此外,依赖于 V 的每个可更新视图也受这些约束约束。 因此,将 V 的搜索条件与 V 所依赖的每个视图一起进行 AND 运算,以形成用于插入或更新 V 或任何依赖于 V的视图的约束。
- LOCAL
- 视图 V 上的 WITH LOCAL CHECK OPTION 约束表示将 V 的搜索条件作为插入或更新 V 或依赖于 V的任何视图的约束应用。
CASC冲和 LOCAL 之间的差异在以下示例中显示。 请考虑以下可更新视图 (从下表的列标题中替换 Y):V1 defined on table T V2 defined on V1 WITH Y CHECK OPTION V3 defined on V2 V4 defined on V3 WITH Y CHECK OPTION V5 defined on V4下表显示了用于检查插入或更新的行的搜索条件:Y 为 LOCAL Y 已级联 针对以下内容检查了 V1 : 无视图 无视图 针对以下内容检查了 V2 : V2 V2, V1 针对以下内容检查了 V3 : V2 V2, V1 针对以下内容检查了 V4 : V2, V4 V4, V3, V2, V1 针对以下内容检查了 V5 : V2, V4 V4, V3, V2, V1 请考虑以下可更新的视图,该视图显示了使用缺省CASC冲选项的 WITH CHECK OPTION 的影响:CREATE VIEW V1 AS SELECT COL1 FROM T1 WHERE COL1 > 10 CREATE VIEW V2 AS SELECT COL1 FROM V1 WITH CHECK OPTION CREATE VIEW V3 AS SELECT COL1 FROM V2 WHERE COL1 < 100使用 V1 的以下 INSERT 语句将成功,因为 V1 没有 WITH CHECK OPTION ,并且 V1 不依赖于具有 WITH CHECK OPTION 的任何其他视图。INSERT INTO V1 VALUES(5)使用 V2 的以下 INSERT 语句将导致错误,因为 V2 具有 WITH CHECK OPTION ,并且插入将生成不符合 V2定义的行。INSERT INTO V2 VALUES(5)使用 V3 的以下 INSERT 语句将导致错误,即使它没有 WITH CHECK OPTION ,因为 V3 依赖于具有 WITH CHECK OPTION (SQLSTATE 44000) 的 V2 。INSERT INTO V3 VALUES(5)使用 V3 的以下 INSERT 语句将成功,即使它不符合 V3 的定义 (V3 没有 WITH CHECK OPTION); 它也符合具有 WITH CHECK OPTION 的 V2 的定义。INSERT INTO V3 VALUES(200) - 不带行移动 或 的行移动
- 指定当以违反底层表上的检查约束的方式更新行时,要对可更新的 UNION ALL 视图执行的操作。 缺省值为 WITH NO ROW MOVEMENT。
- 无行移动
- 指定如果以违反底层表的检查约束的方式更新行,那么将返回错误 (SQLSTATE 23513)。
- 带行移动
- 指定要将更新后的行移至相应的底层表,即使它违反了对该表的检查约束也是如此。
行移动涉及删除违反检查约束的行,并将这些行插入到视图中。 只能对其列都可更新的 UNION ALL 视图指定 WITH ROW MOVEMENT 子句 (SQLSTATE 429BJ)。 如果将行 (可能在触发器激活之后) 插入到从中删除该行的同一底层表中,那么将返回错误 (SQLSTATE 23524)。 使用 WITH ROW MOVEMENT 子句定义的视图不得包含嵌套的 UNION ALL 操作,但在最外面的全查询中除外 (SQLSTATE 429BJ)。 使用 WITH ROW MOVEMENT 子句定义的视图不能包含对系统周期时态表,应用程序周期时态表或双时态表的任何引用。
注意
- 使用尚不存在的模式名称创建视图将导致隐式创建该模式,前提是语句的授权标识具有 IMPLICIT_SCHEMA 权限。 模式所有者是 SYSIBM。 该模式上的 CREATEIN 特权会授予 PUBLIC。
- 视图列从基本表或视图继承 NOT NULL WITH DEFAULT 属性,但从表达式派生列时除外。 在可更新视图中插入或更新行时,将根据基本表上定义的约束 (主键,引用完整性和检查) 进行检查。
- 如果新视图在其定义中使用不可用的视图,那么无法创建该视图。 (SQLSTATE 51024)。
- 如果视图主体中引用的对象不存在或被标记为无效,或者定义者暂时没有访问该对象的特权,并且如果数据库配置参数 auto_reval 设置为 DEFERRED_FORCE ,那么仍将成功创建该视图。 该视图将标记为无效,并将在下次引用该视图时重新生效。
- 此语句不支持声明的临时表 (SQLSTATE 42995)。
- 基于 按列组织的 表的视图:
- 不支持在 按列组织的 表上创建带类型视图。
- 如果 按列组织的 表是视图定义的一部分,那么不能指定 WITH CHECK OPTION 子句。
- 可删除视图: 如果为视图定义了删除操作的 INSTEAD OF 触发器,或者满足以下所有条件,那么视图 可删除 :
- 外全查询的每个 FROM 子句仅标识一个基本表 (没有 OUTER 子句) ,可删除视图 (没有 OUTER 子句) ,可删除嵌套表表达式或可删除公共表表达式 (无法标识昵称)。 另外,为基本表或可删除视图指定的任何时间段规范都不会引用 SYSTEM_TIME 时间段。
- 外部全查询不包含 VALUES 子句
- 外部全查询不包含 GROUP BY 子句或 HAVING 子句
- 外部全查询不包含选择列表中的聚集函数
- 外部全查询不包含 SET 操作 (UNION , EXCEPT 或 INTERSECT) , UNION ALL 除外
- UNION ALL 的操作数中的基本表不能是同一表,并且每个操作数都必须可删除
- 外部全查询的选择列表不包含 DISTINCT
- 可更新视图: 如果为视图定义了用于更新操作的 INSTEAD OF 触发器,或者满足以下所有条件,那么视图的列 可更新 :
- 视图可删除 (独立于用于删除的 INSTEAD OF 触发器) ,该列解析为基本表的列 (不使用取消引用操作) ,并且未指定 READ ONLY 选项
- UNION ALL 的操作数的所有相应列都具有完全匹配的数据类型 (包括长度或精度和小数位) 和匹配的缺省值 (如果视图的全查询包含 UNION ALL)
如果视图的 any 列是可更新的,那么该视图是可更新的。
- 可插入视图: 如果为视图定义了用于插入操作的 INSTEAD OF 触发器,或者视图的至少一列可更新 (独立于用于更新的 INSTEAD OF 触发器) ,并且视图的全查询不包含 UNION ALL ,那么视图可插入。
给定的行可以插入到视图中 (包括 UNION ALL) ,如果且仅当它满足一个底层基本表的检查约束时。
要插入到包含不可更新列的视图中,必须从列列表中省略这些列。
- 只读视图: 如果视图 不可 删除,可更新或可插入,那么该视图为 只读 。
SYSCAT.VIEWS 目录视图指示视图是只读的,而不考虑周期规范或 INSTEAD OF 触发器。
- 公共表表达式和嵌套表表达式遵循同一组规则,用于确定它们是可删除的,可更新的,可插入的还是只读的。
- 用于临时支持的专用寄存器: CURRENT TEMPORAL SYSTEM_TIME 和 CURRENT TEMPORAL BUSINESS_TIME 专用寄存器的值不会影响在定义视图时定义视图的查询表达式。 在 SQL 语句中使用视图时,用于处理 SQL 语句的会话的 CURRENT TEMPORAL SYSTEM_TIME 和 CURRENT TEMPORAL BUSINESS_TIME 专用寄存器的值将应用于该视图。
- 不可用视图: 不可用视图 是不再可用于 SQL 语句的视图。 在下列情况下,视图将变为不可用:
- 将撤销视图定义所依赖的特权。
- 将删除视图定义所依赖的对象,例如表,昵称,别名或函数。
- 视图定义所依赖的视图将变为不可用。
- 作为视图定义 (子视图) 的超视图变得不可用。
实际上,不可操作的视图是指视图定义已被无意删除的视图。 例如,删除别名时,将使使用该别名定义的任何视图不可用。 所有从属视图也变得不可用,依赖于该视图的包不再有效。
在显式地重新创建或删除不可用视图之前,无法编译使用该不可用视图的语句 (SQLSTATE 51024) ,但 CREATE ALIAS , CREATE VIEW , DROP VIEW 和 COMMENT ON TABLE 语句除外。 在显式删除不可用视图之前,不能使用其限定名来创建另一个表或别名 (SQLSTATE 42710)。
可以通过使用不可用视图的定义文本发出 CREATE VIEW 语句来重新创建不可用视图。 此视图定义文本存储在 SYSCAT.VIEWS 目录。 重新创建不可用视图时,需要显式授予其他用户对该视图所需的任何特权,因为如果该视图被标记为不可用,那么将删除该视图上的所有授权记录。 请注意,不需要显式删除不可操作的视图以重新创建该视图。 发出与不可用视图具有相同 view-name 的 CREATE VIEW 语句将导致替换该不可用视图,并且 CREATE VIEW 语句将返回警告 (SQLSTATE 01595)。
不可用视图由 SYSCAT.VIEWS 目录视图和 SYSCAT.TABLES 目录视图。
- 特权: 视图的定义者始终接收对该视图的 SELECT 特权以及删除该视图的权限。 仅当定义程序对全查询中标识的每个基本表,视图或昵称都具有 CONTROL 特权时,或者定义程序具有以下每个权限时,视图的定义程序才会获得对视图的 CONTROL 特权:
- 包含全查询中标识的每个基本表,视图或昵称的模式上的 ACCESSCTRL , SECADM 或 ACCESSCTRL
- 包含全查询中标识的每个基本表,视图或昵称的模式上的 DATAACCESS 或 DATAACCESS
- 对包含全查询中标识的每个基本表,视图或昵称的模式的 DBADM 或 SCHEMAADM 权限
如果视图不是只读的,并且定义者对底层对象具有相应的特权,那么该视图的定义者将被授予对该视图的 INSERT , UPDATE ,列级别 UPDATE 或 DELETE 特权。
对于定义为 WITH ROW MOVEMENT 的视图,仅当定义者对视图的所有列具有 UPDATE 特权以及对所有底层表或视图具有 INSERT 和 DELETE 特权时,定义者才会获取对视图的 UPDATE 特权。
仅当创建视图时从中派生的特权存在时,视图的定义者才会获取特权。 定义者必须直接具有这些特权,或者因为 PUBLIC 具有这些特权。 在联合服务器昵称上定义视图时不考虑特权。 但是,在昵称上使用视图时,用户的授权标识必须对该昵称在数据源中引用的表或视图具有有效的选择特权。 否则会返回错误。 不考虑视图定义者所属的组所拥有的特权。
创建子视图时,将自动授予对直接超视图的 SELECT 特权。
- 作用域和 REF 列: 在视图定义的全查询中选择引用类型列时,请考虑所需的目标类型和作用域。
- 如果所需的目标类型和作用域与底层表或视图相同,那么只需选择该列即可。
- 如果需要更改作用域,请使用 WITH OPTIONS SCOPE 子句来定义所需的作用域表或视图。
- 如果需要更改引用的目标类型,那么必须先将列强制类型转换为引用的表示类型,然后再转换为新的引用类型。 在这种情况下,可以在强制类型转换为引用类型或使用 WITH OPTIONS SCOPE 子句来指定作用域。 例如,假定您选择定义为 REF (TYP1) SCOPE TAB1的列 Y。 您希望将其定义为 REF (VTYP1) SCOPE VIEW1。 选择列表项将如下所示:
CAST(CAST(Y AS VARCHAR(16) FOR BIT DATA) AS REF(VTYP1) SCOPE VIEW1)
- 标识列: 如果视图定义全查询中相应列的元素是表的标识列的名称,或者是直接或间接映射到基本表的标识列的名称的视图的列的名称,那么该视图的列被视为标识列。在所有其他情况下,视图的列将不会获取身份属性。 例如:
- 视图定义的选择列表包含标识列名称的多个实例 (即,多次选择同一列)
- 视图定义涉及连接
- 视图定义中的列包含引用标识列的表达式
- 视图定义包含 UNION
当插入视图定义的选择列表直接或间接包含基本表的标识列的名称的视图时,将应用相同的规则,就像 INSERT 语句直接引用基本表的标识列一样。
- 联合视图: 联合视图是包含对全查询中某个位置的昵称的引用的视图。 当随后在查询中引用视图时,此类昵称的存在将更改用于视图的授权模型。
创建视图时,不会执行特权检查以确定视图定义者是否有权访问底层数据源表或昵称的视图。 对联合数据库中的表或视图的引用的特权检查照常处理,要求视图定义者至少对此类对象具有 SELECT 特权。
当随后在查询中引用联合视图时,昵称会导致针对数据源的查询,并且发出查询的授权标识 (或其映射到的远程授权标识) 必须具有访问数据源表或视图所需的特权。 发出引用联合视图的查询的授权标识不需要对联合服务器上存在的表或视图 (非联合) 具有任何其他特权。
- ROW MOVEMENT ,触发器和约束: 更新使用 WITH ROW MOVEMENT 子句定义的视图时,触发器和约束操作的顺序如下所示:
- 将对正在更新的所有行 (包括最终将移动的行) 激活 BEFORE UPDATE 触发器。
- 已处理更新操作。
- 将为所有已更新的行处理约束。
- 对于在更新操作之后满足约束的所有行,将按创建顺序激活 AFTER UPDATE 触发器 (行级别和语句级别)。 因为这是 UPDATE 语句,所以将对所有底层表激活所有 UPDATE 语句级别触发器。
- BEFORE DELETE 触发器将针对更新操作后未满足约束的所有行激活 (这些是要移动的行)。
- 已处理删除操作。
- 将为所有已删除的行处理约束。
- 对于所有已删除的行,将按创建顺序激活 AFTER DELETE 触发器 (行级别和语句级别)。 仅对删除操作中涉及的那些表激活语句级触发器。
- 对于要插入的所有行 (即,要移动的行) ,将激活 BEFORE INSERT 触发器。 BEFORE INSERT 触发器的新转换表包含用户提供的输入数据。 此类触发器不能包含 UPDATE , DELETE 或 INSERT 操作,也不能调用包含此类操作的任何例程 (SQLSTATE 42987)。
- 已处理插入操作。
- 将为所有插入的行处理约束。
- 对于所有插入的行,将按创建顺序激活 AFTER INSERT 触发器 (行级别和语句级别)。 仅对插入操作中涉及的那些表激活语句级触发器。
- 嵌套 UNION ALL 视图: 如果使用 WITH ROW MOVEMENT 子句定义了任何一个视图 (SQLSTATE 429BK) ,那么无法更新使用 UNION ALL 定义的视图以及基于也使用 UNION ALL 定义的视图的视图 (直接或间接)。
- 隐式隐藏列的注意事项: 全查询的结果表可能包含定义为隐式隐藏的基本表的列。 当在视图定义的全查询中显式引用隐式隐藏列时,可能会发生此情况。 但是,视图的相应列不会继承隐式隐藏属性。 视图的列不能定义为隐藏。
- 子查询: 无法在 fullselect 中指定 隔离子句 (SQLSTATE 42601)。
- 模糊处理:CREATE VIEW 语句可以采用模糊处理的形式提交。 在模糊化语句中,只有视图名称是可读的。 该语句的其余部分以不可读的方式进行编码,但可由数据库服务器进行解码。 可以通过调用 DBMS_DDL.WRAP 函数来生成模糊化的语句。
- 语法替代方法: 为了与先前版本的 Db2® 和其他数据库产品兼容,支持以下语法替代方法。
- 可以在关键字 CREATE 和 VIEW 之间指定 FEDERATED 关键字。 但是,将忽略 FEDERATED 关键字,因为如果在视图定义中使用了联合对象,那么将不再返回警告。
示例
- 示例 1: 在 PROJECT 表上创建名为 MA_PROJ 的视图,其中仅包含以字母 "MA" 开头的项目编号 (PROJNO) 行。
CREATE VIEW MA_PROJ AS SELECT * FROM PROJECT WHERE SUBSTR(PROJNO, 1, 2) = 'MA' - 示例 2: 创建视图,例如 1 ,但仅选择项目编号 (PROJNO) ,项目名称 (PROJNAME) 和负责项目的员工 (RESPEMP) 的列。
CREATE VIEW MA_PROJ AS SELECTPROJNO, PROJNAME, RESPEMP FROM PROJECT WHERE SUBSTR(PROJNO, 1, 2) = 'MA' - 示例 3: 创建视图,如示例 2 中所示,但是在视图中,调用负责项目 IN_CHARGE 的员工的列。
CREATE VIEW MA_PROJ (PROJNO, PROJNAME, IN_CHARGE) AS SELECTPROJNO, PROJNAME, RESPEMP FROM PROJECT WHERE SUBSTR(PROJNO, 1, 2) = 'MA'注: 即使只更改了其中一个列名,视图中所有三列的名称也必须在 MA_PROJ 后面的括号中列出。 - 示例 4: 创建名为 PRJ_LEADER 的视图,其中包含 PROJECT 表中的前四列 (PROJNO , PROJNAME , DEPNO 和 RESPEMP) 以及负责项目 (RESPEMP) 的人员的姓氏 (LASTNAME)。 通过将 EMPLOYEE 中的 EMPNO 与 PROJECT 中的 RESPE 匹配,从 EMPLOYEE 表中获取名称。
CREATE VIEW PRJ_LEADER AS SELECT PROJNO, PROJNAME, DEPTNO, RESPEMP, LASTNAME FROM PROJECT, EMPLOYEE WHERE RESPEMP = EMPNO - 示例 5: 创建视图,如示例 4 中所示,但除了列 PROJNO , PROJNAME , DEPTNO , RESPEMP 和 LASTNAME 之外,还显示负责的员工的总薪酬 (SALARY + PAY + COMM)。 还请仅选择平均人员配置 (PRSTAFF) 大于 1 的项目。
CREATE VIEW PRJ_LEADER (PROJNO, PROJNAME, DEPTNO, RESPEMP, LASTNAME, TOTAL_PAY ) AS SELECT PROJNO, PROJNAME, DEPTNO, RESPEMP, LASTNAME, SALARY+BONUS+COMM FROM PROJECT, EMPLOYEE WHERE RESPEMP = EMPNO AND PRSTAFF > 1通过在全查询中将表达式 SALARY + 奖金 + COMM 命名为 TOTAL_PAY ,可以避免指定列名列表。CREATE VIEW PRJ_LEADER AS SELECT PROJNO, PROJNAME, DEPTNO, RESPEMP, LASTNAME, SALARY+BONUS+COMM AS TOTAL_PAY FROM PROJECT, EMPLOYEE WHERE RESPEMP = EMPNO AND PRSTAFF > 1 - 示例 6: 给定下图中显示的一组表和视图:
用户 ZORPIE (没有 ACCESSCTRL , DATAACCESS 或 DBADM 权限) 具有每个对象的括号中显示的特权:图 1。 示例 6 的表和视图 
- ZORPIE 将获得对她创建的视图的 CONTROL 特权:
因为她在 S1.V1。 ( S1.V1 必须已由具有 ACCESSCTRL 或 SECADM 权限的人员授予给 ZORPIE。) 她对底层基本表具有哪些特权 (如果有) 并不重要。CREATE VIEW VA AS SELECT * FROM S1.V1 - 将不允许 ZORPIE 创建视图:
因为她在 S1.V2。 她在底层基本表 (S1.T2)。CREATE VIEW VB AS SELECT * FROM S1.V2 - ZORPIE 将获得对她创建的视图的 CONTROL 特权:
因为 ZORPIE.VC 引用视图 S1.V1 和表 S1.T2 和她都有 CONTROL。 请注意,视图 VC 是只读的,因此 ZORPIE 不会获得 INSERT , UPDATE 或 DELETE 特权。CREATE VIEW VC (COLA, COLB, COLC, COLD) AS SELECT * FROM S1.V1, S1.T2 WHERE COLA = COLC - ZORPIE 将获得对她创建的视图的 SELECT 特权:
因为 ZORPIE.VD 引用两个视图 S1.V1 和 S1.V3,其中一个仅具有 SELECT 特权,另一个具有 CONTROL 特权。 在 ZORPIE.VD。CREATE VIEW VD (COLA,COLB, COLE, COLF) AS SELECT * FROM S1.V1, S1.V3 WHERE COLA = COLE - ZORPIE 将在以下视图定义中获取对视图 VE 的 INSERT , UPDATE 和 DELETE 特权 WITH GRANT OPTION 和 SELECT 特权。
CREATE VIEW VE AS SELECT * FROM S1.V1 WHERE COLA > ANY (SELECT COLE FROM S1.V3)ZORPIE 在 VE 上的特权主要由她在 S1.V1。 自 S1.V3 ,她只需要对 S1.V3 ,用于创建视图 VE。 仅当视图的定义者对视图定义中引用的所有对象都具有 CONTROL 时,该定义者才会对该视图获取 CONTROL。 ZORPIE 在 S1.V3,因此她不会在 VE 上获取 CONTROL。
- ZORPIE 将获得对她创建的视图的 CONTROL 特权:
