DECLARE GLOBAL TEMPORARY TABLE 语句
DECLARE GLOBAL TEMPORARY TABLE 语句可为当前会话定义一个临时表。
已声明临时表的描述未出现在系统目录中。 它不是持久的,并且不能与其他会话共享。 每个定义了同名的已声明全局临时表的会话都针对该临时表提供了自己的唯一描述。 当该会话终止时,将删除该表的行并删除该临时表的描述。
调用
此语句可以嵌入在应用程序中,也可通过动态 SQL 语句来发出。 它是可动态准备的可执行语句。
权限
- USER TEMPORARY 表空间的 USE 特权
- DBADM 权限
- SYSADM 权限
- SYSCTRL 权限
- 表或视图的 SELECT 特权
- 包含表或视图的模式的 SELECTIN 特权
- 该表或视图上的 CONTROL 特权
- 包含表或视图的模式上的模式 DATAACCESS 权限
- DATAACCESS 权限
语法
- 1 The FOR BIT DATA clause can be specified in any order with the other column constraints that follow. The FOR BIT DATA clause cannot be specified with string units CODEUNITS32 (SQLSTATE 42613).
描述
- table-name
- 指定临时表。 如果明确指定了限定符,那么限定符必须是 SESSION,否则将返回错误 (SQLSTATE 428EK)。 如果未指定限定符,那么将隐式分配 SESSION。
每个使用相同 table-name 定义已声明临时表的会话都对已声明的临时表提供了自己的唯一描述。 如果 table-name 标识会话中已存在的已声明临时表,那么必须指定 WITH REPLACE 子句 (SQLSTATE 42710)。
目录中可能已经存在具有相同名称和模式名称 SESSION 的表、视图、别名或昵称。 在这种情况下:- 仍然可以定义已声明的临时表 table-name,并且不返回任何错误或警告。
- 对 SESSION.table-name 的任何引用都将解析为已声明的临时表,而不是已在目录中定义的 SESSION.table-name。
- column-definition
- 定义临时表的列的属性。
- 列名称
- 指定表列。 名称不能限定,并且同一名称不能用于表的多列 (SQLSTATE 42711)。按行组织的表可以具有以下属性:
- 最多包含 500 列的 4K 页面大小,其中列的字节数不得大于 4005。
- 最多包含 1012 列的 8K 页面大小,其中列的字节数不得大于 8101。
- 最多包含 1012 列的 16K 页面大小,其中列的字节数不得大于 16,293。
- 最多包含 1012 列的 32K 页面大小,其中列的字节数不得大于 32,677。
不论页面大小如何,按列组织的表都最多可以包含 1012 列。 每列的字节数不得超过 32,677。 扩展行大小支持不适用于按列组织的表。
创建的临时表不能包含 row-begin 列、row-end 列或 transaction-start-ID 列。
有关更多详细信息,请参阅 CREATE TABLE 语句中的
行大小
。 - data-type
- 指定列的数据类型
- 内置类型
- 指定内置数据类型。 请参阅
CREATE TABLE
以获取 内置类型的描述。不能为已声明的临时表指定 SYSPROC.DB2SECURITYLABEL 数据类型。
- column-options
- 定义与表列相关的其他选项。
- NOT NULL
- 防止列包含空值。 有关空值的规范,请参阅 CREATE TABLE 语句中的 NOT NULL。
- default-clause
- 指定列的缺省值。
- WITH
- 可选关键字。
- 缺省值
- 如果在 INSERT 上未提供值,或者在 INSERT 或 UPDATE 上将值指定为 DEFAULT,那么将提供缺省值。 如果在 DEFAULT 关键字之后未指定缺省值,那么缺省值取决于列的数据类型,如
ALTER TABLE
中所示。如果该列基于输入表的列,那么在定义缺省值时必须指定特定的缺省值。 不能为输入表的对象标识列指定缺省值 (SQLSTATE 42997)。
如果使用单值类型定义了某个列,那么该列的缺省值是强制转换为单值类型的源数据类型的缺省值。
如果使用结构化类型定义了某个列,那么无法指定 default-clause (SQLSTATE 42842)。
在 column-definition 中省略 DEFAULT 会导致使用空值作为该列的缺省值。 如果将此类列定义为 NOT NULL,那么该列没有有效的缺省值。
- default-values
- 下面是可指定的特定类型的缺省值。
- constant
- 将常量指定为该列的缺省值。 指定的常量必须:
- 表示可根据赋值规则分配给该列的值
- 不是浮点常量,除非使用浮点数据类型定义该列
- 如果该列的数据类型是十进制浮点,那么为数字常量或十进制浮点特殊值。 如果目标列是 DECFLOAT,那么首先会将浮点常量解释为 DOUBLE,然后将其转换为十进制浮点。 对于 DECFLOAT(16) 列,精度大于 16 位的十进制常量将使用 CURRENT DECFLOAT ROUNDING MODE 专用寄存器指定的取整模式进行取整。
- 如果常量是十进制常量(例如,1.234 不能是 DECIMAL(5,2) 列的缺省值),那么不能包含超出列数据类型小数位数的非零数字
- 用不超过 254 个字节表示,包括引号字符、任何引导字符(例如,X 表示十六进制常量)以及标准函数名称和括号中的字符(当常量是 cast-function 的参数时)
- datetime-special-register
- 将在执行 INSERT、UPDATE 或 LOAD 时日期时间专用寄存器(CURRENT DATE、CURRENT TIME 或 CURRENT TIMESTAMP)的值指定为该列的缺省值。 该列的数据类型必须是与指定的专用寄存器对应的数据类型(例如,指定 CURRENT DATE 时,数据类型必须是 DATE)。
- user-special-register
- 将在执行 INSERT、UPDATE 或 LOAD 时用户专用寄存器(CURRENT USER、SESSION_USER、SYSTEM_USER)的值指定为该列的缺省值。 该列的数据类型必须是长度不小于用户专用寄存器的长度属性的字符串。 请注意,可以指定 USER 来代替 SESSION_USER,并且可以指定 CURRENT_USER 来代替 CURRENT USER。
- CURRENT SCHEMA
- 将在执行 INSERT、UPDATE 或 LOAD 时 CURRENT SCHEMA 专用寄存器的值指定为该列的缺省值。 如果指定了 CURRENT SCHEMA,那么该列的数据类型必须是长度大于或等于 CURRENT SCHEMA 专用寄存器的长度属性的字符串。
- NULL
- 指定空值作为列的缺省值。 如果指定了 NOT NULL,那么可以在同一列定义中指定 DEFAULT NULL,但在尝试将列设置为缺省值时会出现错误。
- cast-function
- 这种形式的缺省值只能用于定义为单值类型、BLOB 或日期时间(DATE、TIME 或 TIMESTAMP)数据类型的列。 对于单值类型,该函数的名称必须与该列的单值类型的名称匹配(基于 BLOB 或日期时间类型的单值类型除外)。 如果使用模式名进行限定,那么它必须与单值类型的模式名相同。 如果未进行限定,那么函数解析中的模式名必须与单值类型的模式名相同。 对于基于日期时间类型的单值类型(缺省值是一个常量),必须使用一个函数,并且该函数的名称必须与其隐式或显式模式名为 SYSIBM 的单值类型的源类型名称匹配。 对于其他日期时间列,也可以使用相应的日期时间函数。 对于 BLOB 或基于 BLOB 的单值类型,必须使用一个函数,并且该函数的名称必须是隐式或显式模式名为 SYSIBM 的 BLOB。
- constant
- 指定一个常量作为参数。 该常量必须符合单值类型的源类型或非单值类型的数据类型的常量规则。 如果 cast-function 是 BLOB,那么常量必须是字符串常量。
- datetime-special-register
- 指定 CURRENT DATE、CURRENT TIME 或 CURRENT TIMESTAMP。 该列的单值类型的源类型必须是与指定的专用寄存器对应的数据类型。
- user-special-register
- 指定 CURRENT USER、SESSION_USER 或 SYSTEM_USER。 该列的单值类型的源类型的数据类型必须是长度至少为 8 字节的字符串数据类型。 如果 cast-function 是 BLOB,那么长度属性必须至少为 8 个字节。
- CURRENT SCHEMA
- 指定 CURRENT SCHEMA 专用寄存器的值。 该列的单值类型的源类型的数据类型必须是长度大于或等于 CURRENT SCHEMA 专用寄存器的长度属性的字符串。 如果 cast-function 是 BLOB,那么长度属性必须至少为 8 个字节。
- EMPTY_CLOB()、EMPTY_DBCLOB() 或 EMPTY_BLOB()
- 指定长度为零的字符串作为该列的缺省值。 该列必须具有与函数的结果数据类型相对应的数据类型。
如果指定的值无效,那么将返回错误 (SQLSTATE 42894)。
- IDENTITY 和 identity-options
- 有关标识列的规范,请参阅
CREATE TABLE
中的 IDENTITY 和 identity-options。
- LIKE table-name1 或 view-name 或 nickname
- 指定该表的列具有与所标识表 (table-name1)、视图 (view-name) 或昵称 (nickname) 的列完全相同的名称和描述。 在 LIKE 之后指定的名称必须标识存在于目录或已声明的临时表中的表、视图或昵称。 不能指定类型化表或类型化视图 (SQLSTATE 428EC)。 不能指定受保护的表 (SQLSTATE 42962)。不能指定其某个列定义为 IMPLICITLY HIDDEN 的表 (SQLSTATE 560AE)。 使用 LIKE 将隐式定义 n 列,其中 n 是所标识的表(包括隐式隐藏的列)、视图或昵称中的列数。 隐式定义取决于 LIKE 之后标识的内容。
- 如果标识了一个表,那么隐式定义包括 table-name1 的各列的列名、数据类型和可空性特征。 如果未指定 EXCLUDING COLUMN DEFAULTS,那么还包括列缺省值。
- 如果标识了一个视图,那么隐式定义包括 view-name 中定义的全查询的各结果列的列名、数据类型和可空性特征。 视图列的数据类型必须是对表列有效的数据类型。
- 如果标识了一个昵称,那么隐式定义包括 nickname 的各列的列名、数据类型和可空性特征。
如果在 LIKE 子句中标识了一个表并且该表包含 ROW CHANGE TIMESTAMP 列,那么新表的对应列仅继承 ROW CHANGE TIMESTAMP 列的数据类型。 不会将新列视为生成的列。
如果对 table-name1 强制施加行或列级别访问控制 (RCAC),那么新表不会继承 RCAC。
- AS (fullselect)
- 指定对于 fullselect 的派生结果表中的每一列,将为该表定义一个对应的列。 定义的每一列将沿用结果表相应列的以下属性(如果适用于该数据类型):
- 列名
- 列描述
- 数据类型、长度、精度和小数位
- 可空性
不包括以下属性(尽管可以使用 copy-options 包括缺省值和身份属性):- 缺省值
- 身份属性
- 隐藏的属性
- ROW CHANGE TIMESTAMP
- 全查询中引用的表或视图的任何其他可选属性
下列限制适用:- 每个选择列表元素都必须具有唯一名称 (SQLSTATE 42711)。 可以在 Select 子句中使用 AS 子句来提供唯一名称。
- 全查询不能引用主机变量或包含参数标记。
- 全查询结果列的数据类型必须是对表列有效的数据类型。
- 如果为全查询中指定的任何表激活了行或列级别访问控制 (RCAC),那么不会将 RCAC 级联到新表。
- WITH NO DATA | WITH DATA
- 确定是否用数据填充表列:
- WITH NO DATA
- 不执行全查询。 它仅用于定义未填充查询结果的表。
- WITH DATA
- 执行全查询并使用查询结果填充表。
- copy-options
- 这些选项指定是否复制源结果表定义(表、视图或全查询)的其他属性。
- INCLUDING COLUMN DEFAULTS
- 将复制源结果表定义的每个可更新列的列缺省值。 不可更新的列不会在所创建表的相应列中定义缺省值。
如果指定了 LIKE table-name1,并且 table-name1 标识了基本表、创建的临时表或已声明的临时表,那么 INCLUDING COLUMN DEFAULTS 是缺省值。
- EXCLUDING COLUMN DEFAULTS
- 不会从源结果表定义中复制列缺省值。
除非指定了 LIKE table-name 并且 table-name 标识了基本表、创建的临时表或已声明的临时表,否则此子句是缺省子句。
- INCLUDING IDENTITY COLUMN ATTRIBUTES
- 如果可用,那么将从源的结果表定义中复制身份列属性(START WITH、INCREMENT BY 和 CACHE 值)。 如果表、视图或全查询中对应列的元素是表的列名或视图的列名(将直接或间接映射到具有身份属性的基本表或创建的临时表的列名),那么可以复制这些属性。 在所有其他情况下,新临时表的列将不具有身份属性。 例如:
- 全查询的选择列表包含身份列名称的多个实例(即多次选择同一列)
- 全查询的选择列表包含多个身份列(即涉及到一个连接)
- 身份列包含在选择列表的表达式中
- 全查询包括一个集合操作(union、except 或 intersect)。
- EXCLUDING IDENTITY COLUMN ATTRIBUTES
- 不会从源结果表定义中复制身份列属性。
- ORGANIZE BY
- 指定数据在表的数据页中的组织方式:
- ROW
- 数据按行存储在表的数据页中。 每个数据页都会存储表中一行或多行的数据。
- COLUMN
- 数据按列存储在表的数据页中。 每个数据页都存储该表的一列数据。
缺省值由 dft_table_org 数据库配置参数的值确定。
- ON COMMIT
- 指定在执行 COMMIT 操作时对全局临时表执行的操作。 缺省值为 DELETE ROWS。
- DELETE ROWS
- 如果在表上没有打开 WITH HOLD 游标,那么将删除该表中的所有行。
- PRESERVE ROWS
- 将保留表的行。
- LOGGED 或 NOT LOGGED
- 指定是否记录表的操作。 缺省值为 LOGGED。
- LOGGED
- 指定将记录对表执行的插入、更新或删除操作以及表创建或删除操作。
- NOT LOGGED
- 指定将不记录对表执行的插入、更新或删除操作,但会记录表创建或删除操作。 在 ROLLBACK(或 ROLLBACK TO SAVEPOINT)操作期间:
- 如果已在工作单元(或保存点)中创建了该表,那么将删除该表
- 如果已在工作单元(或保存点)中删除了该表,那么将重新创建该表,但该表不含任何数据
- ON ROLLBACK
- 指定在执行 ROLLBACK(或 ROLLBACK TO SAVEPOINT)操作时要对未记录的全局临时表执行的操作。 缺省值为 DELETE ROWS。
- DELETE ROWS
- 如果表数据已发生更改,那么将删除所有行。
- PRESERVE ROWS
- 将保留表的行。
注: 使用 NOT LOGGED ON ROLLBACK PRESERVE ROWS 声明的全局临时表不能按列组织。
- WITH REPLACE
- 指示如果已存在具有指定名称的已声明临时表,那么现有表将替换为该语句所定义的临时表(并删除现有表的所有行)。
如果未指定 WITH REPLACE,那么指定的名称不能标识当前会话中已存在的已声明临时表 (SQLSTATE 42710)。
- IN tablespace-name
- 标识要在其中实例化已声明的临时表的表空间。 此表空间必须存在并且是 USER TEMPORARY 表空间 (SQLSTATE 42838),而该语句的授权标识具有此表空间的 USE 特权 (SQLSTATE 42501)。 如果未指定此子句,那么将通过选择具有最小足够页大小的 USER TEMPORARY 表空间来确定表的表空间(该语句的授权标识具有该表空间的 USE 特权)。 如果有多个表空间符合条件,那么将根据获得 USE 特权的对象来分配优先级:
- 授权标识
- 授权标识所属的组
- PUBLIC
可以在以下情况下更改表空间的决定:- 删除或创建表空间
- 授予或撤销 USE 特权
表的足够页面大小由行的字节数或列数确定。 有关更多详细信息,请参阅 CREATE TABLE 语句中的
行大小
。 - distribution-clause
- 指定数据库分区或跨多个数据库分区分布数据的方式。
- DISTRIBUTE BY HASH (column-name, ...)
- 指定在特定列(称为分布键)上使用缺省散列函数作为跨数据库分区的分布方法。 column-name 必须是标识表列的非标准名称 (SQLSTATE 42703)。 不能多次标识同一列 (SQLSTATE 42709)。 数据类型为 BLOB、CLOB、DBCLOB、XML、基于任何这些类型的单值类型或结构化类型的列不能用作分布键的一部分 (SQLSTATE 42962)。
如果未指定此子句,并且表驻留在具有多个数据库分区的多分区数据库分区组中,那么将自动定义缺省分发键。
如果所有列都不满足缺省分布键的要求,那么将创建一个不含任何列的表。 只有在单分区数据库分区组上定义的表空间中才允许此类表。
对于在单分区数据库分区组上定义的表空间中的表,可使用任何具有对分布键有效的数据类型的列集合来定义分布键。 如果未指定此子句,那么不会创建分布键。
注意
- 必须存在用户临时表空间,然后才能声明已声明的临时表 (SQLSTATE 42727)。
- 引用已声明的临时表:已声明的临时表的描述不会显示在数据库目录 (SYSCAT.TABLES) 中;因此,它不是持久的,并且在数据库连接中不可共享。 这意味着,定义了名为 table-name 的已声明临时表的每个会话都对这个已声明全局临时表提供了自己的唯一描述。
为了在 SQL 语句(DECLARE GLOBAL TEMPORARY TABLE 语句除外)中引用已声明的临时表,必须通过模式名 SESSION 显式或隐式限定该表。 如果 SESSION 未限定 table-name,那么在解析引用时不会考虑已声明的临时表。
对于连接中对 SESSION.table-name 的引用,如果此引用没有使用该名称声明已声明的临时表,那么将尝试从目录中的持久对象进行解析。 如果不存在此类对象,那么将发生错误 (SQLSTATE 42704)。
- 如果绑定的包中有静态 SQL 语句引用了由 SESSION 隐式或显式限定的表,那么将不会静态绑定这些语句。 不论在绑定包时是否选择了 VALIDATE 选项,都会在调用这些语句时逐步绑定这些语句。 在运行时,每个表引用都将解析为已声明的临时表(如果存在)、已创建的临时表或永久表。 如果不存在,那么将引发错误 (SQLSTATE 42704)。
- 特权:定义已声明的临时表时,会向该表的定义者授予该表的所有表特权,包括删除表的能力。 此外,还会向 PUBLIC 授予这些特权。 (使用 GRANT 选项不会授予其中任何特权,并且所有这些特权都不会出现在目录表中。) 这使得会话中的任何 SQL 语句都可以引用已在该会话中定义的已声明临时表。
- 实例化和终止:在以下解释中,P 表示一个会话,T 是会话 P 中声明的临时表:
- 通过在 P 中执行的 DECLARE GLOBAL TEMPORARY TABLE 语句创建了一个空的 T 实例。
- P 中的任何 SQL 语句都可以引用 T,并且 P 中对 T 的任何引用都是对同一个 T 实例的引用。
- 如果在 SQL 过程复合语句(由 BEGIN 和 END 定义)中指定了 DECLARE GLOBAL TEMPORARY TABLE 语句,那么已声明的临时表的范围是连接,而不仅仅是复合语句,并且在复合语句之外也可以识别该表。 不会在复合语句的 END 处隐式删除该表。 不能在该会话的其他复合语句中使用相同名称多次定义已声明的临时表,除非已显式删除了该表。
- 假设隐式或显式指定了 ON COMMIT DELETE ROWS 子句,当落实操作终止 P 中的一个工作单元,并且 P 中没有依赖于 T 的 WITH HOLD 打开游标时,落实过程将包括 DELETE FROM SESSION.T 操作。
- 如果回滚操作终止 P 中的一个工作单元或保存点,并且该工作单元或保存点包含对 SESSION.T 的修改:
- 如果指定了 NOT LOGGED,那么除非还指定了 ON ROLLBACK PRESERVE ROWS,否则将删除 SESSION.T 中的所有行
- 如果未指定 NOT LOGGED,那么将撤销对 T 的更改
- 如果指定了 NOT LOGGED 并且 INSERT、UPDATE 或 DELETE 语句在执行期间失败(与编译错误相反),那么将删除 SESSION.T 中的所有行。
- 如果回滚操作终止 P 中的一个工作单元或保存点,并且该工作单元或保存点包含 SESSION.T 的声明,那么回滚过程将包括 DROP SESSION.T 操作。
- 如果回滚操作终止了 P 中的一个工作单元或保存点,并且该工作单元或保存点包含对已声明临时表 SESSION.T 的删除,那么回滚将撤销对该表的删除。 如果指定了 NOT LOGGED,那么也会清空该表。
- 如果声明了 T 的应用程序进程终止或与数据库断开连接,那么将删除 T 并销毁其实例化的行。
- 如果与用于声明 T 的服务器的连接终止,那么将删除 T 并销毁其实例化的行。
- 已声明的临时表的使用限制:已声明的临时表不能:
- 在 ALTER、COMMENT、GRANT、LOCK、RENAME 或 REVOKE 语句中指定 (SQLSTATE 42995)。
- 在 AUDIT、CREATE ALIAS 或 CREATE VIEW 语句中引用 (SQLSTATE 42995)。
- 在引用约束中指定 (SQLSTATE 42995)。
- 已声明临时表支持数据行压缩。 如果数据库管理器确定性能有所提升,那么将压缩包含已内联存储在基本表对象中的 XML 文档的表行数据。 但是,不支持对已声明临时表的 XML 存储对象进行数据压缩。
- 对于在已声明的临时表上创建的索引,已启用索引压缩。
- 对于在已声明的临时表上创建的索引,缺省情况下已启用索引压缩。 压缩将显示为 on ,但如果未应用正确的许可证 (IBM Db2® Storage Optimization Feature) ,那么不会压缩索引。
- 替代语法:以下替代语法不是标准语法。 支持这些语法,以便与早期产品版本或其他数据库产品兼容。
- 可以指定 DEFINITION ONLY 来代替 WITH NO DATA。
- 可以指定 PARTITIONING KEY 子句或 DISTRIBUTE ON 子句来代替 DISTRIBUTE BY 子句。
- 指定日期时间专用寄存器的值时,可以指定 NOW() 来代替 CURRENT_TIMESTAMP。
- 在 CHAR 或 VARCHAR 列定义中,您不需要显式指定 CCSID;将自动使用正确的 CCSID。 但是,如果您明确指定了 CCSID,它必须对应于所使用的数据库类型:
CCSID ASCII(针对非 Unicode 数据库)CCSID UNICODE(对于 unicode 数据库)
示例
- 示例 1:定义一个已声明的临时表,其中包含员工编号、薪水、奖金和佣金的列定义。
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMP (EMPNO CHAR(6) NOT NULL, SALARY DECIMAL(9, 2), BONUS DECIMAL(9, 2), COMM DECIMAL(9, 2)) ON COMMIT PRESERVE ROWS - 示例 2:假设存在基本表 USER1.EMPTAB 并且它包含三列(其中一列是身份列)。 声明一个与基本表具有相同列名和属性(包括身份属性)的临时表。
在此示例中,SESSION 将用作 TEMPTAB1 的隐式限定符。DECLARE GLOBAL TEMPORARY TABLE TEMPTAB1 LIKE USER1.EMPTAB INCLUDING IDENTITY ON COMMIT PRESERVE ROWS
Netezza Performance Server (NPS) 临时表的兼容性
如果需要声明临时表,那么建议使用 DECLARE GLOBAL TEMPORARY TABLE 语句。 但是,要提供与 IBM® Netezza® SQL 的兼容性,可以改为使用 CREATE TEMPORARY TABLE 语句。- 为了能够在 STATIC SQL 中引用已声明的临时表,必须使用 VALIDATE RUN 绑定该包。
- 因此,会话使用包缓存的能力可能会受到阻碍。
- 模式名不能以 SYS 开头 (SQLSTATE 42939)。
- 列定义列表。
- DISTRIBUTE BY HASH 子句。 为了实现兼容性,可以指定 DISTRIBUTE ON HASH 作为替代方法。
- AS fullselect 子句。 请注意,全查询未包含在括号中,就像为 DECLARE GLOBAL TEMPORARY TABLE 指定的那样。
CREATE TEMPORARY TABLE table_name (column_definition) AS fullselect
DECLARE GLOBAL TEMPORARY TABLE table_name (column_definition) AS (fullselect) WITH DATA
ON COMMIT PRESERVE ROWS LOGGED