TRUNCATE — 清空一个表或者一组表
TRUNCATE [ TABLE ] [ ONLY ] name
[ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
TRUNCATE
可以从一组表中快速地移除所有行。
它具有和在每个表上执行无条件DELETE
相同的
效果,不过它会更快,因为它没有实际扫描表。此外,它会立刻回收磁盘空间,
而不是要求一个后续的VACUUM
操作。在大表上
它最有用。
name
要截断的表的名字(可以是模式限定的)。如果在表名前指定了
ONLY
,则只会截断该表。如果没有指定ONLY
,
该表及其所有后代表(如果有)都会被截断。可选地,可以在表名后指定
*
来显式地包括后代表。
RESTART IDENTITY
自动重新开始被截断表的列所拥有的序列。
CONTINUE IDENTITY
不更改序列值。这是默认值。
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 安全的。截断之后,
如果并发事务使用的是一个在截断发生前取得的快照,
表将对这些并发事务呈现为空。详见第 13.6 节。
从表中数据的角度来说,TRUNCATE
是事务安全的:
如果所在的事务没有提交,阶段将会被安全地回滚。
在指定了RESTART IDENTITY
时,隐含的
ALTER SEQUENCE RESTART
操作也会被事务性地完成。
也就是说,如果所在事务没有提交,它们也将被回滚。注意如果
事务回滚前在被重启序列上还做了额外的序列操作,这些操作在序列上的效果
也将被回滚,但是它们在currval()
上的效果不会被回滚。也就
是说,在事务之后,currval()
将继续反映在失败事务内得到的
最后一个序列值,即使序列本身可能已经不再与此一致。这和失败事务之后
currval()
的通常行为类似。
TRUNCATE
当前不能用于被发布封装器支持的外部表,相应示例,参见postgres_fdw。
截断表bigtable
和
fattable
:
TRUNCATE bigtable, fattable;
做同样的事情,并且还重置任何相关联的序列发生器:
TRUNCATE bigtable, fattable RESTART IDENTITY;
截断表othertable
,并且级联地截断任何通过
外键约束引用othertable
的表:
TRUNCATE othertable CASCADE;
SQL:2008 标准包括了一个TRUNCATE
命令,
语法是TRUNCATE TABLE
。子句
tablename
CONTINUE IDENTITY
/RESTART IDENTITY
也出现在了该标准中,但是含义有些不同。这个命令的一些并发行为被标准
留给实现来定义,因此如果必要应该考虑上述注解并且与其他实现进行比较。