PostgreSQL导入JSON报错:INSERT目标列数多于表达式数
解决PostgreSQL INSERT时「more target columns than expressions」错误
你遇到的INSERT has more target columns than expressions错误,本质是你指定的插入目标列数量,和SELECT子句返回的字段数量不匹配,再仔细看你的脚本,还有几个其他的小问题,我帮你逐一梳理并修正:
1. 错误使用了不匹配的行类型
你在json_populate_recordset里用了NULL::contacts,但你要插入的是books表啊!这个错误会导致JSON解析出来的字段和你预期的books表字段完全不匹配,直接造成列数不对的问题,应该改成NULL::books。
2. ON CONFLICT子句完全无效
- 你的
books表主键是自增的id,而你插入时并没有手动指定id值(由SERIAL自动生成),这种情况下几乎不可能触发主键冲突,这个子句在这里根本没必要。 - 退一步说,就算要保留冲突处理,你写的
SET name = excluded.name, active = excluded.active也是错的——你的books表根本没有name和active这两个字段!
3. 字段顺序隐含风险
就算行类型改对了,json_populate_recordset返回的字段顺序是按照表结构的定义顺序,而不是你INSERT语句里写的列顺序,所以最好明确指定SELECT的字段,和INSERT的目标列一一对应,避免踩坑。
修正后的完整SQL脚本
CREATE TABLE Books ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL, genre VARCHAR(255), year INTEGER, createdAt timestamp with time zone NOT NULL, updatedAt TIMESTAMP WITH TIME ZONE NOT NULL ); WITH books_json (doc) AS ( VALUES( '[ { "author": "Jane Austen", "createdAt": "2018-10-04 18:21:59.011 +00:00", "genre": "Classic", "title": "Emma", "updatedAt": "2018-10-04 18:21:59.011 +00:00", "year": 1815 } ]'::json ) ) INSERT INTO books (title, author, genre, year, createdAt, updatedAt) SELECT p.title, p.author, p.genre, p.year, p.createdat, p.updatedat FROM books_json l CROSS JOIN lateral json_populate_recordset(NULL::books, doc) AS p;
关键修正说明:
- 将
NULL::contacts替换为NULL::books,确保JSON解析后的字段与目标表结构匹配 - 移除了无效的
ON CONFLICT子句(如果之后需要处理重复数据冲突,建议基于title+author这类业务唯一键来设置,同时SET的字段要对应books表的列) - 明确指定SELECT的字段列表,和INSERT的目标列严格对应,避免因字段顺序不一致导致的问题
内容的提问来源于stack exchange,提问作者user2371290
相关产品推荐
相关产品推荐

