Подтвердить что ты не робот

Вставить, если не существует, иначе вернуть id в postgresql

У меня есть простая таблица в PostgreSQL, которая имеет три столбца:

  • id первичный ключ
  • ключ varchar
  • значение varchar

Я уже видел этот вопрос здесь на SO: Вставить, при дублировании обновления в PostgreSQL?, но мне интересно, как получить идентификатор, если он существует, вместо обновления. Если стандартная практика заключается в том, чтобы всегда "вставлять" или "обновлять, если существует", почему? Является ли стоимость выполнения SELECT (LIMIT 1) больше, чем выполнение ОБНОВЛЕНИЯ?

У меня есть следующий код

INSERT INTO tag
    ("key", "value")
    SELECT 'key1', 'value1'
WHERE
    NOT EXISTS (
        SELECT id,"key","value" FROM tag WHERE key = 'key1' AND value = 'value1'
    );

который работает в том смысле, что он не вставляет, если существует, но я хотел бы получить идентификатор. Есть ли предложение "RETURNING id" или что-то подобное, что я мог бы там нажать?

4b9b3361

Ответ 1

Да есть returning

INSERT INTO tag ("key", "value")
SELECT 'key1', 'value1'
WHERE NOT EXISTS (
    SELECT id, "key", "value"
    FROM node_tag
    WHERE key = 'key1' AND value = 'value1'
    )
returning id, "key", "value"

Чтобы вернуть строку, если она уже существует

with s as (
    select id, "key", "value"
    from tag
    where key = 'key1' and value = 'value1'
), i as (
    insert into tag ("key", "value")
    select 'key1', 'value1'
    where not exists (select 1 from s)
    returning id, "key", "value"
)
select id, "key", "value"
from i
union all
select id, "key", "value"
from s

Если строка не существует, она вернет вставленную другую существующую.

BTW, если пара "ключ" / "значение" делает его уникальным, то это первичный ключ, и нет необходимости в столбце id. Если одна или обе пары "ключ" / "значение" не могут быть пустыми.

Ответ 2

with vals as (
  select 'key5' as key, 'value2' as value
)
insert into Test1 (key, value)
select v.key, v.value
from vals as v
where not exists (select * from Test1 as t where t.key = v.key and t.value = v.value)
returning id

демонстрация скриптов sql

Ответ 3

И вы можете сохранить значение, возвращаемое переменным в форме... RETURNING field1, field2,... INTO var1, var2,...

RETURNING, как правило, возвращает запрос, который бы возвращал запрос "Ошибка запроса" для конечных данных ", если вы вызываете его в plpgsql без использования его возвращаемого набора результатов.