====== DELETE ====== .. container:: refentry :name: SQL-DELETE .. container:: titlepage .. container:: refnamediv .. rubric:: DELETE :name: delete DELETE — 删除一个表的行 .. container:: refsynopsisdiv .. rubric:: 大纲 :name: 大纲 .. code:: synopsis [ WITH [ RECURSIVE ] with_query [, ...] ] DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ] [ USING using_list ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ] .. container:: refsect1 :name: id-1.9.3.100.5 .. rubric:: 描述 :name: 描述 ``DELETE``\ 从指定表中删除满足 ``WHERE``\ 子句的行。如果\ ``WHERE`` 子句没有出现,效果将会是删除表中的所有行。结果是一个合法的空表。 .. tip:: .. rubric:: 提示 :name: 提示 :class: title `TRUNCATE `__\ 提供移除表中所有行的快速机制。 有两种方式可以使用数据库中其他表中包含的信息来删除一个表的行: 使用子选择或者在\ ``USING``\ 子句中指定额外的表。 哪种技术更合适取决于特定的环境。 可选的\ ``RETURNING``\ 子句导致\ ``DELETE`` 基于实际被删除的每一行计算并且返回值。任何使用被删除表列或者 ``USING``\ 中提到的其他表的列的表达式都可以被计算。 ``RETURNING``\ 列表的语法和\ ``SELECT``\ 的 输出列表语法相同。 要从表中删除行,你必须具有其上的\ ``DELETE``\ 特权, 以及\ ``USING``\ 子句中任何表以及其值在\ ``condition``\ 中被读取的表上的 ``SELECT``\ 特权。 .. container:: refsect1 :name: id-1.9.3.100.6 .. rubric:: 参数 :name: 参数 .. container:: variablelist ``with_query`` ``WITH``\ 子句允许你指定一个或者多个子查询,在 ``DELETE``\ 查询中可以用子查询的名字来引用它们。 详见\ `节 `__\ 和\ `SELECT `__\ 。 ``table_name`` 要从其中删除行的表名(可以是模式限定的)。如果在表名前指定 ``ONLY``\ ,只会从提到的表中删除匹配的行。如果没有指定 ``ONLY``\ ,还会删除该表的任何继承表中的匹配行。可选地, 可以在表名后面指定\ ``*``\ 来显式指定要包括继承表。 ``alias`` 目标表的一个别名。提供别名时,它会完全隐藏该表的真实名称。例如, 对于\ ``DELETE FROM foo AS f``\ , ``DELETE``\ 语句的剩余部分都会用 ``f``\ 而不是 ``foo``\ 来引用该表。 ``using_list`` 一个表表达式的列表,它允许在\ ``WHERE``\ 条件中出现 来自其他表的列。这和\ ``SELECT``\ 语句 的\ ```FROM`` 子句 `__\ 中指定 的表列表相似。例如,可以指定表的别名。除非想要进行自连接, 否则不要在\ ``using_list`` 再写上目标表。 ``condition`` 一个返回\ ``boolean``\ 类型值的表达式。只有让这个 表达式返回\ ``true``\ 的行才将被删除。 ``cursor_name`` 要在\ ``WHERE CURRENT OF``\ 情况中使用的游标 的名称。最近一次从这个游标中取出的行将被删除。该游标 必须是\ ``DELETE``\ 的目标表上的非分组查询。 注意不能在使用\ ``WHERE CURRENT OF``\ 的同时 指定一个布尔条件。有关将游标用于 ``WHERE CURRENT OF``\ 的更多信息请见 `DECLARE `__\ 。 ``output_expression`` 在每一行被删除后,会被\ ``DELETE``\ 计算并且返回的表达式。 该表达式可以使用\ ``table_name`` 以及\ ``USING``\ 中的表的任何列。写成\ ``*``\ 可以返回所有列。 ``output_name`` 被返回列的名称。 .. container:: refsect1 :name: id-1.9.3.100.7 .. rubric:: 输出 :name: 输出 在成功完成时,一个\ ``DELETE``\ 命令会返回以下形式 的命令标签: .. code:: screen DELETE count ``count``\ 是被删除行的数目。 注意如果有一个\ ``BEFORE DELETE``\ 触发器抑制删除,那么该数目 可能小于匹配\ ``condition`` 的行数。如果\ ``count``\ 为 0, 表示查询没有删除行(这并非一种错误)。 如果\ ``DELETE``\ 命令包含\ ``RETURNING``\ 子句, 则结果会与包含有\ ``RETURNING``\ 列表中定义的列和值的 ``SELECT``\ 语句结果相似,这些结果是在被该命令删除的 行上计算得来。 .. container:: refsect1 :name: id-1.9.3.100.8 .. rubric:: 注解 :name: 注解 通过在\ ``USING``\ 子句中指定其他的表, PostgreSQL允许在 ``WHERE``\ 条件中引用其他表的列。例如,要 删除有一个给定制片人制作的所有电影,可以这样做: .. code:: programlisting DELETE FROM films USING producers WHERE producer_id = producers.id AND producers.name = 'foo'; 这里实际发生的事情是在\ ``films``\ 和 ``producers``\ 之间进行连接,然后删除 所有成功连接的\ ``films``\ 行。这种语法不 属于标准。更标准的方式是: .. code:: programlisting DELETE FROM films WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo'); 在一些情况下,连接形式比子查询形式更容易书写或者执行更快。 .. container:: refsect1 :name: id-1.9.3.100.9 .. rubric:: 示例 :name: 示例 删除所有电影,但音乐剧除外: .. code:: programlisting DELETE FROM films WHERE kind <> 'Musical'; 清空表\ ``films``\ : .. code:: programlisting DELETE FROM films; 删除已完成的任务,返回被删除行的明细: .. code:: programlisting DELETE FROM tasks WHERE status = 'DONE' RETURNING *; 删除\ ``tasks``\ 中游标\ ``c_tasks`` 当前位于其上的行: .. code:: programlisting DELETE FROM tasks WHERE CURRENT OF c_tasks; .. container:: refsect1 :name: id-1.9.3.100.10 .. rubric:: 兼容性 :name: 兼容性 这个命令符合SQL标准,不过 ``USING``\ 和\ ``RETURNING``\ 子句是 PostgreSQL扩展,在 ``DELETE``\ 中使用\ ``WITH``\ 也是扩展。 .. container:: refsect1 :name: id-1.9.3.100.11 .. rubric:: 又见 :name: 又见 `TRUNCATE `__