如何在PostgreSQL中获取已删除行的数量?

71
我正在寻找一种返回PostgreSQL DELETE语句影响行数的方法。文档中指出:
当DELETE命令成功完成时,会返回一个形如DELETE count的命令标记。
count是删除的行数。如果count为0,则表示没有匹配到任何行(这不被视为错误)。
如果DELETE命令包含RETURNING子句,则结果将类似于包含在RETURNING列表中定义的列和值上计算所删除的行的SELECT语句。
但我无法找到一个很好的例子。有人能帮我解决这个问题吗?我怎样才能知道删除了多少行?

编辑: 我后来发现了一种替代方法,可以在这里找到,标题为38.5.5. 获取结果状态的章节中有详细解释。


您偏爱哪种脚本语言?Perl、PHP、Python、C还是Klingon? - Paul
6个回答

163
您可以使用RETURNING子句:
DELETE FROM table WHERE condition IS TRUE RETURNING *;

之后,您只需检查返回的行数。您可以使用CTE进行优化:

WITH deleted AS (DELETE FROM table WHERE condition IS TRUE RETURNING *) SELECT count(*) FROM deleted;

这应该只返回已删除行的数量。

9
无需扩展程序即可正常工作!这绝对应该是被接受的答案:D - Alfabravo
4
这种方式是否比仅使用 DELETE FROM table WHERE condition IS TRUE 更低效?例如,当评估 CTE 时,Postgres 是否会在某处临时存储已删除的行,或者它是否足够聪明,只看到仅使用计数,而将被删除的行作为它们被删除而计数? - EM0

18

GET DIAGNOSTICS用于显示修改/删除的记录数量。

示例代码

CREATE OR REPLACE FUNCTION fnName()
  RETURNS void AS
$BODY$
        declare
         count numeric;
       begin
              count := 0;
            LOOP
             -- condition here update or delete;
             GET DIAGNOSTICS count = ROW_COUNT;
             raise notice 'Value: %', count;
             end loop;
        end;
$BODY$a

15

在Java中,这应该很简单。

Statement stmt = connection.createStatement();
int rowsAffected = stmt.executeUpdate("delete from your_table");
System.out.println("deleted: " + rowsAffected);

请参阅java.sql.Statement


8
在问题的第二个评论中,OP表示:“使用的编程语言是Java。” - cope360

11

在使用Python的psycopg2库时,可以使用rowcount属性。以下是一个示例,用于查找删除了多少行...

cur = connection.cursor()
try:
    cur.execute("DELETE FROM table WHERE col1 = %s", (value,))
    connection.commit()
    count = cur.rowcount
    cur.close()
    print("A total of %s rows were deleted." % count)
except:
    connection.rollback()
    print("An error as occurred, No rows were deleted")

4

这适用于函数。它也可以与其他操作(如INSERT)一起使用。

DECLARE _result INTEGER;
...
DELETE FROM mytable WHERE amount = 0;  -- or whatever other operation you desire
GET DIAGNOSTICS _result = ROW_COUNT;
IF _result > 0 THEN
    RAISE NOTICE 'Removed % rows with amount = 0', _result;
END IF;

-6

2
严格来说,您不需要那个扩展。下面提供了一个基本解决方案。 - Craig Labenz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接