公共表表达式
一个通用的表表达式定义了一个结果表,该表带有表标识符 ,可以在后续全选语句的任何 FROM 子句中引用。
可以在单个 WITH 关键字后面指定多个公共表表达式。 每个指定的公共表表达式也可以在后续公共表表达式的 FROM 子句中按名称引用。
如果指定了列的列表,那么它必须由与全查询的结果表中的列数一样多的名称组成。 每个 column-name 必须唯一且未限定。 如果没有指定这些列名,则从用于定义公共表表达式的全选列表中选择。
表标识符必须是无限制的SQL标识符,且必须与同一语句中的任何其他表标识符不同。 如果在INSERT语句中指定了公共表表达式,则表标识符不能与作为插入对象的表或视图名称相同。 如果在CREATE VIEW语句中指定了公共表表达式,则表标识符不能与创建的视图名称相同。 在fullselect的任何FROM子句中,一个通用的表表达式表标识符都可以被指定为表名。
如果同一语句中定义了多个公共表表达式,则不允许公共表表达式之间存在循环引用。 创建两个公共表表达式 dt1 和 dt2 时,会发生循环引用,以便 dt1 引用 dt2,而 dt2 引用 dt1。 此外,之前定义的公共表表达式不能引用后续公共表表达式。
普通表表达式名称只能在定义它的 select语句、SELECT INTO语句、INSERT语句、CREATE VIEW语句或RETURN语句中引用。
如果触发器定义中不包含的 SELECT语句、SELECT INTO语句、INSERT语句或CREATE VIEW语句引用了非限定表名,则应遵循以下规则确定实际引用的表:
- 如果不合格的名称与 select语句中指定的一个或多个公共表表达式名称相对应,则该名称标识最内层作用域中的公共表表达式。
- 否则,该名称标识的是默认模式中存在的持久表、临时表或视图。
如果触发器定义中的 SELECT语句、SELECT INTO语句、INSERT语句或CREATE VIEW语句引用了非限定表名,则将应用以下规则来确定实际引用的表:
- 如果不合格的名称与 select语句中指定的一个或多个公共表表达式名称相对应,则该名称标识最内层作用域中的公共表表达式。
- 如果不合格的名称与过渡表名称一致,则该名称标识该过渡表。
- 否则,该名称标识的是默认模式中存在的持久表、临时表或视图。
在CREATE VIEW和INSERT语句中,在fullselect之前,也可以选择使用普通表表达式。 但是,在SELECT语句中的INSERT中不允许使用常见的表表达式。
可以使用常见的餐桌表达:
- 代替视图以避免创建视图(不需要对视图进行一般使用,并且不使用定位更新或删除)
- 当所需的结果表基于宿主变量时
- 当需要在全查询中共享同一个结果表时
- 当需要使用递归得出结果时
如果公共表表达式的全查询在 FROM 子句中包含对自身的引用,那么该公共表表达式就是递归公共表表达式。 使用递归的查询在支持诸如材料清单 (BOM),预留系统和网络规划之类的应用程序方面很有用。
- 递归循环中的每个全选操作必须以“选择”或“全选”开头。 不允许使用 SELECT DISTINCT。 此外,场景操作员必须使用ALL关键字。
- 列名必须紧跟在公共表表达式的表名之后。
- 第一个全选操作符 (初始化全选 )的任何 FROM 子句中不得包含对公共表表达式的引用。
- 如果迭代全选引用了公共表表达式的列名,则该列的数据类型、长度和CCSID将根据初始化全选确定。 迭代全选中的相应列必须具有与根据初始化全选确定的数据类型和长度相同的数据类型和长度,并且CCSID必须匹配。 但是,对于字符串类型而言,这两种数据类型的长度可能不同。 在这种情况下, 迭代全选中的列长度必须始终与初始化全选确定的长度一致。 如果递归公共表表达式的列在定义中没有递归使用,则该列的数据类型、长度和CCSID由与非递归查询关联的规则确定。
递归循环中的每个全选(fullselect) 都不得包含任何聚合函数、GROUP BY子句、HAVING子句、ORDER BY子句、OFFSET子句或FETCH FIRST子句。 这些全选中的 FROM 子句最多可以引用一次作为递归循环一部分的公共表表达式。
- 子查询(标量或量化)不得成为任何递归循环的一部分。
- 外部连接不能成为任何递归循环的一部分。
递归公共表表达式中引用的所有列对于查询都是空值,即使它们被定义为非空值。
当开发递归公共表表达式时,请记住可以创建无限递归循环(循环)。 检查递归循环是否终止。 如果涉及的数据是循环的,那么这一点尤其重要。 期望递归公共表表达式包含一个谓词,该谓词将阻止无限循环。 期望递归的公共表表达式包括:
- 在迭代的全选操作中 ,整数列按常数递增。
- 在WHERE子句中,以 “counter_col < constant ”或 “counter_col < :hostvar ”的形式出现。 如果找不到此语法,则会发出警告。
如果递归公共表表达式的结果用于导出最终结果表,并且如果列掩码用于屏蔽最终结果表中的列值,则列掩码不能应用于递归公共表表达式的全选中所指定的列。
