在使用`rows.NextResultSet()`进行多结果集查询时,调用`rows.Err()`。

huangapple go评论76阅读模式
英文:

Calling rows.Err() in a multiple result set query with rows.NextResultSet()

问题

我正在构建一个包含多个结果集的查询,按照给出的示例这里进行操作。为了方便起见,我复制了重要的部分。

我的问题是,是否应该在每个for rows.Next() {...}循环之后调用rows.Err(),而不是像示例中那样在最后一次调用?为什么/为什么不?我理解rows.Err()会捕获在迭代过程中遇到的错误,而rows.NextResultSet()会捕获"前进到下一个结果集时遇到的错误"。看起来我应该在每次迭代过程中捕获错误,对吗?谢谢!

rows, err := db.Query(q, age)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
    var (
        id   int64
        name string
    )
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("id %d name is %s\n", id, name)
}
if !rows.NextResultSet() {
    log.Fatal("expected more result sets", rows.Err())
}
var roleMap = map[int64]string{
    1: "user",
    2: "admin",
    3: "gopher",
}
for rows.Next() {
    var (
        id   int64
        role int64
    )
    if err := rows.Scan(&id, &role); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("id %d has role %s\n", id, roleMap[role])
}
if err := rows.Err(); err != nil {
    log.Fatal(err)
}
英文:

I'm building a query with multiple result sets, following the example given, here. Important bits copied below for convenience.

My question is, should rows.Err() be called after each for rows.Next() {...} loop, rather than once at the very end as shown in the example? Why / why not? My understanding is that rows.Err() will catch errors, "... encountered during iteration", whereas rows.NextResultSet() will catch, "... [errors] advancing to [the next result set]". Seems like I would want to catch errors during each iteration, no? Thanks!

rows, err := db.Query(q, age)
if err != nil {
	log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
	var (
		id   int64
		name string
	)
	if err := rows.Scan(&id, &name); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("id %d name is %s\n", id, name)
}
if !rows.NextResultSet() {
	log.Fatal("expected more result sets", rows.Err())
}
var roleMap = map[int64]string{
	1: "user",
	2: "admin",
	3: "gopher",
}
for rows.Next() {
	var (
		id   int64
		role int64
	)
	if err := rows.Scan(&id, &role); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("id %d has role %s\n", id, roleMap[role])
}
if err := rows.Err(); err != nil {
	log.Fatal(err)
}

答案1

得分: 2

你可以从NextErrNextResultSet函数的源代码中找到Rows结构体的lasterr成员,它可以通过几种方式进行设置,如果不是EOFErr函数总是返回它。

这些方式包括:

  1. Next函数遇到错误时,会设置lasterr并始终返回false(因此for rows.Next() {...不会再迭代,只需在循环后检查rows.Err()即可)。
  2. NextResultSet函数在遇到错误时也会设置lasterr,并返回false

所以答案是肯定的,它应该这样做。因为如果NextResultSetNext之后返回false,它的错误会替换Next的错误。

英文:

You can find from source code of Next or Err or NextResultSet function that there is lasterr member of Rows structure which can be set by several ways and Err always return it if it isn't EOF.

Those ways are:

  1. Next gets some error, sets lasterr and always returns false (so for rows.Next() {... doesn't iterate more and it is enough to check rows.Err() only after the loop.
  2. NextResultSet also sets lasterr whenever it gets error and also returns false.

So answer is yes, it should. Because if NextResultSet after Next returns false its error replaces error from Next.

huangapple
  • 本文由 发表于 2017年8月16日 01:06:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/45697851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定