有些挠头。我有以下结构:
type Room struct {
ID int
Name string
RoomType int
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt time.Time
GroupId int
BlockId int
ProjectId int
RoomLength float64
RoomWidth float64
CeilingHeight float64
CeilingColorHex string
WallColorHex string
FloorColorHex string
CeilingColorRgb string
WallColorRgb string
FloorColorRgb string
}
使用以下命令在rest api中读取该信息:
database := db.New()
stmt, err := database.Prepare("SELECT * FROM room WHERE block_id = ?")
if err != nil {
panic(err)
}
defer stmt.Close()
rows, err := stmt.Query(c.Param("id"))
if err != nil {
panic(err)
}
defer rows.Close()
var rooms []common.Room
for rows.Next() {
var r common.Room
err := rows.Scan(&r.ID, &r.Name, &r.RoomType, &r.CreatedAt, &r.UpdatedAt, &r.DeletedAt,
&r.GroupId, &r.BlockId, &r.ProjectId, &r.RoomLength, &r.RoomWidth, &r.CeilingHeight,
&r.CeilingColorHex, &r.WallColorHex, &r.FloorColorHex, &r.CeilingColorRgb, &r.WallColorRgb,
&r.FloorColorRgb)
if err = rows.Err(); err != nil {
panic(err)
}
fmt.Printf("Found: %v", r)
rooms = append(rooms, r)
}
但是,生成的有效载荷是:
{3 Loki #1 3 2018-09-25 08:42:38 +0000 UTC 2018-09-25 14:52:39 +0000 UTC 0001-01-01 00:00:00 +0000 UTC 0 0 0 0 0 0 }
我具体是在长度/宽度之后(上面是0)。但是在db中:
mysql> select * from room where id = 3 \G
*************************** 1. row ***************************
id: 3
name: Loki #1
room_type: 3
created_at: 2018-09-25 08:42:38
updated_at: 2018-09-25 14:52:39
deleted_at: NULL
group_id: 0
block_id: 1
project_id: 0
room_length: 10
room_width: 7
ceiling_height: 4
ceiling_color_hex: #c0c0c0
wall_color_hex: #a9a9a9
floor_color_hex: #708090
ceiling_color_rgb: 192,192,192
wall_color_rgb: 169,169,169
floor_color_rgb: 112,128,144
1 row in set (0.00 sec)
我认为这可能与不同的类型有关,但是在db中更改了它们,然后在代码中进行了更改,则没有任何变化。谁能解释为什么.Scan
没有选择某些值?
谢谢!
答案 0 :(得分:2)
首先,检查来自rows.Scan()的错误。您只检查来自rows.Err()的错误,它是另一种错误,与扫描无关。
err := rows.Scan(&r.ID, &r.Name, &r.RoomType, &r.CreatedAt, &r.UpdatedAt, &r.DeletedAt,
&r.GroupId, &r.BlockId, &r.ProjectId, &r.RoomLength, &r.RoomWidth, &r.CeilingHeight,
&r.CeilingColorHex, &r.WallColorHex, &r.FloorColorHex, &r.CeilingColorRgb, &r.WallColorRgb,
&r.FloorColorRgb)
if err != nil {
panic(err) // Error related to the scan
}
if err = rows.Err(); err != nil {
panic(err) // Error related to the iteration of rows
}
当deleted_at
中的值返回为NULL
时,Scan将返回诸如unsupported Scan, storing driver.Value type <nil> into type *time.Time
之类的错误,而您的其他结构体将得到零值
这意味着您的房间结构必须更改以使用指向时间的指针。
CreatedAt *time.Time
UpdatedAt *time.Time
DeletedAt *time.Time
但是,您可能需要在sql.Open()中添加parameter parseTime sql.Open("mysql", "user:password@/dbname?parseTime=true)
才能正确解析mysql的时间。
然后,您应该在设置了有效的* time.Time时收到一个有效的* time.Time,而在它为NULL时会收到一个nil。