-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Examples
Many use cases are covered by the tests of Go-MySQL-Driver. You might find what you are looking for there.
Assume an empty table with the following layout:
+--------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+-------+
| number | int(11) | NO | PRI | NULL | |
| squareNumber | int(11) | NO | | NULL | |
+--------------+---------+------+-----+---------+-------+
In this example we prepare two statements - one for inserting tuples (rows) and one to query.
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@/database")
if err != nil {
panic(err.Error())
}
defer db.Close()
// Prepare statement for inserting data
stmtIns, err := db.Prepare("INSERT INTO squareNum VALUES( ?, ? )") // ? = placeholder
if err != nil {
panic(err.Error())
}
defer stmtIns.Close() // Close the statement when we leave main() / the program terminates
// Prepare statement for reading data
stmtOut, err := db.Prepare("SELECT squareNumber FROM squarenum WHERE number = ?")
if err != nil {
panic(err.Error())
}
defer stmtOut.Close()
// Insert square numbers for 0-24 in the database
for i := 0; i < 25; i++ {
_, err = stmtIns.Exec(i, (i * i)) // Insert tuples (i, i^2)
if err != nil {
panic(err.Error())
}
}
var squareNum int // we "scan" the result in here
// Query the square-number of 13
err = stmtOut.QueryRow(13).Scan(&squareNum) // WHERE number = 13
if err != nil {
panic(err.Error())
}
fmt.Printf("The square number of 13 is: %d", squareNum)
// Query another number.. 1 maybe?
err = stmtOut.QueryRow(1).Scan(&squareNum) // WHERE number = 1
if err != nil {
panic(err.Error())
}
fmt.Printf("The square number of 1 is: %d", squareNum)
}
Note: This might cause problems in Go 1.0 since the conversion from integer types to []byte is missing. The Issue is fixed in Go 1.1+
Maybe you already encountered this error:
sql: Scan error on column index 1: unsupported driver -> Scan pair: <nil> -> *string
Normally you would use sql.NullString
in such a case. But sometimes you don't care if the value is NULL
, you just want to treat it as an empty string.
You can do this with a small workaround, which takes advantage of the fact, that a nil-[]byte gets converted to an empty string.
Instead of using *string
as a rows.Scan(...)
destination, you simple use *[]byte
(or *sql.RawBytes
), which can take the nil
value:
[...]
var col1, col2 []byte
for rows.Next() {
// Scan the value to []byte
err = rows.Scan(&col1, &col2)
// Use the string value
fmt.Println(string(col1), string(col2))
}
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// Open database connection
db, err := sql.Open("mysql", "user:password@@tcp(127.0.0.1:3306)/dbname?charset=utf8")
if err != nil {
panic(err.Error())
}
defer db.Close()
// Execute the query
rows, err := db.Query("SELECT * FROM table")
if err != nil {
panic(err.Error())
}
// Get column names
columns, err := rows.Columns()
if err != nil {
panic(err.Error())
}
// Make a slice for the values
values := make([]sql.RawBytes, len(columns))
// rows.Scan wants '[]interface{}' as an argument, so we must copy the
// references into such a slice
// See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details
scanArgs := make([]interface{}, len(values))
for i := range values {
scanArgs[i] = &values[i]
}
// Fetch rows
for rows.Next() {
// get RawBytes from data
err = rows.Scan(scanArgs...)
if err != nil {
panic(err.Error())
}
// Now do something with the data.
// Here we just print each column as a string.
var value string
for i, col := range values {
// Here we can check if the value is nil (NULL value)
if col == nil {
value = "NULL"
} else {
value = string(col)
}
fmt.Println(columns[i], ": ", value)
}
fmt.Println("-----------------------------------")
}
}
Feel free to contribute your own examples!