Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use rows.Scan of Go's database/sql

Tags:

go

I use database/sql and define a struct mapping to DB table columns(tag field):

// Users ...
type Users struct {
    ID            int64  `field:"id"`                      
    Username      string `field:"username"`           
    Password      string `field:"password"`           
    Tel           string `field:"tel"`                   
}

then I query:

        rows, err := db.Query(sql)  // select * from users
        if err != nil {
            fmt.Println(err)
        }
        defer rows.Close()
        for rows.Next() {
            user := new(Users)

            // works but I don't think it is good code for too many columns
            err = rows.Scan(&user.ID, &user.Username, &user.Password, &user.Tel)

            // TODO: How to scan in a simple way 


            if err != nil {
                fmt.Println(err)
            }
            fmt.Println("user: ", user)
            list = append(list, *user)
        }
        if err := rows.Err(); err != nil {
            fmt.Println(err)
        }

As you can see for rows.Scan() , I have to write all columns , and I don't think it's a good way for 20 or more columns .

How to scan in a clear way.

like image 986
Rife Avatar asked Jun 10 '19 11:06

Rife


People also ask

How do you query a row in SQL?

To select rows using selection symbols for character or graphic data, use the LIKE keyword in a WHERE clause, and the underscore and percent sign as selection symbols. You can create multiple row conditions, and use the AND, OR, or IN keywords to connect the conditions.

How do you query in go?

You can query for multiple rows using Query or QueryContext , which return a Rows representing the query results. Your code iterates over the returned rows using Rows. Next . Each iteration calls Scan to copy column values into variables.

Which method is used to read the rows from a table in a database?

An SQL SELECT statement retrieves records from a database table according to clauses (for example, FROM and WHERE ) that specify criteria. The syntax is: SELECT column1, column2 FROM table1, table2 WHERE column2='value';


2 Answers

You may consider using jmoiron's sqlx package. It has support for assigning to a struct.

Excerpt from the readme:

type Place struct {
    Country string
    City    sql.NullString
    TelCode int
}
 places := []Place{}
 err = db.Select(&places, "SELECT * FROM place ORDER BY telcode ASC")
 if err != nil {
     fmt.Println(err)
      return
 }
like image 123
alexfwulf Avatar answered Sep 18 '22 16:09

alexfwulf


It's a good practice for using reflect:

    for rows.Next() {
        user := Users{}

        s := reflect.ValueOf(&user).Elem()
        numCols := s.NumField()
        columns := make([]interface{}, numCols)
        for i := 0; i < numCols; i++ {
            field := s.Field(i)
            columns[i] = field.Addr().Interface()
        }

        err := rows.Scan(columns...)
        if err != nil {
            log.Fatal(err)
        }
        log.Println(user)
    }
like image 35
Rife Avatar answered Sep 21 '22 16:09

Rife