首页 > 解决方案 > 当父记录可能存在或可能不存在时如何添加记录

问题描述

我在 Postgresql 数据库中有三个表

用户 -> 购物车 -> CartItem

每个用户有很多购物车,每个购物车有很多购物车项目,但每个购物车属于一个用户,每个购物车项目属于一个购物车。我有一个查询我想在哪里添加 CartItem 但有三种情况:首先,购物车可能不存在,我将在其中创建购物车,然后创建 CartItem 第二,购物车可能存在并且 CartItem 是新的购物车项目(不编辑以前的购物车项目),在这种情况下,我只会添加购物车项目 第三,购物车可能存在,并且 CartItem 可能是对现有 CartItem 的修改,其中新的 CartItem 对象将具有一个 id 和 Cart_id允许它替换现有的 CartItem

我有两个问题,按照重要性和联系在一起的顺序排列。一个,在第一种情况下,我处理它的方式是检查一个查询中是否有购物车,如果没有,则创建一个,然后将具有外键引用的购物车项目添加到创建的购物车。但是,由于它的查询不止一个,(首先检查然后创建)我担心由于竞争条件,可以创建两个购物车(不同的 ID,但都引用相同的用户和商店)。我无法选择更新,因为它不存在所以我不知道如何处理它。

我的第二个问题是,是否有一个或两个查询可以一次完成所有这些(如果不存在则插入购物车,返回购物车 ID,以便我可以将其附加到对象,然后插入购物车项目,如果它不存在)

标签: postgresql

解决方案


我建议尝试使用带有 LEFT JOIN 的单个 SELECT QUERY 来提取用户、他的购物车和购物车的连接数据。如果没有可用的 Cart 或 CartItem,您将收到相应属性的空值。这样,您可以直接对丢失的表行做出反应,并在必要时创建它们。

关于您的第二个问题:使用 WITH {...} INSERT... RETURNING (或使用过程)可以动态插入多个值。像这样的东西,例如:

with new_cart as (
  insert into cart
     (user_id, creatiom_date) 
  values
     (current_user_id, now())
  returning id as cart_id
)
insert into cart_item
  (cart_id, item_id, count) 
values
  (cart_id, seleted_item_id, 2);

推荐阅读