首页 > 解决方案 > 如何在 Go 中正确绑定 postgresql 变量?

问题描述

我有这个返回错误的函数sql: Rows are closed。我想不通为什么...

这是功能:

func GetUserFromToken(db *sql.DB, token string) User {
    query := `
        SELECT id, token, name, surname, phone, email FROM users WHERE token=$1
        `

    rows, err := db.Query(query, token)
    if err != nil {
        fmt.Println("query error : " + err.Error())
    }

    var user User
    rows.Next()
    err = rows.Scan(&user.ID, &user.Token, &user.Name, &user.Surname, &user.Phone, &user.Email)
    if err != nil {
        fmt.Println("scan error : " + err.Error())
    }

    return user
}

当我记录令牌时,它是正确的令牌。当我在查询中对令牌进行硬编码以进行测试时,它可以正常工作。例如 :

query := `
        SELECT id, token, name, surname, phone, email FROM users WHERE token='abcdefg12345'
        `

还尝试设置查询,例如:

query := "SELECT id, token, name, surname, phone, email FROM users WHERE token = $1"

row := db.QueryRow(query, "abcdefg12345")

它工作正常。fmt.Println(token)打印abcdefg12345

有人会帮助我了解我所缺少的吗?


更新:发现我失败了。

所以我拥有的令牌是从标头中提取的不记名令牌,具有以下功能:

func GetBearerToken(r *http.Request) string {
    reqToken := r.Header.Get("Authorization")
    splitToken := strings.Split(reqToken, "Bearer")
    reqToken = splitToken[1]
    return reqToken
}

在我的 fmt.Println 中有一个我没有注意到的前导空格。在考虑@RayfenWindspear 的评论一夜好眠之后,我强烈要求检查字符串长度,然后我看到了失败。感觉有点白痴和逗乐,同时我没有抓住它。

所以我的简单修复:从:reqToken = splitToken[1] 到: strings.TrimSpace(splitToken[1])

标签: postgresqlgo

解决方案


这是您编写此代码的方式。如果没有返回任何内容,则返回的错误将为 sql.ErrNoRows。让我知道这是如何工作的,然后也许我可以提供其他调试步骤。

func GetUserFromToken(db *sql.DB, token string) (u User, err error) {
  err = db.QueryRow(
    "SELECT id, token, name, surname, phone, email FROM users WHERE token=$1",
    token,
  ).Scan(
    &u.ID,
    &u.Token,
    &u.Name,
    &u.Surname,
    &u.Phone,
    &u.Email)
  return
}

推荐阅读