2016-04-01 3 views
43

Когда вы поднимаете строку (PostgreSQL> = 9.5) и хотите, чтобы возможный INSERT был точно таким же, как и возможное UPDATE, вы можете написать его так: :PostgreSQL INSERT ON CONFLICT UPDATE (upsert) использует все исключенные значения

INSERT INTO tablename (id, username, password, level, email) 
       VALUES (1, 'John', 'qwerty', 5, '[email protected]') 
ON CONFLICT (id) DO UPDATE SET 
    id=EXCLUDED.id, username=EXCLUDED.username, 
    password=EXCLUDED.password, level=EXCLUDED.level,email=EXCLUDED.email 

Есть ли более короткий путь? Чтобы просто сказать: используйте все значения EXCLUDE.

В SQLite я делал:

INSERT OR REPLACE INTO tablename (id, user, password, level, email) 
         VALUES (1, 'John', 'qwerty', 5, '[email protected]') 
+5

Не реальный ответ, но вы можете использовать несколько коротко обозначения: 'INSERT INTO имя_таблицы (ID, имя пользователя, пароль, уровень, электронная почта) VALUES (1, 'Джон', 'QWERTY', 5 , '[email protected]') ON CONFLICT (id) DO UPDATE SET (имя пользователя, пароль, уровень, электронная почта) = (EXCLUDED.username, EXCLUDED.password, EXCLUDED.level, EXCLUDED.email). Почти то же, но легко скопировать/вставить/управлять списком столбцов – foal

+0

Другой вариант - использовать столбцы jsonb, и вам не придется беспокоиться о столбцах –

ответ

53

Postgres не выполнил эквивалент INSERT OR REPLACE. Из ON CONFLICT docs (курсив мой):

Это может быть или не делать, или пункт UPDATE DO с указанием точные детали акции UPDATE должны быть выполнены в случае конфликта.

Хотя это не дает вам обсчитывать для замены, ON CONFLICT DO UPDATE применяется в более общем плане, так как она позволяет установить новые значения на основе ранее существовавших данных. Например:

INSERT INTO users (id, level) 
VALUES (1, 0) 
ON CONFLICT (id) DO UPDATE 
SET level = users.level + 1;