CREATE VIEW 语句
CREATE VIEW 语句用于在当前服务器上创建表或视图的视图。
调用 CREATE VIEW
此语句可嵌入应用程序中或者以交互方式发出。 这是一个可执行语句,只有在DYNAMICRULES RUN行为生效时才能动态准备。 更多信息,请参阅授权ID和动态SQL。
授权 CREATE VIEW
对于在fullselect中确定的每个表或视图,下面定义的权限集必须至少包含以下内容之一:
- 表或视图的 SELECT 权限
- 表格或视图的所有权
- DBADM 数据库权限(仅限表格)
- DATAACCESS 权限
- SYSADM 权限
- SQLADM权限(仅限目录表)
- 系统 DBADM 权限(仅限目录表)
- ACCESSCTRL权限(仅限目录表)
- SYSCTRL权限(仅限目录表)
- SECADM 权限(仅限目录表)
如果数据库是隐式创建的,则数据库权限必须位于隐式数据库或 DSNDB04 上。
权威要求部分取决于观点持有者的选择。 有关如何选择所有者,请参阅 ALTER VIEW语句中 view-name 的描述。
权限集: 如果语句嵌入在应用程序中,则权限集是所持有的权限 由计划或套餐的所有者。 如果应用程序在可信环境中绑定,并指定了“角色作为对象所有者”子句,则角色就是所有者。 否则,授权ID就是所有者。
- 如果此权限集包含 SYSADM 权限,则视图的所有者可以是任何授权 ID。 如果该集合包含 SYSCTRL 权限,但不包含 SYSADM 权限,则以下情况成立:视图的所有者可以是任何授权 ID,前提是该视图在其定义的全选查询的第一个 FROM 子句中不引用用户表或视图。 (例如,它可以指目录表或目录表视图。)
如果视图满足前一段中的规则,并且CREATE语句中没有错误,则视图将被创建,即使所有者对视图定义中的全选所标识的表和视图完全没有权限。
- 如果特权集包含系统 DBADM 权限,则视图的所有者可以是任何授权 ID。 但是,若要在用户表上创建视图,则视图的所有者或创建者必须在CREATE VIEW语句中对所有表或视图拥有SELECT权限。
- 如果特权集缺少系统 DBADM、SYSADM 和 SYSCTRL,但包含至少一个数据库的 DBADM 权限,且该数据库包含创建视图的表,则如果以下所有条件均满足,则视图的所有者可以是任何授权 ID:
子系统参数 DBACRVW 的值设置为 YES。
- 观点并非仅基于观点。
注意 :视图的所有者必须在CREATE VIEW语句中对所有表和视图拥有SELECT权限,或者,如果所有者对某个表没有SELECT权限,则创建者必须对包含该表的数据库拥有DBADM权限。 - 如果权限集缺少 SYSADM、SYSCTRL、系统 DBADM 和 DBADM 权限,或者应用程序计划或包的授权 ID 不符合上述任何条件,则视图的所有者必须为应用程序计划或包的所有者。
如果角色为对象所有者,则模式限定符必须与角色相同,除非角色具有模式创建权限、SYSADM 权限、系统DBADM权限或 SYSCTRL权限。
如果“作为物品拥有者的角色”未生效,则适用以下规则之一:
- 如果权限集缺少模式上的 CREATEIN 权限、SYSADM 权限、系统 DBADM 权限或 SYSCTRL 权限,则模式限定符(隐式或显式)必须与进程的授权 ID 之一相同。
- 如果特权集包括系统 DBADM 权限、SYSADM 权限 或 SYSCTRL 权限,则模式限定符可以是任何有效的模式名称。
如果语句是动态生成的,则适用以下规则:
- 如果进程的SQL授权ID具有SYSADM权限,则视图的所有者可以是任何授权ID。 如果授权ID具有SYSCTRL权限,但不具有SYSADM权限,则以下情况成立:视图的所有者可以是任何授权ID,前提是视图在其定义的全选查询的第一个FROM子句中不引用用户表或视图。 (例如,它可以指目录表或目录表视图。)
如果视图满足前一段中的规则,并且CREATE语句中没有错误,则视图将被创建,即使所有者对视图定义中的全选所标识的表和视图完全没有权限。
- 如果进程的 SQL 授权 ID 具有系统 DBADM 权限,则视图的所有者可以是任何授权 ID。 但是,若要在用户表上创建视图,则视图的所有者或 SQL 授权 ID 必须在 CREATE VIEW 语句中对所有表或视图具有 SELECT 权限。
- 如果进程的 SQL 授权 ID 缺少系统 DBADM 权限、 SYSADM 和 SYSCTRL,但包含至少一个包含创建视图的表的数据库的 DBADM 权限,则在满足以下所有条件的情况下,视图的所有者可以不同于 SQL 授权 ID:
- 在 Db2 安装过程中,面板DSNTIPP上的现场DBADM CREATE AUTH的值被设置为YES。
- 观点并非仅基于观点。
注意 :视图的所有者必须在CREATE VIEW语句中对所有表和视图拥有SELECT权限,或者,如果所有者对某个表没有SELECT权限,则创建者必须对包含该表的数据库拥有DBADM权限。 - 如果进程的 SQL 授权 ID 缺少 SYSADM、SYSCTRL、 系统 DBADM 权限或 DBADM 权限,或者进程的 SQL 授权 ID 不满足上述任何条件,则只有进程的授权 ID 才能拥有该视图。 在这种情况下,特权集是指为所有权选择的授权ID所拥有的特权。
语法 CREATE VIEW
描述 CREATE VIEW
- 视图名称
- 命名景观。 该名称(包括隐式或显式限定符)不得标识当前服务器上存在的表、视图、别名或同义词,也不得标识 SYSIBM.SYSPENDINGOBJECTS 目录表中存在的表。 非限定名称不得与现有同义词相同。
如果名字是限定性的,则名字可以是两部分或三部分的名字。 如果使用由三个部分组成的名称,则第一部分必须与当前服务器上安装面板 DSNTIPR 的 Db2 位置名称字段中的值匹配。 (如果当前服务器不是本地服务器 Db2 ,则该名称不一定是当前服务器特殊寄存器中的名称。)
- 列名……
- 命名视图中的列。 如果您指定列名列表,则列表中的列名必须与全选查询结果表中的列数相同。 每个名字必须是唯一的,且没有限制。 如果您没有指定列名称列表,视图中的列将继承全选查询结果表的列名称。
如果全选的结果表有重复的列名或未命名的列(由常量、函数或表达式派生而来,且未通过AS子句命名),则必须指定列名列表。 有关未命名列的详细信息,请参阅 select子句下有关结果列名称的信息。
- AS
- 确定视图定义。
- WITH common-table-expression
- 定义一个公共表表达式,用于后面的全选操作。 fullselect不能包含句号。 关于常见表表达式的解释,请参阅常见表表达式。
- fullselect
- 定义了视野。 在任何时候,视图都包含执行全选操作后的结果。
完全选择必须符合以下规则:
- fullselect 不能引用任何宿主变量或参数标记(问号),但可以引用全局变量。
- fullselect 不能引用任何已声明的临时表。
- fullselect中不得包含对UNPACK函数的调用。
- fullselect 不能包含句号。
- fullselect 的FROM子句不得包含数据更改表引用。
- fullselect 的FROM子句中不能包含已定义了INSTEAD OF触发器的视图。
- 外层全选列表的外层选择列表不能产生数组列。
有关“全选” 的解释,请参阅 “全选 ”。
- WITH CASCADED CHECK OPTION 或者 WITH LOCAL CHECK OPTIONS
- 规定通过视图插入或更新的每一行都必须符合视图的定义。 不符合视图定义的行是使用该视图无法检索的行。
如果视图是只读的,包含子查询,引用不确定的函数或具有外部操作,或者视图的fullselect引用已创建的临时表,则不得指定CHECK OPTION子句。 如果为不允许插入的可更新视图指定了CHECK OPTION子句,则该子句仅适用于更新。
如果省略了CHECK OPTION子句,则视图的定义将不会用于检查使用该视图的任何插入或更新操作。 如果在插入或更新操作期间,视图直接或间接依赖于包含CHECK OPTION子句的另一个视图,则仍可能发生一些检查。 由于未使用视图的定义,因此可能会通过不符合视图定义的视图插入或更新行。
当视图依赖于另一个视图时,CASCADED和LOCAL这两种检查选项形式的区别才有意义。 默认值为CASCADED。 直接或间接定义另一个视图的视图是基础视图。- CASCADED
- 视图 V 的更新和插入操作必须满足视图 V 和所有基础视图的搜索条件,无论基础视图是否带有复选框选项。 此外,在视图V上直接或间接定义的每个可更新视图都继承了这些搜索条件(视图V和V的所有基础视图的搜索条件),作为插入或更新操作的约束条件。 如果指定视图定义所依赖的视图定义具有“代替”触发器,则不得指定“带级联检查选项”。
- LOCAL
- 视图 V 的更新和插入操作必须满足视图 V 和底层视图的搜索条件,这些条件由检查选项(WITH CASCADED CHECK OPTION 或 WITH LOCAL CHECK OPTION)定义。 此外,在视图V上直接或间接定义的每个可更新视图都继承了这些搜索条件(视图V和V的所有基础视图的搜索条件,这些搜索条件通过复选框选项进行定义),作为插入或更新操作的约束条件。
CHECK选项的LOCAL形式允许您更新或插入不符合视图V搜索条件的行。 如果视图直接或间接定义在未带检查选项的视图中,则可以执行这些操作。
表1 说明了使用默认检查选项CASCADED的效果。 表1中的信息基于以下观点:
- 创建视图 V1 AS SELECT COL1 FROM T1 WHERE COL1 > 10
- 创建视图 V2 AS SELECT COL1 FROM V1 WITH CASCADED CHECK OPTION
- 创建视图 V3 AS SELECT COL1 FROM V2 WHERE COL1 < 100
表 1. 使用默认检查选项CASCADED的示例 SQL 语句 结果描述 INSERT INTO V1 VALUES(5) 成功是因为 V1 没有复选框选项,且它不依赖于任何其他带有复选框选项的视图。 INSERT INTO V2 VALUES(5) 结果出错,因为插入的行不符合 V1 的搜索条件,而 是 V2 定义的一部分。 INSERT INTO V3 VALUES(5) 结果出错,因为插入的行不符合 V1 的搜索条件。 INSERT INTO V3 VALUES(200) 尽管不符合 V3 的定义( V3 没有指定视图检查选项),但它符合 V2 的定义(指定了视图检查选项)。 CASCADED和LOCAL的区别可以通过实例得到最好的说明。 请考虑以下可更新的视图,其中x和y代表LOCAL或CASCADED:
- V1 在表 中定义。 T0
- V2 定义为 ,带有x检查选项。 V1
- V3 定义为。 V2
- V4 定义为 ,带有y检查选项。 V3
- V5 定义为。 V4
此示例显示 V1 是 V2 的基础视图 ,并且 V2 依赖于 V1。
表2 显示了在插入或更新操作期间检查搜索条件的视图:表 2. 在插入和更新操作期间检查搜索条件的视图 在
插入或
更新操作中使用的视图x = 本地
y = 本地x = 级联
y = 级联x = 本地
y = 级联x = 级联
y = 本地V1 NONE NONE NONE NONE V2 V2 V2, V1 V2 V2, V1 V3 V2 V2, V1 V2 V2, V1 V4 V4, V2 V4, V3, V2, V1 V4, V3, V2, V1 V4, V2, V1 V5 V4, V2 V4, V3, V2, V1 V4, V3, V2, V1 V4, V2, V1
备注 CREATE VIEW
- 车主特权
- 视图的所有者总是拥有该视图的“选择”权限和删除该视图的权限。 如果在创建视图之前,使用GRANT选项授予了创建视图所需的所有权限,则视图的所有者将使用GRANT选项获得SELECT权限。 否则,所有者将收到不带授权选项的“选择”权限。 例如,假设视图定义也引用了用户定义的函数。 如果所有者对用户定义函数的 EXECUTE 权限未附带 GRANT 选项,则所有者将获得视图的 SELECT 权限,且不附带 GRANT 选项。
所有者还可以获得视图的插入、更新和删除权限。 如果视图不是“只读”的,则可以获得这些特权,这意味着在fullselect的第一个FROM子句中识别出单个视图表。 在创建新视图之前,对于所有者对已识别表或视图(INSERT、UPDATE和DELETE)拥有的每个权限,所有者都会获得该视图的权限。 如果特权在桌面上或视图中以GRANT选项的形式存在,则所有者将获得GRANT选项的特权。 否则,车主将无法享受GRANT选项的特权。
通过适当的 Db2 权限,流程可以为那些没有权限创建视图的人创建视图。 拥有此类视图的用户拥有该视图的 SELECT 权限,但无 GRANT 选项,且可以删除该视图。
有关对象所有权的更多信息,请参阅授权、特权、权限、掩码和对象所有权。
- 授权查看其他用户创建的视图
- 当具有适当权限的进程为没有基础表或视图权限的其他用户创建视图时,创建的视图的 SELECT 权限将隐式授予该用户。
- 行访问控制和列访问控制注意事项
- 视图定义可能引用已激活行访问控制或列访问控制的表。 如果视图定义引用了行访问控制或列访问控制已激活的表,则在插入或更新操作期间将检查视图或基础视图中的搜索条件时,不得指定 WITH CHECK OPTION 子句。 请注意,如果搜索条件不存在,则忽略“带检查选项”子句。
- 只读视图
- 如果以下一个或多个语句与视图的定义相符,则该视图为只读视图 :
- 第一个 FROM 子句标识多个表或视图,或标识表函数、嵌套表表达式、公共表表达式或集合派生表。
- 第一个SELECT子句指定了关键字DISTINCT。
- 外层fullselect包含一个GROUP BY子句。
- 外层全选包含一个HAVING子句。
- 第一个SELECT子句包含一个聚合函数。
- 它包含一个子查询,使得外部全选和子查询的基础对象是同一个表。
- 第一个 FROM 子句用于标识只读视图。
- 第一个 FROM 子句用于标识系统维护的物化查询表。
- 外层全选不是子选择(包含集合运算符)。
只读视图不能作为SQL数据更改语句或TRUNCATE语句的对象。 在基本谓词的子查询中不能引用包含GROUP BY或HAVING的视图。
- 可插入视图
- 如果为视图定义了插入操作的“代替”触发器,或者视图至少有一列可更新(与更新的“代替”触发器无关),则可以插入视图。
- 隐式隐藏列的注意事项
- 完全选择的结果表可能包含一个被定义为隐式隐藏的基表列。 当视图定义的完全选择中明确引用了隐含隐藏的列时,就会出现这种情况。 然而,视图的相应列不会继承隐式隐藏的属性。 不能将视图列定义为隐藏。
- 测试视图定义
- 您可以通过执行 SELECT * FROM view-name 来测试视图定义的语义。
- 两种形式的视图定义
- 视图定义的来源和操作形式都存储在 Db2 目录中。 这两种形式并不一定等同,因为操作形式反映了创建视图时存在的状态。 例如,考虑如下语句:
CREATE VIEW V AS SELECT * FROM S;
在这个例子中,S是 A.T 的别名或别称,而 是一个表格,其中包含 C1、 C2 和 C3® 列。视图定义的操作形式等同于:SELECT C1, C2, C3 FROM A.T;
使用ALTER TABLE向 A.T 添加列并删除S不会影响视图定义的操作形式。 因此,如果向 A.T 添加列或重新定义S,视图定义的源形式可能会产生误导。
- 查看限制
- 视图定义不能包含对远程对象的引用。 视图定义不能映射到超过15个基本表实例。 视图定义不能引用已声明的全局临时表。
- 涉及待定义变更的限制
- 如果视图引用了有未定义更改的列,则不允许创建视图。
- 直列式LOB柱的注意事项
- 如果视图引用了包含内联LOB列的表,并且 Db2 确定内联属性可以传递给视图,则视图将继承内联属性,否则视图不会继承内联属性。
- XML列注意事项
- 如果视图有一个XML列,并且视图的基础表列有一个XML类型修饰符,则视图列具有相同的类型修饰符。 但是,如果在视图中定义了一个而不是触发器,则在插入或更新此视图时,不会强制执行类型修饰符中XML模式定义的列验证。
例子 CREATE VIEW
- 示例 1
- 创建视图 DSN8C10.VPROJRE1。 PROJNO、PROJNAME、PROJDEP、RESPEMP、FIRSTNME、MIDINIT和LASTNAME是列名。 该视图由多个表格组成,因此为只读。
CREATE VIEW DSN8C10.VPROJRE1 (PROJNO,PROJNAME,PROJDEP,RESPEMP, FIRSTNME,MIDINIT,LASTNAME) AS SELECT ALL PROJNO,PROJNAME,DEPTNO,EMPNO, FIRSTNME,MIDINIT,LASTNAME FROM DSN8C10.PROJ, DSN8C10.EMP WHERE RESPEMP = EMPNO;
在这个示例中,WHERE子句引用了列EMPNO,该列包含在某个基本表中,但不是视图的一部分。 通常,在WHERE、GROUP BY或HAVING子句中命名的列不必是视图的一部分。
- 示例 2
- 创建视图DSN8C10.FIRSTQTR ,该视图是三个全选(fullselect)的UNION ALL,分别对应2000年第一季度的每个月。 常用名称包括SNO、CHARGES和DATE。
CREATE VIEW DSN8C10.FIRSTQTR (SNO, CHARGES, DATE) AS SELECT SNO, CHARGES, DATE FROM MONTH1 WHERE DATE BETWEEN '01/01/2000' and '01/31/2000' UNION All SELECT SNO, CHARGES, DATE FROM MONTH2 WHERE DATE BETWEEN '02/01/2000' and '02/29/2000' UNION All SELECT SNO, CHARGES, DATE FROM MONTH3 WHERE DATE BETWEEN '03/01/2000' and '03/31/2000';