Как можно использовать синтаксис INSERT ... ON CONFLICT (id) DO UPDATE... с идентификатором последовательности?


В postgresql 9.5 как можно вставить ... По конфликту (id) сделайте обновление... синтаксис будет использоваться с идентификатором последовательности?

В таблице tbltest, содержащей следующие столбцы:

  • tbltest_ID
  • tbltest_Name
  • tbltest_Description

Где tbltest_ID имеет последовательность в БД, которая делает автоматическое приращение.

Следующее прекрасно работает для обновлений, например; обновление записи с идентификатором 4:

INSERT INTO tbltest (
    tbltest_ID,
    tbltest_Name,
    tbltest_Description) 
VALUES 
(4, 'test name','test description')
ON CONFLICT (tbltest_ID) DO UPDATE SET (
    tbltest_Name,
    tbltest_Description) = (
    excluded.tbltest_Name,
    excluded.tbltest_Description) RETURNING *;

Но для того, чтобы получить БД для создания ID последовательности для вставок мне нужно удалить столбец ID из инструкции:

INSERT INTO tbltest (
    tbltest_Name,
    tbltest_Description) 
VALUES 
('test name','test description')
ON CONFLICT (tbltest_ID) DO UPDATE SET (
    tbltest_Name,
    tbltest_Description) = (
    excluded.tbltest_Name,
    excluded.tbltest_Description) RETURNING *;

Это становится проблемой, если я хочу обновить несколько записей, некоторые новые и некоторые существующие. Как если бы я удалил столбец ID, все они были бы вставками come, и если я оставлю его там, я должен предоставить значение ID в массиве значений для каждой строки, и когда я определяю ID, последовательность (автоматическое приращение db) больше не используется.

Как происходит вставка ... По конфликту (id) сделайте обновление... синтаксис спорт, чтобы быть использованы с идентификатором последовательности для вставки / обновления набора записей, который будет содержать как новые записи, так и существующие записи?

Например, не работает следующее:

INSERT INTO tbltest (
    tbltest_ID,
    tbltest_Name,
    tbltest_Description) 
VALUES 
(NULL, 'new record','new record description'),
(4, 'existing record name','existing record description')
ON CONFLICT (tbltest_ID) DO UPDATE SET (
    tbltest_Name,
    tbltest_Description) = (
    excluded.tbltest_Name,
    excluded.tbltest_Description) RETURNING *;

Он выдает ошибку:

Ошибка: нулевое значение в столбце "tbltest_ID" нарушает ограничение not-null

Спасибо, что уделили мне время.
1 2

1 ответ:

Ладно, просто разобрался. Я читал эту замечательную статью от Нила Конвея: http://www.neilconway.org/docs/sequences/

Где он показывает использование ключевого слова DEFAULT для указания БД использовать значение последовательности для столбца.

Итак, вот обновленный пример, который теперь работает:

INSERT INTO tbltest (
    tbltest_ID,
    tbltest_Name,
    tbltest_Description) 
VALUES 
(DEFAULT, 'new record','new record description'),
(4, 'existing record name','existing record description')
ON CONFLICT (tbltest_ID) DO UPDATE SET (
    tbltest_Name,
    tbltest_Description) = (
    excluded.tbltest_Name,
    excluded.tbltest_Description) RETURNING *;

Надеюсь, это кому-то поможет; -)