使用db.Query返回多列数据

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

Go Using db.Query to return more than one column

问题

在Go SQL文档中,他们给出了一个示例在这里,该查询只返回一个列(在我看来是个糟糕的示例,至少应该返回两个...)

age := 27
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
        log.Fatal(err)
}
for rows.Next() {
        var name string
        if err := rows.Scan(&name); err != nil {
                log.Fatal(err)
        }
        fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
        log.Fatal(err)
}

文档在这里说明了
Scan将当前行的列复制到dest指向的值中。

如果我有一个结构体,比如说我有一个结构体

type User struct{
    Name string
    Age int
}

并且我将查询修改为SELECT name, age from users where age=?

如何将*Rows解包到我的结构体中?我找到了这个示例,但它没有涉及到结构体。我将遵循Active Record模式的约定,因此我的结构体将通过蛇形转换映射到我的数据库。

英文:

In the Go SQL docs they give an example here of a query that only returns 1 column (poor example in my opinion, at least return 2...)

age := 27
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
        log.Fatal(err)
}
for rows.Next() {
        var name string
        if err := rows.Scan(&name); err != nil {
                log.Fatal(err)
        }
        fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
        log.Fatal(err)
}

The docs state here that
Scan copies the columns in the current row into the values pointed at by dest.

How does this work with a struct, lets say I have a struct

type User struct{
    Name string
    Age int
}

and I modify my query to SELECT name, age from users where age=?

How do I unpack *Rows into my struct? I did find this example, but it didn't deal with structs. I will be following Active Record pattern conventions so my structs will map to my database via snake case conversion.

答案1

得分: 4

根据源代码,似乎使用...语法在目标指针上进行复制:

func (rs *Rows) Scan(dest ...interface{}) error

所以在你的例子中,你可以这样做:

for rows.Next() {
    u := User{} // 一个空的用户
    ...
    if err := rows.Scan(&u.Name, &u.Age); err != nil {
        ...
    }
 }

只要传递了确切数量的指针,无论它们是来自结构体还是其他地方,这应该都可以工作。

英文:

Looking at the source, it seems the copy is done with ... syntax on destination pointers:

func (rs *Rows) Scan(dest ...interface{}) error

So in your example, you can do for instance:

for rows.Next() {
    u := User{} // An empty user
    ...
    if err := rows.Scan(&u.Name, &u.Age); err != nil {
        ...
    }
 }

As long as you pass the exact number of pointers, this should work, whether they are from a struct or not.

huangapple
  • 本文由 发表于 2014年1月6日 18:07:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/20947517.html
匿名

发表评论

匿名网友

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

确定