【问题标题】:INSERT with several UPDATE statements带有几个 UPDATE 语句的 INSERT
【发布时间】:2016-01-22 21:52:44
【问题描述】:

使用 Postgresql 解决以下问题的最佳方法是什么?

对于我插入到文章表中的每一行,我想更新插入文章的某些列。

这是我目前的解决方案:


-- temporarily alter table to avoid not null issues
ALTER TABLE article ALTER COLUMN fk_article_unit DROP NOT NULL;
(...)

--create article and return inserted pks, store these in a temporary table so they can be used for all following updates
WITH articles AS (
  insert into article
  (
    ...
  )
  select
    ...
  from other_table
  where some_condition
  RETURNING pk
)
SELECT pk INTO temporary temp_articles
FROM articles;

-- update various fk for all newly created articles
UPDATE article
SET fk_article_type =
  (SELECT pk
  FROM article_type
  WHERE unique_id = 'service')
WHERE pk in (select pk from temp_articles);

UPDATE article
SET fk_article_type =
  (SELECT min(pk)
  FROM vat_code)
WHERE fk_article_type is null;

(... several more updates)

--readd no null constraint
ALTER TABLE article ALTER COLUMN fk_article_type SET NOT NULL;
(...)

【问题讨论】:

  • INSERT 是否为所有新行保留fk_article_type null?您是在问如何将以下 2 个更新直接合并到 INSERT 中?
  • 你好丹尼尔。对于某些行,INSERT 可能会使 fk_article_type 为空。我认为在我的复杂示例中合并更新不会起作用(在这个简化的示例中,我想它可能是可能的)。
  • 我想我只是想知道我的解决方案是否是一个“好”的解决方案,或者我是否正在做一些相当愚蠢的事情,因为有一种更简单/更好/更清洁...的方式。
  • 切换 NOT NULL 约束需要对表进行强锁(不包括读卡器),放回去时会重新检查整个表。在高并发或大表上下文中,这并不理想。
  • 在我的情况下,这应该不是问题,因为所涉及的表通常不超过 100 行,我们仅在迁移期间使用此查询。但我仍然很想知道如何在不切换 NOT NULL 约束的情况下实现这一点。全部在 1 个查询中?那么如何处理 fk_article_type 的双重更新呢?谢谢你:)

标签: database postgresql database-migration common-table-expression


【解决方案1】:

我不明白为什么这不能通过单个 insert 查询来完成。如果以下解决方案不适用,请提供有关您的数据模型的一些附加信息。

insert into article
(
  ...,
  fk_article_type
)
select
  ...,
  coalesce -- if first query is null, then the result of second will be used
  (
      ( -- 1st query
          select pk from article_type where unique_id= 'service'
      ),
      ( -- 2nd query
          select min(pk) from vat_code
      )
  )
from other_table
where some_condition
returning pk;

【讨论】:

  • 我现在不能尝试,但它看起来很棒:)。我把这种方法弄得太复杂了。一旦我可以尝试,我会接受答案:)。
猜你喜欢
  • 2021-03-27
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多