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

Golang Gin REST API POST正常但GET查询数据报错问题排查

问题排查与解决

1. 字段顺序不匹配

你用SELECT * FROM table查询时,返回的字段顺序必须和rows.Scan的参数顺序完全一致。从你的INSERT语句看,表字段顺序大概率是id, title, body, titles, contents, date,但你当前Scan的顺序把Date放在了数组字段前面,这会导致类型匹配错误。

解决:要么明确指定SELECT的字段顺序(推荐,避免表结构变更出问题),要么调整Scan参数顺序:

// 明确指定字段,和结构体字段对应
rows, err := db.Query("SELECT id, title, body, titles, contents, date FROM table")
// Scan顺序严格对应查询字段
err := rows.Scan(&job.ID, &job.Title, &job.Body, pq.Array(&job.Titles), pq.Array(&job.Contents), &job.Date)

2. 数组类型扫描错误

PostgreSQL的数组类型不能直接扫描到Go的固定长度数组[4]string里,必须像插入时那样用pq.Array()包裹指针,否则会触发类型不匹配错误,这是GET接口失败的核心原因。

解决:扫描数组字段时用pq.Array()包裹:

err := rows.Scan(
    &job.ID,
    &job.Title,
    &job.Body,
    pq.Array(&job.Titles),
    pq.Array(&job.Contents),
    &job.Date,
)

3. 错误信息太笼统

你当前的错误提示都是“failed to retrieve jobs”,根本没法定位具体问题。应该把原始错误信息返回,方便排查:

if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to scan job: %v", err)})
    return
}

4. 遗漏遍历后的错误检查

rows.Next()返回false不一定是遍历结束,也可能是出错了,必须在循环结束后检查rows.Err():

for rows.Next() {
    // 现有遍历代码
}
// 检查遍历过程中是否出现错误
if err := rows.Err(); err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("rows iteration error: %v", err)})
    return
}

修正后的GET接口完整代码

r.GET("/jobs", func(c *gin.Context) {
    rows, err := db.Query("SELECT id, title, body, titles, contents, date FROM table")
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to query jobs: %v", err)})
        return
    }
    defer rows.Close()

    jobs := []Job{}
    for rows.Next() {
        var job Job
        err := rows.Scan(
            &job.ID,
            &job.Title,
            &job.Body,
            pq.Array(&job.Titles),
            pq.Array(&job.Contents),
            &job.Date,
        )
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to scan job: %v", err)})
            return
        }
        jobs = append(jobs, job)
    }

    if err := rows.Err(); err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("rows iteration error: %v", err)})
        return
    }

    c.JSON(http.StatusOK, jobs)
})

内容的提问来源于stack exchange,提问作者Coding write

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:05:31