ВЫБЕРИТЕ или ВСТАВЬТЕ строку в одну команду - PullRequest
30 голосов
/ 17 июля 2011

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

SELECT id
FROM mytable
WHERE other_key = 'SOMETHING'

Затем, если нетmatch:

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, если это помогает.

Ответы [ 3 ]

34 голосов
/ 17 июля 2011

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


Редактировать - для этого требуется 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 голосов
/ 17 июля 2011

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

1 голос
/ 17 июля 2011

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

IF (SELECT id FROM mytable WHERE other_key = 'SOMETHING' LIMIT 1) < 0 THEN
 INSERT INTO mytable (other_key) VALUES ('SOMETHING')
END IF
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...