postgresql “sql:结果集中没有行”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48932423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:41:29  来源:igfitidea点击:

"sql: no rows in result set"

sqlpostgresqlgo

提问by 223seneca

I am handling user auth data posted to my Go backend through an HTML form. I am building on some boilerplateto learn Go better.

我正在处理通过 HTML 表单发布到我的 Go 后端的用户身份验证数据。我正在建立一些样板来更好地学习 Go。

My problem is what the following funcreturns:

我的问题是以下func返回的内容:

func (ctrl UserController) Signin(c *gin.Context) {

  var signinForm forms.SigninForm
  user, err := userModel.Signin(signinForm)

  if err := c.ShouldBindWith(&signinForm, binding.Form); err != nil {
      c.JSON(406, gin.H{"message": "Invalid signin form", "form": signinForm})
      c.Abort()
      return
  }

    if err == nil {
        session := sessions.Default(c)
        session.Set("user_id", user.ID)
        session.Set("user_email", user.Email)
        session.Set("user_name", user.Name)
        session.Save()

        c.JSON(200, gin.H{"message": "User signed in", "user": user})
    } else {
        c.JSON(406, gin.H{"message": "Invalid signin details", "error": err.Error()})
    }

}

The first ifstatement validates the input, and that works fine (error if the email isn't in proper email format, no error if it is). However, if input is properly validated, the elseclause of the second statement is triggered, and the following JSON is returned:

第一个if语句验证输入,并且工作正常(如果电子邮件不是正确的电子邮件格式,则错误,如果是,则没有错误)。但是,如果正确验证输入,else则会触发第二个语句的子句,并返回以下 JSON:

{
error: "sql: no rows in result set",
message: "Invalid signin details"
}

It is probably useful to also post the relevant code in my Usermodel:

在我的User模型中发布相关代码可能也很有用:

//User ...
type User struct {
    ID        int    `db:"id, primarykey, autoincrement" json:"id"`
    Email     string `db:"email" json:"email"`
    Password  string `db:"password" json:"-"`
    Name      string `db:"name" json:"name"`
    UpdatedAt int64  `db:"updated_at" json:"updated_at"`
    CreatedAt int64  `db:"created_at" json:"created_at"`
}

//UserModel ...
type UserModel struct{}

//Signin ...
func (m UserModel) Signin(form forms.SigninForm) (user User, err error) {

    err = db.GetDB().SelectOne(&user, "SELECT id, email, password, name, updated_at, created_at FROM public.user WHERE email=LOWER() LIMIT 1", form.Email)

    if err != nil {
        return user, err
    }

    bytePassword := []byte(form.Password)
    byteHashedPassword := []byte(user.Password)

    err = bcrypt.CompareHashAndPassword(byteHashedPassword, bytePassword)

    if err != nil {
        return user, errors.New("Invalid password")
    }

    return user, nil
}

How do I resolve the sql: no rows in result seterror?

如何解决sql: no rows in result set错误?

采纳答案by Pavlo Strokov

You should change the order of operations in your code. At first you need to get data from request with if err := c.ShouldBindWith(&signinForm, binding.Form); err != nil {and after that you need to try get data from database with user, err := userModel.Signin(signinForm)

您应该更改代码中的操作顺序。首先你需要从请求中获取数据,if err := c.ShouldBindWith(&signinForm, binding.Form); err != nil {然后你需要尝试从数据库中获取数据user, err := userModel.Signin(signinForm)

回答by Onkar Banerjee

There are good reasons for this. Ideally it tries to read paths by the separator, meaning /path/abcd/and /path/abcdare different. abcdIS the resource in the latter while the resource lies somewhere within abcdin the former. With that in mind, then it will not be able to route properly to /path/abcdif you also have a path /pathas well. In order to remove that ambiguity as to which handler to use, you need to mention the handler for the more specific path ie, /path/abcdbefore the more generic one /path.

这有充分的理由。在理想情况下它会尝试通过分离器以读取路径,这意味着/path/abcd//path/abcd是不同的。abcd是后者的资源,而资源位于abcd前者的某处。考虑到这一点,/path/abcd如果您也有路径,那么它将无法正确路由到/path。为了消除关于使用哪个处理程序的歧义,您需要提及更具体路径的处理程序,即,/path/abcd在更通用的路径之前/path