如何根据来自另一个表的值删除customer
表中的行,例如orders
如果客户没有活动订单,则应该可以将它们与行一起从DB中删除(使用CASCADE
完成)。但是,如果他们有任何有效的命令,他们不能被删除。
我想到了一个PLPGSQL函数,然后在触发器中使用它来检查,但我迷路了。我有一个基本的SQL块,如下所示,我第一个想法就是相应地删除记录。但是它不能正常工作,因为它不管状态如何都会删除客户,它只需要在这个函数中取消一个订单,而不是全部取消。
CREATE OR REPLACE FUNCTION DelCust(int)
RETURNS void AS $body$
DELETE FROM Customer
WHERE CustID IN (
SELECT CustID
FROM Order
WHERE Status = 'C'
AND CustID = $1
);
$body$
LANGUAGE SQL;
SELECT * FROM Customer;
我也尝试过使用PLPGSQL函数返回触发器,然后使用触发器来帮助删除和检查,但我对它感到迷茫。对如何解决这个问题有什么想法吗?有什么好的资料可供进一步阅读吗?
发布于 2020-05-26 07:57:09
你们很亲密。我建议你用NOT IN
代替IN
DELETE FROM Customer
WHERE CustID = $1 AND
CustID NOT IN (SELECT DISTINCT CustID
FROM Order
WHERE Status = 'A');
我猜Status = 'A'
的意思是“活动秩序”。如果是其他的东西,适当地修改代码。
发布于 2020-05-28 08:42:28
您的基本功能可以这样工作:
CREATE OR REPLACE FUNCTION del_cust(_custid int)
RETURNS int --③
LANGUAGE sql AS
$func$
DELETE FROM customer c
WHERE c.custid = $1
AND NOT EXISTS ( -- ①
SELECT FROM "order" o -- ②
WHERE o.status = 'C' -- meaning "active"?
AND o.custid = $1
);
RETURNING c.custid; -- ③
$func$;
1 NOT IN
,如果可以的话。这是低效和潜在的危险。相关信息:
2 "order“是SQL中的保留字。最好选择一个合法的标识符,否则你必须总是双引号。
3我用RETURNS int
来表示该行是否真的被删除了。如果DELETE
不通过,则函数返回NULL。可选的加法。
对于触发器实现,请考虑以下密切相关的答案:
https://stackoverflow.com/questions/62026157
复制相似问题