![](/img/trans.png)
[英]sql: expected 3 destination arguments in Scan, not 1 in Golang
[英]Scan SQL NULL values in golang
使用標准數據庫/sql Row.Scan()
我Row.Scan()
空值問題。 在不考慮連續可能出現的空值的情況下,我可能會收到類似<nil> -> *string
掃描錯誤。 這在使用 LEFT JOIN 查詢或缺少 NO NULL 列約束的弱定義表時很常見。
有sql.NullXXX
類型(例如 sql.NullInt64)可用於掃描一行中可能的空值,然后檢查該值是否為.Valid
。 但是,這些類型沒有實現 JSON 編組,需要更多的邏輯和編碼。
為了解決這個問題,在 SQL 查詢中使用COALESCE()
列值是更好的方法還是在 golang 代碼中做一些額外的編碼?
您可以為 sql 包提供的類型使用別名,例如(NullInt64、NullString 等...)。 使用它有兩個優點,一是可以掃描空值並進入 golang 結構,二是可以在 JSON 中編組該結構。
請看示例代碼:
// NullInt64 is an alias for sql.NullInt64 data type
type NullInt64 sql.NullInt64
// Scan implements the Scanner interface for NullInt64
func (ni *NullInt64) Scan(value interface{}) error {
var i sql.NullInt64
if err := i.Scan(value); err != nil {
return err
}
// if nil the make Valid false
if reflect.TypeOf(value) == nil {
*ni = NullInt64{i.Int64, false}
} else {
*ni = NullInt64{i.Int64, true}
}
return nil
}
// MarshalJSON for NullInt64
func (ni *NullInt64) MarshalJSON() ([]byte, error) {
if !ni.Valid {
return []byte("null"), nil
}
return json.Marshal(ni.Int64)
}
請看一下這篇文章,它對在 golang 中處理空值以及如何在 JSON 中使用它非常有幫助。
作為一個選項,您可以實現與JSON Marshaler接口匹配的自定義數據類型。 之后,您將能夠使用常規標簽編組您的結構。
檢查示例:
type UserTitleType sql.NullString
func (s UserTitleType) MarshalJSON() ([]byte, error) {
if s.Valid {
return json.Marshal(s.String)
}
return jsonNull, nil
}
type User struct {
Id int64 `json:"id"`
Title UserTitleType `json:"title"`
}
// Scan implements the Scanner interface.
func (n *NullInt64) Scan(value interface{}) error {
var ok bool
if value == nil {
n.Int64, n.Valid = 0, false
return nil
}
n.Valid = true
n.Int64, ok = value.(int64)
if !ok {
return errors.New("convert error")
}
return nil
}
// Value implements the driver Valuer interface.
func (n NullInt64) Value() (driver.Value, error) {
if !n.Valid {
return nil, nil
}
return n.Int64, nil
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.