sql.DB.Exec 时对 SQL 中的自定义类型感到困惑

具有此表结构:


CREATE TABLE `tableName` (

    `Id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

    `Status` enum('pending','rejected','sent','invalid') NOT NULL,

    `Body` varchar(255) NULL

) ENGINE='MyISAM' COLLATE 'utf8_general_ci';

我有这个(不完整的)代码工作正常:


type StatusEnum string


const (

    STATUS_PENDING  StatusEnum = "pending"

    STATUS_REJECTED StatusEnum = "rejected"

    STATUS_SENT     StatusEnum = "sent"

    STATUS_INVALID  StatusEnum = "invalid"

)


func (s *StatusEnum) Scan(src interface{}) error {

    if src == nil {

        return errors.New("This field cannot be NULL")

    }


    if stringStatus, ok := src.([]byte); ok {

        *s = StatusEnum(string(stringStatus[:]))


        return nil

    }


    return errors.New("Cannot convert enum to string")

}


func (s *StatusEnum) Value() (driver.Value, error) {

    return []byte(*s), nil

}


type EmailQueue struct {

    Id        uint64

    Status    StatusEnum

    Body      sql.NullString

}


func Save (db *sql.DB) error {

    _, err = db.Exec(

        "UPDATE `tableName` SET `Status` = ?, `Body` = ? WHERE `id` = ?",

        &eqi.Status,

        eqi.Body,

        eqi.Id,

    )


    return err

}

所以我的问题是:为什么我需要在 上使用指针引用 ( &eqi.Status) db.Exec?


这两个sql.NullString和我的自定义StatusEnum都没有实现github.com/go-sql-driver/mysql,为什么不同?


如果我不使用指针引用 ( eqi.Status),则会出现此错误(抛出database/sql/convert.go):


sql: converting Exec argument #0's type: unsupported type emailqueue.StatusEnum, a string

我试图实现一些我没有运气发现的其他接口。


我还有其他用sql.Scanner和sql.driver.Valuer接口实现的自定义类型,但问题是一样的。


我在猜测struct和类型继承差异,但我无法得到任何提示...... :(


请帮助了解发生了什么。谢谢!!!:)


茅侃侃
浏览 272回答 1
1回答

吃鸡游戏

您为您的类型实现Valuer 接口StatusEnum作为对*StatusEnum. 因此,当您将一个作为参数传递给 Exec 时,它仅作为指针才有意义,因为它仅作为指向StatusEnumimplementation的指针才有意义Value(),需要内联尊重。您没有EmailList类型的定义,因此我可以建议对您的给定Valuer接口进行更改。func (s StatusEnum) Value() (driver.Value, error) {    return []byte(s), nil}这是标准库实现自定义可为空类型。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go