Golang REST API按ID查询Metric返回全0/空值问题排查
Golang REST API查询返回全零值问题排查
问题现象
- 基于Golang开发REST API过程中,调试运行时通过路由参数获取
metricId查询得到的Metric对象所有字段均为0或空值,接口返回结果与调试打印的对象值完全一致 - 已确认数据库连接正常,暂未定位到问题原因
问题相关代码
接口处理函数代码如下:
func GetMetricById(c *gin.Context) { metricId := c.Param("id") conn := config.DatabaseConnect() var obj models.Metric rows := conn.QueryRow("SELECT * FROM Metric WHERE id = ?", metricId) err := rows.Scan(&obj.Id, &obj.Sms, &obj.Absence, &obj.Pregnant, &obj.Uwv_notifications, &obj.Wia_dossiers_started, &obj.Employees, &obj.Data_id, &obj.Date, &obj.Type) if err != nil { fmt.Println(err.Error()) } fmt.Println(obj, "Metric Object that is called.") c.JSON(http.StatusOK, obj) }
实际接口返回
{ "Id": 0, "Sms": 0, "Absence": 0, "Pregnant": 0, "Uwv_notifications": 0, "Wia_dossiers_started": 0, "Employees": 0, "Data_id": 0, "Date": "", "Type": 0 }
排查方向与修复方案
- 优先处理被忽略的Scan错误
现有代码仅打印Scan错误但未中断执行流程,只要查询无匹配数据、字段顺序错位、类型不匹配导致Scan失败,代码就会把初始化生成的零值obj直接返回,这是该问题最高发的诱因。
注意:使用SELECT *查询时,返回的列顺序严格遵循数据库表的字段定义顺序,和你在Scan中传入的字段指针顺序不一定匹配,一旦顺序错位就会触发类型不匹配错误,最终赋值失败返回零值。
修复操作:- 替换
SELECT *为明确的字段列表,保证查询返回的字段顺序和Scan传入的参数顺序完全一一对应 - Scan捕获到错误时直接返回错误响应,不要继续向下执行返回零值对象,参考修改:
err := rows.Scan(&obj.Id, &obj.Sms, &obj.Absence, &obj.Pregnant, &obj.Uwv_notifications, &obj.Wia_dossiers_started, &obj.Employees, &obj.Data_id, &obj.Date, &obj.Type) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - 替换
- 校验路由参数取值
检查路由定义的参数名和c.Param()传入的key是否一致,例如路由定义为/metric/:metricId时,c.Param("id")会拿到空字符串,用空值作为查询条件自然匹配不到数据。可在获取metricId后加打印逻辑,确认拿到的参数值和预期一致。 - 校验数据库连接与数据存在性
确认config.DatabaseConnect()连接的是目标环境的数据库实例,将代码中执行的SQL语句复制到数据库客户端手动执行,验证对应id的数据是否真实存在。 - 校验结构体字段类型匹配
检查models.Metric的字段类型和数据库对应字段的类型是否兼容,例如数据库中Date字段为datetime/timestamp类型时,用string字段接收会触发Scan错误,导致赋值失败。
内容的提问来源于stack exchange,提问作者Qukz
相关产品推荐
相关产品推荐

