You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang操作PostgreSQL插入数据后出现Scan类型转换错误

问题原因分析

从错误信息来看,你的INSERT ... RETURNING id语句实际返回了多列(包含password_changed_at),但你只提供了一个int类型变量newID接收结果,导致驱动尝试将第8列(索引7)的time.Time类型值转换为int时失败。

可能的根源:

  • 数据库触发器影响:users表可能存在INSTEAD OF INSERT触发器,该触发器返回了完整行数据而非仅id列,覆盖了RETURNING id的结果。
  • SQL语句意外修改:实际运行的代码中,SQL语句可能被改成了RETURNING *而非RETURNING id(比如变量作用域冲突、字符串拼接错误)。
  • 类型不匹配隐患:id是bigserial(对应PostgreSQL的bigint类型),但你用int类型接收,虽不是当前错误的直接原因,但可能引发后续溢出问题。
解决步骤

1. 验证SQL语句的实际返回结果

在PostgreSQL客户端(如psql)中执行以下语句,确认返回列数:

INSERT INTO users (email, first_name, last_name, hashad_password, active, roll_id) 
VALUES ('test_trigger@example.com', 'Test', 'User', 'dummy_hash', 1, 3) 
RETURNING id;

如果仅返回id一列,说明问题出在代码层面;如果返回多列,说明数据库中存在触发器或其他逻辑修改了返回结果。

2. 检查并处理触发器

若上述SQL返回多列,执行以下语句查看users表的触发器:

SELECT tgname, pg_get_triggerdef(t.oid) 
FROM pg_trigger t 
JOIN pg_class c ON t.tgrelid = c.oid 
WHERE c.relname = 'users' AND t.tgisinternal = false;
  • 如果存在INSTEAD OF INSERT触发器,修改触发器函数使其仅返回id列,或调整INSERT语句的RETURNING子句匹配触发器返回结果。
  • 若不需要该触发器,直接删除:
    DROP TRIGGER trigger_name ON users;
    

3. 修正代码中的类型和语句问题

调整newID的类型为int64以匹配bigserial,同时确保SQL语句正确:

var newID int64
stmt := `INSERT INTO users (email, first_name, last_name, hashad_password, active, roll_id) values ($1, $2, $3, $4, $5, $6) returning id`

err = db.QueryRow(stmt,
    user.Email,
    user.FirstName,
    user.LastName,
    hashedPassword,
    user.Active,
    user.RollId,
).Scan(&newID)

if err != nil {
    return 0, err
}
return newID, nil

4. 确认代码逻辑正确性

检查代码中是否存在变量覆盖、字符串拼接错误等情况,确保实际执行的SQL确实是RETURNING id而非其他内容。

内容的提问来源于stack exchange,提问作者Girish Bhutiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:07:44