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 安全的。在清空之后,对于正在使用清空发生之前获取的快照的并发事务来说,该表将显示为空。更多细节请参见 Section 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 。子句 tablenameCONTINUE IDENTITY/RESTART IDENTITY 也出现在那个标准中,但含义稍有不同且互相关联。这个命令的部分并发行为由标准留给实现自行定义,因此应该考虑上述注记,并在必要时与其他实现进行比较。