当 Go 的 database/sql 驱动从 MySQL 等数据库读取浮点型字段(如 DECIMAL 或 FLOAT)并以科学计数法字符串(如 "1.461988e+06")返回时,直接扫描到 int 类型会因 strconv.ParseInt 无法解析指数格式而报错;需先转为浮点数,再安全转换为整型或使用 *big.Int。
当 go 的 database/sql 驱动从 mysql 等数据库读取浮点型字段(如 `decimal` 或 `float`)并以科学计数法字符串(如 `"1.461988e+06"`)返回时,直接扫描到 `int` 类型会因 `strconv.parseint` 无法解析指数格式而报错;需先转为浮点数,再安全转换为整型或使用 `*big.int`。
该错误 sql: Scan error on column index 7: converting string "1.461988e+06" to a int 的根本原因在于:数据库实际返回的是一个浮点数值的字符串表示(科学计数法),而非纯整数字符串。Go 的 rows.Scan(&intVar) 内部调用 strconv.ParseInt,而该函数仅支持形如 "1234567" 的十进制整数字符串,不支持 "1.461988e+06" 这类含小数点与指数符号的浮点格式——即使该值在数学上等价于整数 1461988。
✅ 正确处理流程
- 确认数据库字段类型:检查 SQL 查询中对应列(如本例第 7 列 credit5)的真实类型。若为 DECIMAL(12,6)、FLOAT、DOUBLE 或 NUMERIC,则应使用 float64 接收;
- 修改结构体字段类型:将 Credit5 int 改为 Credit5 float64;
- 按需做整型转换:若业务逻辑确实需要整数值(如积分、计数),应在 Scan 后显式转换,并处理精度与溢出风险。
? 示例修复代码
// 修改结构体定义(关键!)
type Userdaytotalstat_s struct {
Stepdistance float64 // 原 int → 改为 float64
Stepdaywanbu int
Stepnumber int
Credit1 float64 // 所有 creditX 字段均改为 float64
Credit2 float64
Credit3 float64
Credit4 float64
Credit5 float64 // ← 第 7 列,原报错位置
Credit6 float64
Credit7 float64
Credit8 float64
Stepdaypass int
Timestamp int64
Walkdate time.Time
}
// Scan 保持不变,但字段类型已匹配
err := rows.Scan(
&udts.Stepdistance,
&udts.Stepdaywanbu,
&udts.Stepnumber,
&udts.Credit1, &udts.Credit2, &udts.Credit3,
&udts.Credit4, &udts.Credit5, &udts.Credit6,
&udts.Credit7, &udts.Credit8,
&udts.Stepdaypass,
&udts.Timestamp,
&udts.Walkdate,
)
if err != nil {
log.Printf("Scan failed: %v", err)
return err
}
// 后续如需整数语义(例如积分必须为整),安全转换:
credit5Int := int64(udts.Credit5) // 注意:截断小数部分(非四舍五入)
// 或更严谨地判断是否为整数值:
if math.Abs(udts.Credit5-float64(int64(udts.Credit5))) < 1e-9 {
credit5Int = int64(udts.Credit5)
} else {
log.Printf("Warning: Credit5=%f is not an exact integer", udts.Credit5)
}⚠️ 注意事项
- 不要强行用 []byte + strconv.ParseInt 解析原始字节:database/sql 默认对数字类型返回字符串时已做格式化(可能含 e+XX),手动解析易出错且不可移植;
- 避免使用 big.Int 常规场景:示例中 big.NewFloat(e).Int64() 仅适用于极端大数(如 1e1000),日常业务中 float64 足够覆盖 ±1.8e308,且 int64 最大为 9.2e18,只要数值在 float64 精度范围内(≤ 2⁵³ ≈ 9e15),int64(x) 是安全的;
- 预防性设计建议:在建表时,若字段语义为“整数”(如步数、积分),应优先使用 BIGINT 或 INT 类型,而非 DECIMAL/NUMERIC;若必须用小数类型,请在应用层统一约定接收为 float64 并文档化精度行为。
通过类型对齐与显式转换,即可彻底规避该 Scan 错误,同时保障数据精度与程序健壮性。


















