sql—根据另一个表中的值删除行

vdgimpew  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(346)

如何从我的列表中删除行 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函数返回一个触发器,然后使用触发器来帮助删除和检查,但我对它迷茫了。你有没有想过怎么解决这个问题?有什么好的资料可供进一步阅读吗?

erhoui1w

erhoui1w1#

你很接近。我建议你用 NOT IN 而不是 IN :

DELETE FROM Customer 
  WHERE CustID = $1 AND
        CustID NOT IN (SELECT DISTINCT CustID
                         FROM Order
                         WHERE Status = 'A');

我猜在这里 Status = 'A' 指“有效订单”。如果是其他原因,请适当更改代码。

bkhjykvo

bkhjykvo2#

基本功能如下:

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 不能通过。可选添加。
对于触发器实现,请考虑以下密切相关的答案:
多对多关系中的外键约束

相关问题