如何使用 jsonb_populate_record() 插入到包含 IDENTITY 列的表中

问题描述 投票:0回答:1

我用下面的简单表格演示了这个问题。 (实际的表和 JSON 文档有更多字段。)

CREATE table contact (
    id bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
    firstname VARCHAR,
    lastname VARCHAR,
    birthday timestamp with time zone NOT NULL
);

我正在尝试使用

jsonb_populate_record
:

从 JSONB 插入此表
INSERT INTO contact (firstname, lastname, birthday)
SELECT (jsonb_populate_record(NULL::contact, 
'{
    "firstname": "John",
    "lastname": "Doe",
    "birthday": "2023-09-28"
}'
)).*;

此操作失败并出现错误:

错误:INSERT 的表达式多于目标列
第 1 行:...O 联系人(名字、姓氏、生日)选择 jsonb_popu...

我知道错误来自不包含

id
键和值的 JSONB。因此,
jsonb_populate_record
函数正在使用
id
列创建一条记录,但由于
INSERT
中未指定它,因此失败。

我尝试将

id
添加到
INSERT INTO contact (id, ....
中,但失败并出现错误,
id
为空(因为我的 JSONB 中没有任何
id
)。

我怎样才能让它工作,以便

id
是表中指定的
GENERATED BY DEFAULT AS IDENTITY

编辑:

我找到了解决方案:

INSERT INTO contact (id, firstname, lastname, birthday)
SELECT (jsonb_populate_record(NULL::contact, jsonb_set('{
"firstname": "John",
"lastname": "Doe",
"birthday": "2023-09-28"
}', '{id}', to_jsonb(nextval(pg_get_serial_sequence('contact', 'id')))))).*;

然而,此后生成的

id
似乎跳过了4位数字:

select * from contact;
 id | firstname | lastname |        birthday        
----+-----------+----------+------------------------
 10 | John      | Doe      | 2023-09-28 00:00:00-04
 14 | John      | Doe      | 2023-09-28 00:00:00-04
 18 | John      | Doe      | 2023-09-28 00:00:00-04
 22 | John      | Doe      | 2023-09-28 00:00:00-04

知道为什么以及如何避免这种情况吗?

sql postgresql sql-insert jsonb postgres15
1个回答
0
投票

您可以使用不同的函数,例如 jsonb_to_record():

INSERT INTO contact (firstname, lastname, birthday)
SELECT firstname
     , lastname
     , birthday  
FROM jsonb_to_record(
    '{
      "firstname": "John",
      "lastname": "Doe",
      "birthday": "2023-09-28"
    }'::jsonb
    ) AS j(firstname text, lastname text, birthday date);
© www.soinside.com 2019 - 2024. All rights reserved.