========
TRUNCATE
========


.. container:: refentry
   :name: SQL-TRUNCATE

   .. container:: titlepage

   .. container:: refnamediv

      .. rubric:: TRUNCATE
         :name: truncate

      TRUNCATE — 清空一个表或者一组表

   .. container:: refsynopsisdiv

      .. rubric:: 大纲
         :name: 大纲

      .. code:: synopsis

         TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
             [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

   .. container:: refsect1
      :name: id-1.9.3.180.5

      .. rubric:: 描述
         :name: 描述

      ``TRUNCATE``\ 可以从一组表中快速地移除所有行。
      它具有和在每个表上执行无条件\ ``DELETE``\ 相同的
      效果,不过它会更快,因为它没有实际扫描表。此外,它会立刻回收磁盘空间,
      而不是要求一个后续的\ ``VACUUM``\ 操作。在大表上 它最有用。

   .. container:: refsect1
      :name: id-1.9.3.180.6

      .. rubric:: 参数
         :name: 参数

      .. container:: variablelist

         *``name``*
            要截断的表的名字(可以是模式限定的)。如果在表名前指定了
            ``ONLY``\ ,则只会截断该表。如果没有指定\ ``ONLY``\ ,
            该表及其所有后代表(如果有)都会被截断。可选地,可以在表名后指定
            ``*``\ 来显式地包括后代表。

         ``RESTART IDENTITY``
            自动重新开始被截断表的列所拥有的序列。

         ``CONTINUE IDENTITY``
            不更改序列值。这是默认值。

         ``CASCADE``
            自动截断所有对任一所提及表有外键引用的表以及任何由于
            ``CASCADE``\ 被加入到组中的表。

         ``RESTRICT``
            如果任一表上具有来自命令中没有列出的表的外键引用,则拒绝截断。这是默认值。

   .. container:: refsect1
      :name: id-1.9.3.180.7

      .. rubric:: 注解
         :name: 注解

      要截断一个表,你必须具有其上的\ ``TRUNCATE``\ 特权。

      ``TRUNCATE``\ 在要操作的表上要求一个
      ``ACCESS EXCLUSIVE``\ 锁,这会阻塞所有其他在该表上的
      并发操作。当指定\ ``RESTART IDENTITY``\ 时,任何需要被
      重新开始的序列也会被排他地锁住。如果要求表上的并发访问,那么
      应该使用\ ``DELETE``\ 命令。

      ``TRUNCATE``\ 不能被用在被其他表外键引用的表上,
      除非那些表也在同一个命令中被阶段。这些情况中的可行性检查将会
      要求表扫描,并且重点不是为了做扫描。\ ``CASCADE``
      选项可以被用来自动地包括所有依赖表 — 但使用它时要非常
      小心,否则你可能丢失数据!
      特别注意的是,当要被截断的表是一个分区时,兄弟节点分区不会受到影响,但是所有的引用表都发生级联,他们的分区也没有区别。

      ``TRUNCATE``\ 将不会引发表上可能存在的任何
      ``ON DELETE``\ 触发器。但是它将会引发
      ``ON TRUNCATE``\ 触发器。如果在这些表的任意一个
      上定义了\ ``ON TRUNCATE``\ 触发器,那么所有的
      ``BEFORE TRUNCATE``\ 触发器将在任何截断发生之前
      被引发,而所有\ ``AFTER TRUNCATE``\ 触发器将在最后
      一次截断完成并且所有序列被重置之后引发。触发器将以表被处理的顺
      序被引发(首先是那些被列在命令中的,然后是由于级联被加入的)。

      ``TRUNCATE``\ 不是 MVCC 安全的。截断之后,
      如果并发事务使用的是一个在截断发生前取得的快照,
      表将对这些并发事务呈现为空。详见\ `第 13.5 节 <mvcc-caveats.html>`__\ 。

      从表中数据的角度来说,\ ``TRUNCATE``\ 是事务安全的:
      如果所在的事务没有提交,阶段将会被安全地回滚。

      在指定了\ ``RESTART IDENTITY``\ 时,隐含的
      ``ALTER SEQUENCE RESTART``\ 操作也会被事务性地完成。
      也就是说,如果所在事务没有提交,它们也将被回滚。这和
      ``ALTER SEQUENCE RESTART``\ 的通常行为不同。注意如果
      事务回滚前在被重启序列上还做了额外的序列操作,这些操作在序列上的效果
      也将被回滚,但是它们在\ ``currval()``\ 上的效果不会被回滚。也就
      是说,在事务之后,\ ``currval()``\ 将继续反映在失败事务内得到的
      最后一个序列值,即使序列本身可能已经不再与此一致。这和失败事务之后
      ``currval()``\ 的通常行为类似。

      ``TRUNCATE``\ 当前不支持外部表。
      这表示如果一个指定的表具有任何外部的后代表,这个命令将会失败。

   .. container:: refsect1
      :name: id-1.9.3.180.8

      .. rubric:: 示例
         :name: 示例

      截断表\ ``bigtable``\ 和 ``fattable``\ :

      .. code:: programlisting

         TRUNCATE bigtable, fattable;

      做同样的事情,并且还重置任何相关联的序列发生器:

      .. code:: programlisting

         TRUNCATE bigtable, fattable RESTART IDENTITY;

      截断表\ ``othertable``\ ,并且级联地截断任何通过
      外键约束引用\ ``othertable``\ 的表:

      .. code:: programlisting

         TRUNCATE othertable CASCADE;

   .. container:: refsect1
      :name: id-1.9.3.180.9

      .. rubric:: 兼容性
         :name: 兼容性

      SQL:2008 标准包括了一个\ ``TRUNCATE``\ 命令,
      语法是\ ``TRUNCATE TABLE    tablename``\ 。子句
      ``CONTINUE IDENTITY``/``RESTART IDENTITY``
      也出现在了该标准中,但是含义有些不同。这个命令的一些并发行为被标准
      留给实现来定义,因此如果必要应该考虑上述注解并且与其他实现进行比较。

   .. container:: refsect1
      :name: id-1.9.3.180.10

      .. rubric:: 参见
         :name: 参见

      `DELETE <sql-delete.html>`__