2014-10-28 47 views
5

我有這樣的Go代碼:如何.Scan()將MySQL TIMESTAMP值轉換爲time.Time變量?

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 | [email protected] | NULL |   0 | 2014-10-28 15:37:44 | N  | 
+----+------------+-----------------------+--------+--------------+---------------------+--------+ 
1 row in set (0.00 sec) 
.Scan()

後,fmt.Println(usr)打印

{1 alakhazamm [email protected] 0 0 {0 0 <nil>} } 

的最後兩個字段的結構是錯誤的,但我不知道爲什麼。 我試過在結構定義中使用date_registered string,但在.Scan()之後我得到一個空字符串。 我也讀過驅動程序的文檔,?parseTime=true解析MySQL DATE和DATETIME值到time.Time,但他們沒有提到我目前正在使用的TIMESTAMP。

我錯過了一些重要的東西,還是圖書館的缺陷/缺失功能?

回答

3

我找到了錯誤的原因。

由於rating是在數據庫NULL,掃描儀,得到誤差

SQL:上的掃描錯誤列索引3:轉換字符串「無」到 UINT8:strconv.ParseUint:解析「無」 :無效語法

我已更新數據庫行,現在usr.date_registeredusr.online保持正確的值。

我想我將不得不使MySQL字段不爲NULL,並使用-1來表示一個非初始化值。

+2

可以在數據庫/ SQL包使用NullInt64型掃描可能爲null的整數。 http://golang.org/pkg/database/sql/#NullInt64 – 2014-10-29 14:05:31

+0

它的工作,謝謝! – 2014-10-29 17:41:07

+0

我們的代碼中有很多時間戳可以爲空,所以我們最終添加了一個簡單的NullTime類,該類與其他數據庫空類相同。 – 2014-10-30 23:04:48

1

我知道這是一個老問題,但是我錯過了這個參數在我打開電話:

parseTime=true 

See here