如何将INSERT ... ON CONFLICT(id)DO UPDATE ...语法与序列ID一起使用?

use*_*254 3 postgresql insert-update postgresql-9.5

在postgresql 9.5中,如何使用INSERT ... ON CONFLICT(id)DO UPDATE ...语法与序列ID一起使用?

tbltest包含以下列的表中:

  • tbltest_ID
  • tbltest_Name
  • tbltest_Description

数据库中哪个tbltest_ID序列执行自动递增.

以下适用于更新,例如; 更新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 *;
Run Code Online (Sandbox Code Playgroud)

但是为了让DB为插入创建序列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 *;
Run Code Online (Sandbox Code Playgroud)

如果我想更新一些新记录和一些现有记录,这就成了一个问题.好像我删除了ID列,它们都是插入的,如果我把它留在那里,我必须在VALUES数组中为每一行提供一个ID值,当我定义一个ID时,序列(db的自动增量) )不再使用.

如何INSFT ... ON CONFLICT(id)DO UPDATE ...语句spost与序列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 *;
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误:

错误:"tbltest_ID"列中的空值违反非空约束

谢谢你的时间.

use*_*254 5

好的,只是解决了.我读了Neil Conway的这篇精彩文章:http: //www.neilconway.org/docs/sequences/

他在哪里显示使用DEFAULT关键字告诉DB使用列的序列值.

所以这是现在有效的更新示例:

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 *;
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人;-)