How do I get the number of rows returned while using database/sql?

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

How do I get the number of rows returned while using database/sql?

问题

给定以下函数:

func (me *OrderService) GetOrders(orderTx *sql.Tx, orderId int) (orders *sql.Rows) {
    orders, err := ecommTx.Query("SELECT * FROM orders WHERE id=?", orderId)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Successfully queried and receive %d orders", orders.count)
    return orders
}

有没有简单的方法来计算结果的数量?我想保持数据库引擎的通用性,但是我在集成测试中使用了Matt N的sqlite3驱动,但是计划在生产环境中使用不同的数据库。

英文:

Given the following function:

func (me *OrderService) GetOrders(orderTx *sql.Tx, orderId int) (orders *sql.Rows) {
    orders, err := ecommTx.Query("SELECT * FROM orders WHERE id=?", orderId)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Successfully queried and receive %d orders", orders.count)
    return orders
}

Are there any easy ways to .count the results? I'd like to keep this database engine agonistic, but FWIW.... I'm using Matt N's sqlite3 driver for my integration tests, but plan on having a different DB in prod.

答案1

得分: 3

没有一种便携的方法可以事先知道语句返回的行数,也就是说在迭代返回的游标并计数之前无法知道。

有两种典型的解决方案:

  • 运行一个单独的 COUNT(*) 查询。 这种方法的问题在于它非常有竞争性(结果集可以在两个查询之间被修改,至少在某些事务隔离模式下是这样),因此它只对像分页器这样的情况有用,你可以执行一个只返回结果集的查询,并想知道还有多少其他行。

  • 迭代游标并计数。 在 Go 中,这意味着调用 .Next(),然后将结果扫描到你的 Order 结构中。

英文:

There is no portable way to know the number of rows returned by a statement in advance, meaning without iterating through the returned cursor and counting.

There are two typical solutions to this:

  • Run a separate COUNT(*) query. The problem with this approach is that it's very racy (the result set can be modified between the two queries, at least in some transaction isolation modes), so it is really only useful for things like pagers where you do a query that returns only part of the result set, and want to know how many other rows there are.

  • Iterate through the cursor and count. In Go, that means calling .Next() and then .Scan the result into your Order struct.

答案2

得分: 2

sql.Query() 返回的是 *RowsRows 是一个读取器,而不是一个集合,因此诸如 count()len() 等调用是不相关的。你必须通过读取 Rows 来知道你有多少条记录:

count := 0
for orders.Next() {
    count++
}

log.Printf("成功查询并接收到 %d 条订单", count)

这样做并不会增加额外的开销。其他语言(如 C# 或 Delphi)可能会返回一个带有 count 属性的集合,它们只是为了方便起见,为你进行了读取并将结果打包到集合中。

英文:

sql.Query() returns *Rows. Rows is a reader, not a collection, so calls such as count() or len() etc. are not relevant. You have to read through Rows to know how many entries you've got:

count := 0
for orders.Next() {
	count++
}

log.Printf("Successfully queried and receive %d orders", count)

You are not adding any extra overhead by doing so. Other languages, such as C# or Delphi, that might return a collection with a count property are simply doing the reading for you and packaging the results into a collection for your convenience.

huangapple
  • 本文由 发表于 2014年2月27日 23:54:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/22073633.html
匿名

发表评论

匿名网友

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

确定