我有一个表B,它有一个表A的外键,现在我想在A上做一个“DELETE CASCADE”的东西,但是PostgreSQL不会接受以下内容:
DELETE FROM ATable WHERE aid IN
(
DELETE FROM BTable WHERE aid IN
(
... [expression that depends on the entries in BTAble] ...
)
RETURNING aid
);
似乎只有SELECT可以在IN ()
子句中。我想有一些简单的(和标准的SQL,而不是PostgreSQL特定的?)这样做的方式吗?
编辑:当遇到这类问题时,可以说某些内容结构糟糕吗?在我们的例子中,我有一种直觉,..[expr]..
中的命中应该是新的CTAble而不是ATable的子集,但我不能指出任何设计范例来支持它。
答案 0 :(得分:2)
使用PostgreSQL 9.1可以实现这一点,但我认为如果不定义级联约束,就没有办法做到这一点。
http://developer.postgresql.org/pgdocs/postgres/queries-with.html#QUERIES-WITH-MODIFYING
答案 1 :(得分:2)
您可以等待9.1
或同时创建一个设置返回功能:
CREATE OR REPLACE FUNCTION fn_delete_btable(params)
RETURNS SETOF btable.aid%TYPE
AS
$$
DELETE
FROM btable
WHERE expression_over_params(params)
RETURNING
aid
$$
LANGUAGE 'sql';
DELETE
FROM atable
WHERE aid IN
(
SELECT aid
FROM fn_delete_btable(params)
)
P.S。如果您不了解标准的SQL
方式,以防万一。
如果你创建这样的表:
CREATE TABLE btable (aid INT NOT NULL UNIQUE, …)
CREATE TABLE atable (aid INT NOT NULL FOREIGN KEY REFERENCES (aid) ON DELETE CASCADE, …)
然后从btable
删除也会触发atable
的删除。
要实现这一点,btable.aid
应该是UNIQUE
或PRIMARY KEY
,这对于批量更新而言比基于集合的解决方案效率低。
答案 2 :(得分:1)
你应该可以这样做:这是我在this页面底部找到的一个例子。
CREATE TABLE order_items (
product_no integer REFERENCES products ON DELETE RESTRICT,
order_id integer REFERENCES orders ON DELETE CASCADE,
quantity integer,
PRIMARY KEY (product_no, order_id)
);
答案 3 :(得分:-1)
数据库功能在我的舒适区之外(我知道,我知道)而且我不想对有问题的列进行临时更改,所以我只是做了一个
CREATE TABLE CTable AS ... [expression that depends on BTAble] ...;
并用它来顺序删除B和A中的数据。