英文:
Reuse or copy *sql.Rows in Golang
问题
*sql.Rows
是一个结果集的迭代器,它在迭代过程中会不断地从数据库中获取下一行数据。一旦迭代完成,*sql.Rows
就会被标记为已关闭,不能再使用。
如果你想在迭代完成后将 *sql.Rows
传递给另一个函数使用,你可以将结果集的数据存储在一个切片或其他数据结构中,然后将该数据结构传递给另一个函数。
以下是一个示例代码:
rows, err := db.Query(...)
if err != nil {
// 错误处理
}
defer rows.Close()
var data []YourStruct // YourStruct 是你自定义的结构体类型
for rows.Next() {
var row YourStruct
err := rows.Scan(&row.Field1, &row.Field2) // 假设你的结构体有两个字段 Field1 和 Field2
if err != nil {
// 错误处理
}
data = append(data, row)
}
if err := rows.Err(); err != nil {
// 错误处理
}
anotherFunction(data) // 将数据传递给另一个函数进行处理
在这个示例中,我们使用一个切片 data
来存储结果集的数据。在迭代过程中,我们将每一行数据存储在一个结构体 YourStruct
中,并将该结构体添加到切片中。迭代完成后,我们将整个切片传递给 anotherFunction
进行处理。
请注意,在使用完 *sql.Rows
后,我们使用 defer rows.Close()
来确保结果集被正确关闭,以释放相关资源。
英文:
Is it possible to reuse the same *sql.Rows
after the *sql.Rows.Next()
was called so I could pass it to another function?
rows, err := db.Query(...)
for rows.Next() {
// rows.Scan()
}
anotherFunction(rows) // NOT WORKING: This rows became empty.
I tried to make another copy of the *sql.Rows
but it didn't work.
rows, err := db.Query(...)
anotherRows := *rows
// PANIC: call of load copies lock value: database/sql.Rows contains sync.RWMutex
答案1
得分: 3
database/sql
包在读取完Rows后没有提供任何重置(rewind)Rows的方法,也就是说它是一个“只能向前”的结果集。
此外,它会在内部保持与底层(物理)数据库连接的链接,因此复制或传递它是一个不好的主意。
如果你需要对数据应用多个函数,只需使用Scan
方法读取所有的行,得到一个数据对象的切片,然后将其传递给其他函数。
Scan
方法会复制你读取的数据:
Scan
将匹配的行的列复制到dest
指向的值中。
因此,你可以安全地关闭Rows
对象(释放任何相关的数据库资源)。
在执行查询后(err
)和读取行后,你还应该注意错误,可以通过rows.Err()
来获取。
英文:
The database/sql
package does not provide any means to rewind
the Rows, after you have read them, i.e. it is a "forward only" result set.
Moreover, it will maintain a link to the underlying (physical) database connection, inside it, making it a bad idea to copy it or pass it around.
If you need to apply multiple functions to your data, just Scan
all the rows, to get a slice of data objects, and then pass this around.
Scan will make a copy of the data you read:
>Scan copies the columns from the matched row into the values pointed at by dest.
so you can then safely Close
your Rows
object (releasing any associated database resources).
You should watch out for errors too, after executing the Query (err
) and after reading the rows, via rows.Err()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论