我花了很多时间试图解决这个问题。
我有一个结构:
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"`
}
我有一个通过电子邮件找到一个 token 的函数:
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
最佳答案
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
}
关于sql - 如果未找到行,QueryRow().Scan() 将返回错误。怎么解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57444649/