如何删除我的行 customer
根据另一个表的值,例如 orders
?
如果客户没有活跃的订单,他们应该能够从数据库中删除他们的行(使用 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函数返回一个触发器,然后用触发器来帮助删除和检查,但是我对这个问题很迷茫。有什么想法可以解决这个问题吗?有什么好的来源可以进一步阅读吗?
你很接近了。我建议你使用 NOT IN
而不是 IN
:
DELETE FROM Customer
WHERE CustID = $1 AND
CustID NOT IN (SELECT DISTINCT CustID
FROM Order
WHERE Status = 'A');
我猜想 Status = 'A'
意思是 "活动订单"。如果是其他的东西,就适当的修改代码。
你的基本函数可以这样工作。
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$;
① 避免 NOT IN
如果你能。效率低下,而且有可能会有奸情。相关的。
②"令 "是 保留字 在SQL中。最好选择一个合法的标识符,否则就得一直用双引号。
③我把它做成了 RETURNS int
来表示该行是否真的被删除。如果该行被删除,函数返回NULL。DELETE
不通过。可选添加。
对于一个 触发执行,考虑这个密切相关的答案。