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

ВЫБЕРИТЕ или ВСТАВЬТЕ строку в одной команде

Я использую PostgreSQL 9.0, и у меня есть таблица с только искусственным ключом (автоинкрементная последовательность) и еще один уникальный ключ. (Да, есть причина для этой таблицы.:)) Я хочу искать идентификатор другим ключом или, если он не существует, вставьте его:

SELECT id
FROM mytable
WHERE other_key = 'SOMETHING'

Затем, если нет совпадения:

INSERT INTO mytable (other_key)
VALUES ('SOMETHING')
RETURNING id

Вопрос: можно ли сохранить двустороннюю поездку в БД, выполнив оба из них в одном утверждении? Я могу вставить строку, если она не существует следующим образом:

INSERT INTO mytable (other_key)
SELECT 'SOMETHING'
WHERE NOT EXISTS (SELECT * FROM mytable WHERE other_key = 'SOMETHING')
RETURNING id

... но это не дает идентификатор существующей строки. Есть идеи? Существует уникальное ограничение на other_key, если это помогает.

4b9b3361

Ответ 1

Вы пытались объединить его?


Изменить - для этого требуется Postgres 9.1:

create table mytable (id serial primary key, other_key varchar not null unique);

WITH new_row AS (
INSERT INTO mytable (other_key)
SELECT 'SOMETHING'
WHERE NOT EXISTS (SELECT * FROM mytable WHERE other_key = 'SOMETHING')
RETURNING *
)
SELECT * FROM new_row
UNION
SELECT * FROM mytable WHERE other_key = 'SOMETHING';

приводит к:

 id | other_key 
----+-----------
  1 | SOMETHING
(1 row)

Ответ 2

вы можете использовать хранимую процедуру

IF (SELECT id FROM mytable WHERE other_key = 'SOMETHING' LIMIT 1) < 0 THEN
 INSERT INTO mytable (other_key) VALUES ('SOMETHING')
END IF

Ответ 3

Нет, нет специального синтаксиса SQL, который позволяет вам выбирать или вставлять. Вы можете делать то, что Илия упоминает и создает sproc, а это значит, что он не будет совершать круговую поездку от клиента к серверу, но он все равно приведет к двум запросам (три фактически, если вы считаете сам sproc).