sql - 根据另一个表中的值删除行
问题描述
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 函数,然后使用触发器来帮助删除和检查,但我迷路了。关于如何解决这个问题的任何想法?有什么好的资源可以进一步阅读吗?
解决方案
您的基本功能可以这样工作:
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
。它效率低下并且可能很危险。有关的:
②“order”是SQL中的保留字。最好选择合法标识符,否则您必须始终使用双引号。
③我做了它RETURNS int
来表示该行是否真的被删除了。DELETE
如果没有通过,该函数返回 NULL 。可选添加。
对于触发器实现,请考虑这个密切相关的答案:
推荐阅读
- php - 使用 preg_match_all 匹配多个和可选变量
- java - Spring RestTemplate PUT 带参数
- go - 存储库名称和模块名称冲突
- android - Android 上的 Xamarain Forms 文件读取权限问题。ENOENT(没有这样的文件或目录)。仅对某些用户发生
- http - 你可以通过读取状态行来确定请求方法吗?
- python - 直接从 Pandas 数据框中创建 Plotly 图表并将其保存为 html 文件
- git - Visual Studio Code git 活动帐户
- r - svd 中的错误:x 中的值无限或缺失
- c# - SystemMediaControls.ButtonPressed 事件触发两次
- javascript - antlr4:如何在velocity文件中为javascript定义字符串语法?