Golang中如何只查询一行数据QueryRow(x)?

Golang中如何只查询一行数据QueryRow(x)? 这段代码用于获取多行数据。据我所知,它运行得很好。 https://api.go4webdev.org/ques

func Get(query string) interface{} {
	// execute query to postgresql db
	if len(query) > 0 {
		var list []map[string]interface{}
		rows, err := db.Queryx(query)
		if err != nil {
			fmt.Println("no records")
		}
		defer rows.Close()
		for rows.Next() {
			row := make(map[string]interface{})
			err = rows.MapScan(row)
			if err != nil {
				log.Fatal(err)
			}
			list = append(list, row)
		}
		rows.Close()
		if len(list) == 0 {
			return ("norec")
		}
		return list
	}
	return nil
}

问题是如何用同样的方法处理单一行数据?期望的结果是(不带方括号):

{“que_desc”:“Sexual dysfunction, unspecified”,“que_id”:2,“que_subject”:“Robust upward-trending instruction set”}

我尝试过实现这个功能,但没有成功。


更多关于Golang中如何只查询一行数据QueryRow(x)?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

我的错,我想当你扫描到映射时,你需要的是 MapScan。试试用 MapScan 而不是 StructScan

更多关于Golang中如何只查询一行数据QueryRow(x)?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


skillian:

直接传递映射即可。

最终我让它成功运行了。方法简单而优雅。

row := make(map[string]interface{})
db.QueryRowx(query, val).MapScan(row)
return (row)

https://api.go4webdev.org/c_que?id=2

非常感谢!

错误信息表明,不能将指向映射的指针作为映射传递。只需直接传递映射本身,而不要取其地址。这与你最初帖子中的 err = rows.MapScan(row) 这行代码没有区别,区别仅在于你是在 *sqlx.Row 上调用它,而不是在 *sqlx.Rows 上。

只需使用 QueryRow,或者如果你在使用 sqlx,可以使用 Get。例如:

var count int
count; err = tx.QueryRow("SELECT count(database_id) FROM database_tr WHERE database_id = $1", id).Scan(&count)
fmt.Println(count)

skillian:

只需直接传入映射,而无需取其地址。这与 err = rows.MapScan(row) 并无不同。

我不太明白。这样会返回 “null”:

data := db.QueryRowx(query, val).MapScan(make(map[string]interface{}))
fmt.Println(data)
return (data)

这样也是 “null”:

rows := db.QueryRowx(query, val)
results := make(map[string]interface{})
rows.MapScan(results)
return results

我哪里做错了?

var subject string
db.QueryRow("SELECT que_subject FROM ques WHERE que_id = $1", 2).Scan(&subject)
return (subject)

但是结果只有一列,没有花括号,也没有标签。

这个查询选择单个列并将其扫描到单个字符串字段中。如果你改为选择所有需要的列(例如,也许使用 SELECT * FROM ...),然后使用

row := make(map[string]interface{})
db.QueryRowx(query, val).StructScan(&row)

我预计这会起作用。

此查询选择单个列并将其扫描到单个字符串字段中。如果你改为选择所有需要的列(例如,也许使用 SELECT * FROM ...),然后使用以下代码:

row := make(map[string]interface{})
db.QueryRowx(query, val).StructScan(&row)

我预计这会奏效。

我无法让它工作。你是说像这样吗?

db.QueryRowx("SELECT * FROM ques LIMIT 1")
row := make(map[string]interface{})
db.QueryRowx("SELECT * FROM ques WHERE que_id = $1", 2).StructScan(&row)
return (row)

返回一个空的 map[]

方向是对的

var subject string
db.QueryRow("SELECT que_subject FROM ques WHERE que_id = $1", 2).Scan(&subject)
return (subject)

但结果只有一个列,没有花括号,也没有标签。

“稳健的上升趋势指令集”

目标是得到 JSON:

{“que_desc”:“未明确的性功能障碍”,“que_id”:2,“que_subject”:“稳健的上升趋势指令集”}

我正在寻找一个更通用(?)的解决方案,像下面这样的伪代码:

row := make(map[string]interface{})
db.QueryRowx(query, val).StructScan(&row)
return row

这可能实现吗?

试试用那个代替 StructScan

谢谢。

是,也不是。这个方法对 db.Queryx 有效,但对 db.QueryRow 无效。

(类型 *sqlx.Row 没有字段或方法 Next)

rows := db.Queryx(query, val)
for rows.Next() {
    results := make(map[string]interface{})
    rows.MapScan(results)
    return results
}

对于 db.QueryRowx 有等效的代码吗?像这样:

row := make(map[string]interface{})
data := db.QueryRowx(query, val).MapScan(&row)
return (data)

报错:

无法在参数中将 &row (类型 *map[string]interface {}) 作为 map[string]interface {} 类型传递给 db.QueryRowx(query, val).MapScan

对于查询单行数据,推荐使用 QueryRow 配合 StructScan 或直接扫描到变量。以下是针对单行查询的修改示例:

func GetSingleRow(query string) interface{} {
    if len(query) == 0 {
        return nil
    }
    
    // 定义结构体来映射查询结果
    type Question struct {
        QueID      int    `db:"que_id"`
        QueSubject string `db:"que_subject"`
        QueDesc    string `db:"que_desc"`
    }
    
    var result Question
    err := db.QueryRowx(query).StructScan(&result)
    if err != nil {
        if err == sql.ErrNoRows {
            return "norec"
        }
        log.Printf("查询失败: %v", err)
        return nil
    }
    
    // 返回map格式(与你的期望输出匹配)
    return map[string]interface{}{
        "que_id":      result.QueID,
        "que_subject": result.QueSubject,
        "que_desc":    result.QueDesc,
    }
}

如果不想定义结构体,也可以直接扫描到map:

func GetSingleRowToMap(query string) interface{} {
    if len(query) == 0 {
        return nil
    }
    
    row := db.QueryRowx(query)
    if row == nil {
        return "norec"
    }
    
    result := make(map[string]interface{})
    err := row.MapScan(result)
    if err != nil {
        if err == sql.ErrNoRows {
            return "norec"
        }
        log.Printf("扫描失败: %v", err)
        return nil
    }
    
    return result
}

或者直接扫描到具体变量:

func GetSingleRowDirect(query string) interface{} {
    if len(query) == 0 {
        return nil
    }
    
    var queID int
    var queSubject, queDesc string
    
    err := db.QueryRow(query).Scan(&queID, &queSubject, &queDesc)
    if err != nil {
        if err == sql.ErrNoRows {
            return "norec"
        }
        log.Printf("查询失败: %v", err)
        return nil
    }
    
    return map[string]interface{}{
        "que_id":      queID,
        "que_subject": queSubject,
        "que_desc":    queDesc,
    }
}

关键点:

  1. QueryRow 用于单行查询,查询无结果时返回 sql.ErrNoRows
  2. StructScan 需要定义对应的结构体字段标签
  3. MapScan 直接扫描到 map[string]interface{}
  4. 必须处理 sql.ErrNoRows 错误情况
回到顶部