首页 > 解决方案 > 根据另一个表中的值删除行

问题描述

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 函数,然后使用触发器来帮助删除和检查,但我迷路了。关于如何解决这个问题的任何想法?有什么好的资源可以进一步阅读吗?

标签: sqlpostgresqlplpgsqlsql-delete

解决方案


您的基本功能可以这样工作:

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 。可选添加。


对于触发器实现,请考虑这个密切相关的答案:


推荐阅读