我正在尝试将oracle Merge
语句转换为postgreSQL(> 9.5)。
不幸的是postgres(= <11)仍然不支持MERGE
,而我发现的最佳替代方法是INSERT ... ON CONFLICT
,也称为UPSERT
。
我能够将更基本的merge语句转换为upserts,但是对于更复杂的查询,我需要访问源查询中的列,这些列不会插入,而仅用于DO UPDATE
中的逻辑。
不幸的是,特殊的excluded.
表使用与目标相同的列标识符。
ORACLE MERGE版本
MERGE INTO tgt
USING (SELECT nam.text AS normalizedtext, norm.originaltext,
norm.entryid AS entryID,
nam.name_id AS name_id,
norm.islink AS islink
FROM norm, nam
WHERE norm.name_id = nam.name_id
GROUP BY originaltext
) source
ON (tgt.languagecode = :langCode AND tgt.text = source.originaltext)
WHEN MATCHED AND ptid IS NULL THEN
UPDATE SET tgt.name_id = source.name_id,
tgt.PTID = source.entryID,
tgt.normname = CASE WHEN source.islink = 1 THEN
source.originaltext ELSE source.normalizedtext END CASE
当前发布版本
INSERT INTO tgt (text, normname, ptid, name_id, languagecode)
SELECT nam.text AS normalizedtext, norm.originaltext,
norm.entryid AS entryID,
nam.name_id AS name_id,
:langCode, -- edited
norm.islink AS islink
FROM norm, nam
WHERE norm.name_id = nam.name_id
GROUP BY originaltext
ON CONFLICT (text, languagecode)
DO UPDATE
SET name_id = excluded.name_id,
ptid = excluded.ptid,
normname = CASE WHEN excluded.islink = 1 THEN -- PROBLEM
excluded.originaltext ELSE excluded.normalizedtext END -- PROBLEM
WHERE ptid IS NULL;
问题是排除的表不包含列:isLink
,originaltext
和normalizedtext
。
错误:排除的列。islink不存在
有什么解决方法,或者如何使用更新查询中的源列? 如果这不可能,是否还有其他方法可以在postgres中编写merge语句?
答案 0 :(得分:0)
您可以将该CASE表达式移至SELECT语句:
INSERT INTO tgt (text, normname, ptid, name_id, languagecode)
SELECT nam.text,
case islink
when 1 then norm.originaltext
else normalizedtext
end as normname,
norm.entryid AS ptid,
nam.name_id AS name_id,
:langCode as languagecode
FROM norm
JOIN nam ON norm.name_id = nam.name_id
GROUP BY originaltext
ON CONFLICT (text, languagecode)
DO UPDATE
SET name_id = excluded.name_id,
ptid = excluded.ptid,
normname = excluded.normname
WHERE ptid IS NULL;