【问题标题】:Unable to use type string as sql.NullString无法将类型字符串用作 sql.NullString
【发布时间】:2020-03-21 19:24:19
【问题描述】:

我正在创建一个gorm 模型

// Day is a corresponding day entry
type Day struct {
    gorm.Model
    Dateday   string         `json:"dateday" gorm:"type:date;NOT NULL"`
    Nameday   string         `json:"nameday" gorm:"type:varchar(100);NOT NULL"`
    Something sql.NullString `json:"salad"`
    Holyday   bool           `json:"holyday"`
}

我将sql.NullString 用于Something 字段,因为它可能为NULL。

所以当我尝试执行一个典型的gorm 示例来验证我的设置是否有效时:

    db.Create(&Day{
        Nameday:     "Monday",
        Dateday:     "23-10-2019",
        Something:   "a string goes here",
        Holyday:      false,
    })

我明白了:

不能在字段值中使用“一个字符串”,(类型字符串)作为类型 sql.NullString

如果Something 字段可能为NULL,我应该使用什么类型?

【问题讨论】:

  • sql.NullStringstruct 类型,不能转换为 string 类型。您需要初始化 sql.NullString 的值并将其设置为该字段。一种方法是Something: sql.NullString{String: "a string goes here", Valid: true}golang.org/pkg/database/sql/#NullString
  • 感谢您抽出宝贵时间回复;我建议您将其发布为正常答案,以便我接受/支持它
  • 如果我没记错的话,您可以使用*string 类型作为NULL-able 列

标签: go orm go-gorm


【解决方案1】:

sql.NullString 类型实际上不是字符串类型,而是结构类型。定义为:

type NullString struct {
    String string
    Valid  bool // Valid is true if String is not NULL
}

因此你需要这样初始化它:

db.Create(&Day{
    Nameday:     "Monday",
    Dateday:     "23-10-2019",
    Something:   sql.NullString{String: "a string goes here", Valid: true},
    Holyday:     false,
})

作为替代方案,如果您想要在初始化可空字符串时继续使用更简单的语法,您可以声明自己的可空字符串类型,让它实现sql.Scannerdriver.Valuer 接口,并利用空字节来表示NULL 值。

type MyString string

const MyStringNull MyString = "\x00"

// implements driver.Valuer, will be invoked automatically when written to the db
func (s MyString) Value() (driver.Value, error) {
    if s == MyStringNull {
        return nil, nil
    }
    return []byte(s), nil
}

// implements sql.Scanner, will be invoked automatically when read from the db
func (s *String) Scan(src interface{}) error {
    switch v := src.(type) {
    case string:
        *s = String(v)
    case []byte:
        *s = String(v)
    case nil:
        *s = StringNull
    }
    return nil
}

这样,如果您将字段 Something 声明为 MyString 类型,您可以按照您的初衷对其进行初始化。

db.Create(&Day{
    Nameday:     "Monday",
    Dateday:     "23-10-2019",
    // here the string expression is an *untyped* string constant
    // that will be implicitly converted to MyString because
    // both `string` and `MyString` have the same *underlying* type.
    Something:   "a string goes here",
    Holyday:     false,
})

请记住,这仅适用于无类型常量,一旦您拥有string 类型的常量或变量,为了能够将其分配给MyString,您需要使用显式转换。

var s string
var ms MyString

s = "a string goes here"
ms = s // won't compile because s is not an untyped constant
ms = MyString(s) // you have to explicitly convert

【讨论】:

  • Something: sql.NullString{String: "a string goes here", Valid: true},帮我解决了,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
相关资源
最近更新 更多