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