TRUNCATE — 清空一个表或者一组表
TRUNCATE [ TABLE ] [ ONLY ] name
[ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ DROP STORAGE ] [ CASCADE | RESTRICT ]
TRUNCATE
可以从一组表中快速地移除所有行。
它具有和在每个表上执行无条件DELETE
相同的
效果,不过它会更快,因为它没有实际扫描表。此外,它会立刻回收磁盘空间,
而不是要求一个后续的VACUUM
操作。在大表上
它最有用。
name
要截断的表的名字(可以是模式限定的)。如果在表名前指定了
ONLY
,则只会截断该表。如果没有指定ONLY
,
该表及其所有后代表(如果有)都会被截断。可选地,可以在表名后指定
*
来显式地包括后代表。
RESTART IDENTITY
自动重新开始被截断表的列所拥有的序列。
CONTINUE IDENTITY
不更改序列值。这是默认值。
DROP STORAGE
为了兼容Oracle数据库的语法,仅是一个语法糖。
CASCADE
自动截断所有对任一所提及表有外键引用的表以及任何由于
CASCADE
被加入到组中的表。
RESTRICT
如果任一表上具有来自命令中没有列出的表的外键引用,则拒绝截断。这是默认值。
要截断一个表,你必须具有其上的TRUNCATE
特权。
TRUNCATE
在要操作的表上要求一个
ACCESS EXCLUSIVE
锁,这会阻塞所有其他在该表上的
并发操作。当指定RESTART IDENTITY
时,任何需要被
重新开始的序列也会被排他地锁住。如果要求表上的并发访问,那么
应该使用DELETE
命令。
TRUNCATE
不能被用在被其他表外键引用的表上,
除非那些表也在同一个命令中被阶段。这些情况中的可行性检查将会
要求表扫描,并且重点不是为了做扫描。CASCADE
选项可以被用来自动地包括所有依赖表 — 但使用它时要非常
小心,否则你可能丢失数据!
特别注意的是,当要被截断的表是一个分区时,兄弟节点分区不会受到影响,但是所有的引用表都发生级联,他们的分区也没有区别。
TRUNCATE
将不会引发表上可能存在的任何
ON DELETE
触发器。但是它将会引发
ON TRUNCATE
触发器。如果在这些表的任意一个
上定义了ON TRUNCATE
触发器,那么所有的
BEFORE TRUNCATE
触发器将在任何截断发生之前
被引发,而所有AFTER TRUNCATE
触发器将在最后
一次截断完成并且所有序列被重置之后引发。触发器将以表被处理的顺
序被引发(首先是那些被列在命令中的,然后是由于级联被加入的)。
TRUNCATE
不是 MVCC 安全的。截断之后,
如果并发事务使用的是一个在截断发生前取得的快照,
表将对这些并发事务呈现为空。详见Section 14.5。
从表中数据的角度来说,TRUNCATE
是事务安全的:
如果所在的事务没有提交,阶段将会被安全地回滚。
在指定了RESTART IDENTITY
时,隐含的
ALTER SEQUENCE RESTART
操作也会被事务性地完成。
也就是说,如果所在事务没有提交,它们也将被回滚。注意如果
事务回滚前在被重启序列上还做了额外的序列操作,这些操作在序列上的效果
也将被回滚,但是它们在currval()
上的效果不会被回滚。也就
是说,在事务之后,currval()
将继续反映在失败事务内得到的
最后一个序列值,即使序列本身可能已经不再与此一致。这和失败事务之后
currval()
的通常行为类似。
TRUNCATE
当前不能用于被发布封装器支持的外部表。这意味着,如果指定的表具有任何外部的后代表,则该命令将失败。
截断表bigtable
和
fattable
:
TRUNCATE bigtable, fattable;
做同样的事情,并且还重置任何相关联的序列发生器:
TRUNCATE bigtable, fattable RESTART IDENTITY;
截断表othertable
,并且级联地截断任何通过
外键约束引用othertable
的表:
TRUNCATE othertable CASCADE;
drop storage的使用示例
TRUNCATE bigtable drop storage;
SQL:2008 标准包括了一个TRUNCATE
命令,
语法是TRUNCATE TABLE
。子句
tablename
CONTINUE IDENTITY
/RESTART IDENTITY
也出现在了该标准中,但是含义有些不同。这个命令的一些并发行为被标准
留给实现来定义,因此如果必要应该考虑上述注解并且与其他实现进行比较。