2011-04-15 94 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