【问题标题】:Implement TRIGGER/RULE in postgresql to deduplicate records在 postgresql 中实现 TRIGGER/RULE 以删除重复记录
【发布时间】:2021-12-16 16:40:00
【问题描述】:

我在 PostgreSQL 中有一个经典的 cart items 表。

我想要什么:

当我执行插入时,我想防止插入新的重复记录,而是更新现有记录的数量字段。

在插入前尝试过触发函数和触发:

CREATE OR REPLACE FUNCTION ecommerce.add_store_cart_item()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    VOLATILE
    COST 100
AS $BODY$
begin
 insert into ecommerce.store_cart_item 
  (item_id, user_id) 
  values 
  (NEW.item_id, NEW.user_id) 
  on conflict (item_id, user_id) DO UPDATE
   SET qty = EXCLUDED.qty + NEW.qty;
  return NULL;
end;
$BODY$;

但我在这里得到递归。

也尝试了规则,但它也不起作用:

CREATE OR REPLACE RULE check_store_cart_item_duplicates AS
    ON INSERT TO ecommerce.store_cart_item
    WHERE (EXISTS ( SELECT 1
           FROM ecommerce.store_cart_item store_cart_item_1
          WHERE ((store_cart_item_1.item_id = new.item_id) AND (store_cart_item_1.user_id = new.user_id))))
    DO INSTEAD
(UPDATE ecommerce.store_cart_item SET qty = (store_cart_item.qty + new.qty)
  WHERE ((store_cart_item.user_id = new.user_id) AND (store_cart_item.item_id = new.item_id)));

注意

我不想使用简单的INSERT ... ON CONFLICT 命令,因为我希望它在数据库级别进行完整性检查(这种方法实际上将其移至应用程序级别)。

我想知道最有效最正确的方法。

【问题讨论】:

    标签: sql postgresql triggers


    【解决方案1】:

    法律是为人民服务的,而不是相反。

    如果您在数据库中对此进行编码的规则使您无法使用最佳和最有效的解决方案 (INSERT ... ON CONFLICT),请在这种情况下忽略该规则。不要让指导方针妨碍简单而好的解决方案。

    【讨论】:

      【解决方案2】:

      在触发器中使用UPDATE 语句而不是INSERT 语句。将触发器设置为仅在 INSERTs 上触发。

      例如

      UPDATE ecommerce.store_cart_item
      SET qty = qty + 1
      WHERE user_id = NEW.user_id AND item_id = NEW.item_id;
      
      RETURN NULL; /* Stop the INSERT */
      

      【讨论】:

      • 但是当表格中不存在记录时,我还需要插入记录...
      猜你喜欢
      • 2019-06-22
      • 2013-12-05
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      相关资源
      最近更新 更多