无法将old_orders所有记录插入new_orders?自增clientId问题解决
报错原因分析
错误Table new_orders has 17 columns but 16 values were supplied的核心是列数不匹配:
new_orders表包含17个字段,你的INSERT语句未指定目标列,数据库会按表定义的列顺序匹配SELECT返回的值;- 你的
SELECT仅返回16个值,遗漏了new_orders.clientId字段的赋值,导致数量不匹配。
自增主键未生效的原因
你认为clientId是自增列,但SQLite对自增主键有明确规则:
只有当主键被定义为INTEGER PRIMARY KEY(或显式添加AUTOINCREMENT)时,才会自动生成递增数值。你的表结构中clientId是INTEGER NOT NULL后单独声明PRIMARY KEY(clientId),虽然SQLite会隐式将其关联到ROWID(具备自增特性),但前提是插入时不为该列赋值或传入NULL,否则不会触发自增逻辑。
解决方法
方法1:指定插入列,让clientId自动生成
明确写出要插入的目标列(排除clientId),数据库会自动为clientId生成自增值:
INSERT INTO new_orders (clientGuid, exchangeId, marketId, id, accountType, listId, side, type, status, price, stopPrice, amount, filled, cost, createTime, updateTime) SELECT clientId, exchangeId, marketId, id, accountType, listId, side, type, status, price, stopPrice, amount, filled, cost, createTime, updateTime FROM old_orders;
这里old_orders.clientId对应new_orders.clientGuid,new_orders.clientId由数据库自动填充。
方法2:显式传入NULL触发自增
如果不想指定目标列,可以在SELECT开头添加NULL,对应new_orders.clientId触发自增逻辑:
INSERT INTO new_orders SELECT NULL, exchangeId, marketId, id, accountType, listId, clientId, side, type, status, price, stopPrice, amount, filled, cost, createTime, updateTime FROM old_orders;
注意顺序:第一个NULL对应new_orders.clientId,后面的clientId(来自old_orders)对应new_orders.clientGuid,列数刚好匹配17个。
可选:优化表结构明确自增特性
如果需要更明确的自增约束,可以修改new_orders的表结构,将clientId定义为:
clientId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
AUTOINCREMENT会保证ID严格递增且不会复用已删除的ID,适合对ID连续性有要求的场景。
内容的提问来源于stack exchange,提问作者Alexey Starinsky

