您必须指定您当前连接到的本地数据库中表的名称或同义词。如果设置 USETABLENAME 环境变量,则您必须使用表的名称,而不是同义词。该表可为 STANDARD、RAW 或 TEMP 类型,但您不可指定视图的名称或同义词,或 CREATE EXTERNAL TABLE 语句定义了的对象。(在 对 TRUNCATE 语句的限制 部分中罗列对 TRUNCATE 无效的表的类别。)
在符合 ANSI 的数据库中,如果您不是 table 或 synonym 的所有者,则您必须指定 owner 限定符。
在 TRUNCATE 语句开始执行之后, GBase 8s 尝试在指定的表上放置排他锁,以防止其他会话锁定该表,直到提交或回滚 TRUNCATE 语句为止。排他锁还适用于表层级之内的截断表的任何依赖表。
然而,在使用 Dirty Read 隔离级别的并发会话正在读表时,TRUNCATE 语句失败并报 RSAM -106 错误。要降低此风险,您可设置 IFX_DIRTY_WAIT 环境变量来指定 TRUNCATE 操作等待 Dirty Read 事务提交或回滚的指定的秒数。
当 TRUNCATE 操作开始时,可选的 DROP STORAGE 或 REUSE STORAGE 关键字指定数据库服务器对表的存储 extent 采取什么行动。如果您省略此规范,则 DROP STORAGE 选项是缺省的。
使用缺省的或显式的 DROP STORAGE 选项,成功的 TRUNCATE 语句释放当前分配给表及其索引的 extent 之中除了第一个 extent 之外的所有 extent。您可以 oncheck -pT table 命令显示当前的 extent 列表。如果您仅有一个 extent,则不会释放空间。
例如,对于下表,将 4 个缺省的 8 页 extent 合并到当前的第一个 extent 内。还有第二个更大的 extent:
Extents
Logical Page Physical Page Size Physical Pages
0 1:104455 32 32
32 1:104495 4576 4576
在 TRUNCATE 语句运行之后,从同一 oncheck 命令的输出显示为:
Extents
Logical Page Physical Page Size Physical Pages
0 1:104455 32 32
或者,如果您想要为随后加载的数据保持分配给同一表的相同的存储空间,请指定 REUSE STORAGE 关键字来防止该空间被分配。TRUNCATE 的 REUSE STORAGE 选项可使得引用中的存储管理更有效,在这些应用中,定期地清空同一表并以新的行重新加载。
下列示例删除 state 表,并释放它的除了第一 extent 之外的所有 extent:
TRUNCATE TABLE state DROP STORAGE;
下列示例删除同一表,但仅移除实际的数据。所有 extent 保持不变。
TRUNCATE TABLE state REUSE STORAGE;
不论您指定 DROP STORAGE 还是 REUSE STORAGE,当提交 TRUNCATE 事务时,对于表的所有行,释放任何行外数据值。还释放在 TRUNCATE 事务中不再被引用的任何 BLOB 或 CLOB 值所占据的存储。
GBase 8s 为支持在永久表和临时表的列上的 TRUNCATE 操作的主访问方式提供内建的 am_truncate 目的函数。它还为 B 树索引上的 TRUNCATE 操作的辅助访问方式提供内建的 am_truncate 目的函数。
为了 TRUNCATE 语句在虚拟表接口(VTI)中正确地运行,在主访问方式中为 VTI 表的数据类型需要有效的 am_truncate 目的函数。要在数据库中注册新的主访问方式,请使用 SQL 的 CREATE PRIMARY ACCESS_METHOD 语句:
CREATE PRIMARY ACCESS_METHOD vti(
AM_GETNEXT = vti_getnext
AM_TRUNCATE = vti_truncate
...);
您还可使用 ALTER ACCESS_METHOD 语句来将有效的 am_truncate 目的函数添加到一没有 am_truncate 目的函数的现有的访问方式:
ALTER ACCESS_METHOD abc (ADD AM_TRUNCATE = abc_truncate);
在这些示例中,vti_truncate 和 abc_truncate 函数必须是支持 AM_TRUNCATE 目标选项关键字的功能的例程,且通过 CREATE FUNCTION 或 CREATE ROUTINE FROM 语句预先在数据库中注册了。
TRUNCATE 语句不等同于 DROP TABLE。在 TRUNCATE 成功地执行之后,指定的 table 及其所有列和索引仍注册在数据库中,但没有数据行。在一定的时间间隔之后要求替换表中所有记录的信息管理应用中,TRUNCATE 比同等的 DROP TABLE、CREATE TABLE,以及要定义任何同义词、视图、约束、触发器、权限、分片方案和其他属性以及表的相关联的数据库对象,需要对系统目录的较少更新。
在不需要表的现有行的上下文中,与使用不带有 WHERE 子句的 DELETE 语句来清空表相比,TRUNCATE 语句通常更有效率,因为 TRUNCATE 比 DELETE 需要更少的资源和更低的日志记录开销:
当表有带有下列属性的一个或多个列时,TRUNCATE 胜于 DELETE 的这些性能优势会降低:
这些特性的每一个都需要数据库服务器读取表的每一行,大幅降低 TRUNCATE 的速度。
如果表包括一个或多个您已为其注册了 am_truncate( ) 目的函数的 UDT,则 TRUNCATE 与 DELETE 之间的性能差异会在为 TRUNCATE 调用 am_truncate 接口一次与为每一行调用 destroy( ) 支持函数的相对成本上反映出来。
像在下一部分中罗列的那样,某些条件导致 TRUNCATE 失败并报错。这些条件中的某些在 DELETE 操作上没有影响,因此在那些情况下,您以 DELETE 语句移除所有行会更有效,如在 customer 表上的下列操作所示:
DELETE customer;
仅当设置 DELIMIDENT 环境变量时,才可省略紧跟在 DELETE 之后的 FROM 关键字,如在此示例中那样。
如果存在下列任何条件,则 TRUNCATE 语句失败: