UPSERT: использовать исходный столбец, которого нет в исключенной таблице - PullRequest
0 голосов
/ 17 апреля 2019

Я пытаюсь преобразовать выражение оракула Merge в postgreSQL (> 9.5).К сожалению, postgres (= <11) по-прежнему не поддерживает <code>MERGE, и лучшим альтернативным методом, который я нашел, был INSERT ... ON CONFLICT, также называемый UPSERT.

. Мне удалось преобразовать более простой оператор слияния в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.

ОШИБКА: столбец исключен.не существует

Есть ли обходной путь или как вы можете использовать исходные столбцы в запросе на обновление?Если это невозможно, есть ли другой способ написать операторы слияния в postgres?

1 Ответ

0 голосов
/ 17 апреля 2019

Вы можете переместить это выражение 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;
...