公共表表达式
公共表表达式允许使用 table-name 定义结果表,该结果表可在随后的全查询的任何 FROM 子句中指定为表名称。
可以在单个 WITH 关键字后面指定多个公共表表达式。 指定的每个公共表表达式也可以通过后续公共表表达式的 FROM 子句中的名称引用。
如果指定了列的列表,那么它必须由与全查询的结果表中的列数一样多的名称组成。 每个 column-name 必须唯一且未限定。 如果未指定这些列名,那么这些名称将从用于定义公共表表达式的全查询的选择列表中派生。
在同一语句中,公共表表达式的 table-name 必须与任何其他公共表表达式 table-name 不同 (SQLSTATE 42726)。 如果在 INSERT 语句中指定了公共表表达式,那么 table-name 不能与作为插入对象的表名称或视图名称相同 (SQLSTATE 42726)。 在整个全查询中,可以将公共表表达式 table-name 指定为任何 FROM 子句中的表名。 公共表表达式的 table-name 将覆盖具有相同限定名的任何现有表、视图或别名(在目录中)。
如果在同一语句中定义了多个公共表表达式,那么不允许在公共表表达式之间进行循环引用 (SQLSTATE 42835)。 创建两个公共表表达式 dt1 和 dt2 时,会发生循环引用,以便 dt1 引用 dt2,而 dt2 引用 dt1。
如果公共表表达式的全查询在 FROM 子句中包含 data-change-table-reference,那么该公共表表达式将被描述为修改数据。 在处理语句时始终对修改数据的公共表表达式进行求值,而不考虑是否在语句中的任何其他位置使用公共表表达式。 如果至少有一个用于读取或修改数据的公共表表达式,那么所有公共表表达式都将按其发生顺序进行处理,并且每个读取或修改数据的公共表表达式都将在执行任何后续公共表表达式之前完全执行,包括所有约束和触发器。
在 CREATE VIEW 和 INSERT 语句中的全查询之前,公共表表达式也是可选的。
- 代替视图以避免创建视图(不需要对视图进行一般使用,并且不使用定位更新或删除)
- 要启用按从标量子查询或函数派生而来的列进行分组,请执行以下操作:不确定或具有外部操作
- 当必需的结果表基于主变量时
- 当必须在全查询中共享同一结果表时
- 当必须使用递归来派生结果时
- 当必须在查询中处理多个 SQL 数据更改语句时
如果公共表表达式的全查询在 FROM 子句中包含对其自身的引用,那么该公共表表达式是递归公共表表达式。 使用递归的查询在支持诸如材料清单 (BOM),预留系统和网络规划之类的应用程序方面很有用。
对于递归公共表表达式,必须满足以下条件:
- 作为递归循环的一部分的每个全查询都必须以 SELECT 或 SELECT ALL 开头。 不允许使用 SELECT DISTINCT (SQLSTATE 42925)。 此外,联合必须使用 UNION ALL (SQLSTATE 42925)。
- 必须在公共表表达式的 table-name 之后指定这些列名 (SQLSTATE 42908)。
- 第一个并集(初始化全查询)的第一个全查询不得包含对任何 FROM 子句中的公共表表达式的任何列的引用 (SQLSTATE 42836)。
- 如果在迭代全查询中引用了公共表表达式的列名,那么将根据初始化全查询来确定该列的数据类型,长度和代码页。 迭代全查询中的相应列必须具有与根据初始化全查询和代码页必须匹配而确定的数据类型和长度相同的数据类型和长度 (SQLSTATE 42825)。 但是,对于字符串类型而言,这两种数据类型的长度可能不同。 在此情况下,迭代全查询中的列必须具有始终可分配给从初始化全查询所确定的长度的长度。
- 作为递归循环的一部分的每个全查询都不得包含任何聚集函数,按子句分组或 having 子句 (SQLSTATE 42836)。
这些全查询的 FROM 子句最多可以包含一个对公共表表达式的引用,该表达式是递归循环的一部分 (SQLSTATE 42836)。
- 迭代全查询和整体递归全查询不得包含 order-by-clause (SQLSTATE 42836)。
- 子查询(标量或量化的)不能是任何递归循环的一部分 (SQLSTATE 42836)。
- 在迭代全查询中,一个整数列以常量递增。
- 迭代全查询的 where 子句中的谓词,格式为“counter_col < constant”或“counter _col < :hostvar”。
如果在递归公共表表达式中找不到此语法,那么将发出警告 (SQLSTATE 01605)。
