我有这个Go代码:
package main
import (
"fmt"
"database/sql"
_"github.com/go-sql-driver/mysql"
"time"
)
type User struct {
id uint32
name string
email string
rating uint8
subscription uint8
date_registered time.Time
online string
}
// main entry point
func main() {
// setup db connection
db, err := sql.Open("mysql", "user:@tcp(127.0.0.1:3306)/c9?parseTime=true")
if err != nil {
fmt.Println(err)
}
defer db.Close()
// query
rows, err := db.Query("SELECT * FROM users WHERE id = ?", 1)
if err != nil {
fmt.Println(err)
}
defer rows.Close()
usr := User{}
for rows.Next() {
err := rows.Scan(&usr.id, &usr.name, &usr.email, &usr.rating, &usr.subscription, &usr.date_registered, &usr.online)
if err != nil {
fmt.Println(err)
}
}
fmt.Println(usr)
err = rows.Err()
if err != nil {
fmt.Println(err)
}
}
这是我从MySQL控制台获得的:
mysql> describe users;
+-----------------+---------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+-------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
| email | varchar(50) | NO | | NULL | |
| rating | tinyint(3) unsigned | YES | | NULL | |
| subscription | tinyint(3) unsigned | NO | | 0 | |
| date_registered | timestamp | NO | | CURRENT_TIMESTAMP | |
| online | char(1) | NO | | N | |
+-----------------+---------------------+------+-----+-------------------+----------------+
7 rows in set (0.00 sec)
mysql> SELECT * FROM users;
+----+------------+-----------------------+--------+--------------+---------------------+--------+
| id | name | email | rating | subscription | date_registered | online |
+----+------------+-----------------------+--------+--------------+---------------------+--------+
| 1 | alakhazamm | abcdefghhhh@gmail.com | NULL | 0 | 2014-10-28 15:37:44 | N |
+----+------------+-----------------------+--------+--------------+---------------------+--------+
1 row in set (0.00 sec)
.Scan()
之后,fmt.Println(usr)
打印
{1 alakhazamm abcdefghhhh@gmail.com 0 0 {0 0 <nil>} }
结构的最后两个字段是错误的,但我不知道为什么。
我尝试在结构定义中使用date_registered string
,但在.Scan()
之后我得到一个空字符串。
我还在驱动程序的文档中读到?parseTime=true
将MySQL DATE和DATETIME值解析为time.Time,但他们没有提到我正在使用的TIMESTAMP。
我是否遗漏了重要的内容,或者它是图书馆的错误/缺失功能?
答案 0 :(得分:6)
答案 1 :(得分:3)
我找到了错误的原因。
由于数据库中rating
为NULL,因此扫描程序提供了错误
sql:列索引3上的扫描错误:转换字符串&#34; nil&#34;到了 uint8:strconv.ParseUint:解析&#34; nil&#34;:语法无效
我已更新了数据库行,现在usr.date_registered
和usr.online
保留了正确的值。
我想我必须将MySQL字段设为NOT NULL,并使用-1表示未初始化的值。
答案 2 :(得分:2)
除了@incognick的回答外,您还可以执行以下操作(添加parseTime = true):
db, err := sqlx.Connect("mysql", "myuser:mypass@tcp(127.0.0.1:3306)/mydb?parseTime=true")
如果timestamp / datetime可能为null,那么在这种情况下,应将扫描参数用作sql.NullTime而不是time.Time。
使用sql.NullTime将为您提供选项,以检查扫描时间是否为空或不使用var.Valid
标志。如果var.Time
有效且不为空,则可以使用时间。