如何判断pgx.Row是否为空?解决查询空值时err始终为nil的问题
正确判断pgx查询结果是否为空的方法
你当前的问题出在对pgx.Query()的错误理解上:pgx.ErrNoRows这个错误只会由QueryRow()方法返回,当使用Query()查询时,即使结果集为空,返回的err依然是nil——因为空结果集本身不属于查询错误。
方法一:使用Query()时的判断逻辑
如果你的查询预期返回多行结果,需要通过rows.Next()来判断是否存在数据,同时要处理遍历过程中的错误:
rows, err := r.db.Query(r.ctx, getFilmCastQuery, FilmId) if err != nil { logs.LogError(logs.Logger, "films_postgresql", "GetFilmCast", err, err.Error()) return nil, err } defer rows.Close() // 必须确保关闭rows对象,避免资源泄漏 // 检查是否有第一行数据 if !rows.Next() { // 先检查遍历过程中是否有错误 if scanErr := rows.Err(); scanErr != nil { logs.LogError(logs.Logger, "films_postgresql", "GetFilmCast", scanErr, scanErr.Error()) return nil, scanErr } // 确认无数据,返回NotFound错误 return nil, domain.ErrNotFound } // 处理第一行数据(示例) var cast Cast if scanErr := rows.Scan(&cast.ID, &cast.Name); scanErr != nil { logs.LogError(logs.Logger, "films_postgresql", "GetFilmCast", scanErr, scanErr.Error()) return nil, scanErr } // 如果需要处理多行,继续循环rows.Next()...
方法二:改用QueryRow()(适合单行查询场景)
如果你的查询逻辑预期最多返回一行数据,使用QueryRow()会更简洁,它会在无匹配行时直接返回pgx.ErrNoRows:
var cast Cast err := r.db.QueryRow(r.ctx, getFilmCastQuery, FilmId).Scan(&cast.ID, &cast.Name) if err != nil { if err == pgx.ErrNoRows { return nil, domain.ErrNotFound } logs.LogError(logs.Logger, "films_postgresql", "GetFilmCast", err, err.Error()) return nil, err } return &cast, nil
核心要点
Query()返回的是多行结果集,空结果集不属于错误,必须通过rows.Next()的返回值判断是否有数据QueryRow()专为单行查询设计,无匹配行时会返回pgx.ErrNoRows- 使用
Query()时务必通过defer rows.Close()释放资源,避免数据库连接泄漏
内容的提问来源于stack exchange,提问作者Алексей Молдованов
相关产品推荐
相关产品推荐

