Postgres:删除所有表还是级联删除?

5

是否有可能在PostgreSQL中使用单个命令删除所有表的所有行(而不破坏数据库)或级联删除?

如果不行,那么我该如何重置我的测试数据库?

2个回答

7
有没有可能用单个命令从所有表中删除所有行?
你是对的,答案是否定的。
您可以定义级联外键,如果删除“父项”,则会删除所有引用行。但这是外键的属性,您无法使用DELETE语句指定。
如果不行 - 真是太棒了。
这是什么意思?
想一想:你想实现什么?
我怀疑您正在尝试“重置”例如测试数据库。在这种情况下,PostgreSQL的方法是:
1.创建一个包含新数据库中需要的所有内容(表、视图、索引等)的数据库(称为my_template)
2.要重置当前的测试数据库,请使用DROP DATABASE testdb,然后使用CREATE DATABASE testdb TEMPLATE my_template重新创建测试数据库
新创建的testdb将具有my_template中定义的所有表。这可能比删除所有行要快得多。

1
你说得对,那正是我想做的事情,我感到很沮丧的是postgres没有一个快速清除数据的简单方法。我会创建一个模板 - 感谢您的帮助。 - AP257
由于你似乎期望一个“DELETE all FROM everything”类型的语句,我想知道为什么?我所知道的没有任何数据库支持这个操作。 - user330315
嗯,我真正想要的是一个级联删除(DELETE CASCADE)。如果没有这个选项,从所有表中删除所有内容也可以接受。但是既没有级联删除,也没有全表删除,有点麻烦! - AP257

5
你可以编写一个存储过程,选择所有模式中的所有表,然后对这些表执行DELETE CASCADE或TRUNCATE。这只需要几行pl/pgsql代码,不是什么大问题。
编辑:这样做可以解决问题,但要小心!
CREATE OR REPLACE FUNCTION truncate_all() RETURNS void LANGUAGE plpgsql AS
$$
DECLARE
    row record;
    query   text;
BEGIN
    query := 'SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema NOT IN(''pg_catalog'', ''information_schema'') AND table_type = ''BASE TABLE''';

    FOR row IN EXECUTE query LOOP
        EXECUTE 'TRUNCATE ' || quote_ident(row.table_schema) || '.' || quote_ident(row.table_name) || ' CASCADE;';
    END LOOP;

    RETURN;
END;
$$;

-- execute:
SELECT truncate_all();

3
我的选择是使用+1:TRUNCATE,而不是使用DELETE CASCADE,因为太容易因为手指打错而出错了... - OMG Ponies
只有在数据库没有定义外键的情况下,该解决方案才能正常工作,这仅适用于非常简单的数据库。但是可以增强该函数以首先删除所有现有约束,然后截断所有表。 - user330315
不是这样的,这就是CASCADE发挥作用的地方。只需测试一下,您就会看到。http://www.postgresql.org/docs/current/static/sql-truncate.html - Frank Heikens
很酷,我不知道那个 ;) 谢谢你指出来。 - user330315
“TRUNCATE CASCADE” 一方面是存在的最可怕的命令之一……但在这里非常适用。 - araqnid

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