为了账号安全,请及时绑定邮箱和手机立即绑定

如果未找到行,QueryRow().Scan() 将返回错误。怎么解决?

如果未找到行,QueryRow().Scan() 将返回错误。怎么解决?

Go
qq_笑_17 2023-07-10 16:46:35
我花了很多时间试图解决这个问题。我有一个结构:type Token struct {    Id             *int64     `db:"id"`    Email          *string    `db:"email"`    OperationType  *string    `db:"operation_type"`    Token          *string    `db:"token"`    ExpirationDate *time.Time `db:"expiration_date"`}我有一个通过电子邮件查找一个令牌的函数:func (r Repo2) FindOneByEmail(ctx context.Context, email string, ct *Token) error {    row := r.DB.QueryRow(`        SELECT id, email, operation_type, token, expiration_date         FROM tokens         WHERE email=$1 AND type=$2 AND expiration_date>$3::date`,        email, "registration", time.Now(),    )    err := row.Scan(&ct.Id, &ct.Email, &ct.OperationType, &ct.Token, &ct.ExpirationDate)    if err != nil {        return err    }    return nil}db 中的某些字段可以为空(这就是我在结构中使用指针的原因)但是当我执行 .Scan 时,它会抛出错误(因为值为空,所以它不能采用地址“&”)但是如果我删除“&”,它也会抛出错误“无效的内存地址或零指针取消引用”那么我该如何解决这个问题呢?想法是:如果找到一行,则需要获取字段值,但如果未找到行,则需要抛出 sql.ErrNoRows
查看完整描述

1 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

pgx驱动解决方案:


从结构中删除指针


type Token struct {

    Id             int64     `db:"id"`

    Email          string    `db:"email"`

    OperationType  string    `db:"operation_type"`

    Token          string    `db:"token"`

    ExpirationDate time.Time `db:"expiration_date"`

}

重写功能


func (r Repo2) FindOneByEmail(ctx context.Context, email string, ct *Token) error {

    var date pgtype.Timestamptz


    row := r.DB.QueryRow(`

        SELECT id, email, operation_type, token, expiration_date 

        FROM tokens 

        WHERE email=$1 AND type=$2 AND expiration_date>$3::date`,

        email, "registration", time.Now().UTC(),

    )


    err := row.Scan(&ct.Id, &ct.Email, &ct.OperationType, &ct.Token, &date)

    if err != nil {

        return err

    }


    ct.ExpirationDate = date.Time


    return nil

}


查看完整回答
反对 回复 2023-07-10
  • 1 回答
  • 0 关注
  • 97 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信