Sql 如何使用insert的值同时在多行中更新表中的外键

Sql 如何使用insert的值同时在多行中更新表中的外键,sql,postgresql,Sql,Postgresql,我想将表中的外键更新为新插入的值,其中该键当前为空。这里需要注意的是,INSERT中的信息与表相关 举个例子: 汽车有汽车零件 car和car_部件都与版本控制关联(版本控制具有id,从版本到版本,处于活动状态) 一些汽车目前有一个空版本的控制 由于汽车有一个带有版本控制的汽车零件,我们基本上希望为汽车创建一个新的版本控制,并使用与汽车零件的版本控制相同的信息填充它 例如: 对于上述示例,我们希望: 更新汽车1 添加与版本控制#100具有相同信息的新版本控制# 在实际示例中,有数百辆汽车,其中几

我想将表中的外键更新为新插入的值,其中该键当前为空。这里需要注意的是,INSERT中的信息与表相关

举个例子:

  • 汽车有汽车零件
  • car和car_部件都与版本控制关联(版本控制具有id,从版本到版本,处于活动状态)
  • 一些汽车目前有一个空版本的控制
  • 由于汽车有一个带有版本控制的汽车零件,我们基本上希望为汽车创建一个新的版本控制,并使用与汽车零件的版本控制相同的信息填充它
  • 例如:

    对于上述示例,我们希望:

  • 更新汽车1
  • 添加与版本控制#100具有相同信息的新版本控制#
  • 在实际示例中,有数百辆汽车,其中几十辆具有空版本的控制id,因此我们需要在单个查询中完成此操作

    我们如何将下面的伪代码更改为解决此问题的有效SQL

    UPDATE car
    WITH inserted_version as (
        INSERT INTO version_control(
                id, active, from_version_id, to_version_id)
        WITH vc_to_create as (
            select c.id as car_id,vc.* from car c
            inner join car_part cp on cp.id = c.car_part_id 
            inner join version_control vc on cp.version_control_id=vc.id
            where c.version_control_id IS NULL
            )
        SELECT nextval('pk_entities'),vctc.active, vctc.from_version_id, vctc.to_version_id)
        FROM vc_to_create vctc
        RETURNING id
        )
    SET version_control_id=(SELECT i_vc.id  FROM inserted_vc i_vc)
    WHERE id=vc_to_create.car_id -->vc_to_create Not available here
    

    听起来您想在一个事务块中的不同表上进行两次修改

    这是一个开始

    在进入事务之前,您可能还需要将事务隔离级别设置为可序列化。看看我在说什么

    如果我们不需要那么严格的隔离级别,有人请纠正我。不幸的是,我的头脑对于什么样的情景严格要求这种隔离的细节变得模糊起来。严格地说,这可能不需要那个隔离级别,特别是取决于编写的SQL,但闻起来它可能是那种情况。只是一个可能不必要的预警

    编辑:

    好的,您仍然不需要“在一个查询中”完成所有这些操作。严格地说,您只需要识别或跟踪刚刚插入的行。您应该能够使用一个临时表来进行此操作。即:

  • 启动事务
  • 将事务隔离级别设置为可序列化。(同样,如果需要的话,但坦率地说,如果我没有设置它,我会担心,除非另有证明。还要注意,使用SERIALIZABLE,您可能需要重试:)
  • 创建临时表作为(使用查询)将插入到版本控制中的行以及与每个版本控制行相关的车辆ID。也就是说,每行都有版本控制信息和id信息。我们只需要在这里抓取
    nextval('pk_entities')
  • 将临时表中的数据插入到版本控制中(如上所述,我们已经生成了键)
  • 使用临时表中的数据更新车辆
  • 提交/删除表。(这显然可以在事务提交时通过在临时表的create语句中声明表来完成。)

  • 这给我们提供了一个如何计划的高/中级描述,由于我还没有明确为此编写代码,我可能错过了一些东西。

    我不确定插入的位置。从样本数据开始工作,哪个表获得一个额外的行,它的内容是什么?@AndrewLazarus-从样本日期开始,version_控件将获得一个额外的列,其中包含值(10119922012)。然后更新会将车1的版本控制id更改为101。(注意1992年和2012年是从100复制的,因为汽车1有汽车部件10,而汽车部件有版本控制100)我不知道这是否清楚,但本质上我们复制了汽车1的汽车部件的版本控制,并将其与汽车关联),而我了解交易(在版本控制中执行一次插入,在car中执行一次更新是很简单的),这里的问题是:如何在同一个查询中更新这两个控件;否则,我看不到如何插入(比如)10个具有正确信息的版本控件,然后将它们更新到正确的car中-请参阅car/car\u part/version\u控件示例以了解基本问题9
    UPDATE car
    WITH inserted_version as (
        INSERT INTO version_control(
                id, active, from_version_id, to_version_id)
        WITH vc_to_create as (
            select c.id as car_id,vc.* from car c
            inner join car_part cp on cp.id = c.car_part_id 
            inner join version_control vc on cp.version_control_id=vc.id
            where c.version_control_id IS NULL
            )
        SELECT nextval('pk_entities'),vctc.active, vctc.from_version_id, vctc.to_version_id)
        FROM vc_to_create vctc
        RETURNING id
        )
    SET version_control_id=(SELECT i_vc.id  FROM inserted_vc i_vc)
    WHERE id=vc_to_create.car_id -->vc_to_create Not available here