2011-04-15 99 views
2

我有了一个外键表A表B,现在我想做一个八九不离十“DELETE CASCADE”的thingie上A,但PostgreSQL将不会接受以下几点:SQL“DELETE CASCADE”

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中的子集,但我不能指出任何设计范例来支持它。

回答

-1

DB函数是自己的安乐窝(我知道,我知道),我不想让即使是临时性的更改有问题的列,所以我只是做了一个

CREATE TABLE CTable AS ... [expression that depends on BTAble] ...; 

和使用外,要依次删除B和A中的数据。

+0

-1:我知道,我知道,但它远不是最好的答案。 – onedaywhen 2011-04-19 10:40:36

+0

你在一般情况下可能是正确的。对我而言,这是解决我的问题的最简单方法。 – 2011-04-20 08:22:57

2

这对PostgreSQL 9.1来说是可能的,但我认为没有定义级联约束的方法是没有办法的。

http://developer.postgresql.org/pgdocs/postgres/queries-with.html#QUERIES-WITH-MODIFYING

+1

哎唷!你是否正在谈论关于外键上的'ON UPDATE CASCADE ON DELETE CASCADE'的内容? developer.postgresql.org目前不适合我... – 2011-04-15 12:28:21

+0

@Jonas:是的'ON DELETE CASCADE'就是我所说的 – 2011-04-15 12:31:27

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) 
); 
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) 
     ) 

附:以防万一,如果你不知道标准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应该是UNIQUEPRIMARY KEY,这对于大规模更新比基于集合的解决方案效率低。

+0

关于返回ID的函数的好主意 – 2011-04-15 12:31:54