问题描述
|
我有一个表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中的子集,但是我真的不能指出任何支持它的设计范例。
解决方法
PostgreSQL 9.1可以做到这一点,但是我认为没有定义级联约束的方法是没有任何办法的。
http://developer.postgresql.org/pgdocs/postgres/queries-with.html#QUERIES-WITH-MODIFYING
,您可以同时等待
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
删除。
为此,ѭ9应该是ѭ10或PRIMARY KEY
,并且与基于集合的解决方案相比,这对于批量更新而言效率较低。
,您应该能够做到:这是我在本页底部找到的示例。
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)
);
,数据库函数超出了我的舒适范围(我知道,我知道),我甚至不想对所讨论的列进行临时更改,因此我只是做了一个
CREATE TABLE CTable AS ... [expression that depends on BTAble] ...;
并以此顺序删除B和A中的数据。