【问题标题】:Scan error: sql: Scan error on column index 11: destination not a pointer扫描错误:sql:列索引 11 上的扫描错误:目标不是指针
【发布时间】:2018-06-23 18:18:02
【问题描述】:

我了解问题所在,当我尝试扫描数据库调用中的字段时,我没有提供指针地址 - 但是在这种情况下,我不太确定如何解决它。

我有一个看起来像这样的结构:

type ItemsRequest struct {
    Sku      string `json:"sku"`
    Name     string `json:"name"`
    Barcode  string `json:"barcode,omitempty"`
    Category struct {
        ID               string        `json:"id,omitempty"`
        Name             string        `json:"name,omitempty"`
        Subcategories    []interface{} `json:"subcategories,omitempty"`
        CategoryPosition int           `json:"categoryPosition,omitempty"`
        ResourceURI      string        `json:"resource_uri,omitempty"`
    } `json:"category,omitempty"`
    CategoryPosition int               `json:"categoryPosition,omitempty"`
    LongDesc         string            `json:"longDesc,omitempty"`
    MinQty           int               `json:"minQty,omitempty"`
    MultQty          int               `json:"multQty,omitempty"`
    UnitPrice        string            `json:"unitPrice,omitempty"`
    ImageURLs        []string          `json:"imageURLs,omitempty"`
    Variants         []interface{}     `json:"variants,omitempty"`
    AdditionalPrices map[string]string `json:"additionalPrices,omitempty"`
    audtdatetime     int
}

AdditionalPrices 字段用于表示值的对象,例如:

{
    'UK': "12.34",
    'AU': "14.00"
}

因此,我相当有信心该字段的 map[string]string 类型是正确的...

我正在检索数据以从我的数据库中填充此结构,然后尝试将结果扫描到此结构的实例中。在我的查询中,我有预定义数量的列,我想用这些列填充 AdditionalPrices

因此我从这个开始:

func getItemsFromDB() []*ItemsRequest {
    rows, err := bcdataDBConnection.Query(`
        SELECT  *
        FROM    vProducts
        WHERE   max_audit_date_time > @AuditTime
    `, sql.Named("AUDITTIME", 2016101412000000))

    if err != nil {
        log.Fatal("There was an issue with the query for items: ", err)
    }

    defer rows.Close()

    var items []*ItemsRequest

    for rows.Next() {
        var item = &ItemsRequest{}
        err := rows.Scan(
            &item.Sku,
            &item.Name,
            &item.Category.ID,
            &item.Category.Name,
            &item.Category.CategoryPosition,
            &item.LongDesc,
            &item.Barcode,
            &item.UnitPrice,
            &item.MinQty,
            &item.MultQty,
            &item.CategoryPosition,
            &item.AdditionalPrices["NZBASE"],
            &item.AdditionalPrices["NZWWW"],
            &item.AdditionalPrices["MMCMFR"],
            &item.AdditionalPrices["MMBASE"],
            &item.AdditionalPrices["AUBASE"],
            &item.AdditionalPrices["MMCMAU"],
            &item.AdditionalPrices["AUDSA"],
            &item.AdditionalPrices["AUDVIC"],
            &item.AdditionalPrices["AUDWWW"],
            &item.audtdatetime,
        )
        if err != nil {
            log.Fatal("Scan error: ", err)
        }

        items = append(items, item)
    }

    return items
}

但是这似乎不是正确的语法,所以我将其更改为:

func getItemsFromDB() []*ItemsRequest {
    rows, err := bcdataDBConnection.Query(`
        SELECT  *
        FROM    vHandshakeProducts
        WHERE   max_audit_date_time > @AuditTime
    `, sql.Named("AUDITTIME", 2016101412000000))

    if err != nil {
        log.Fatal("There was an issue with the query for items: ", err)
    }

    defer rows.Close()

    var items []*ItemsRequest

    for rows.Next() {
        var item = &ItemsRequest{}
        err := rows.Scan(
            &item.Sku,
            &item.Name,
            &item.Category.ID,
            &item.Category.Name,
            &item.Category.CategoryPosition,
            &item.LongDesc,
            &item.Barcode,
            &item.UnitPrice,
            &item.MinQty,
            &item.MultQty,
            &item.CategoryPosition,
            item.AdditionalPrices["NZBASE"],
            item.AdditionalPrices["NZWWW"],
            item.AdditionalPrices["MMCMFR"],
            item.AdditionalPrices["MMBASE"],
            item.AdditionalPrices["AUBASE"],
            item.AdditionalPrices["MMCMAU"],
            item.AdditionalPrices["AUDSA"],
            item.AdditionalPrices["AUDVIC"],
            item.AdditionalPrices["AUDWWW"],
            &item.audtdatetime,
        )
        if err != nil {
            log.Fatal("Scan error: ", err)
        }

        items = append(items, item)
    }

    return items
}

我的 IDE 更喜欢哪个,但是在运行它时出现错误:

2018/01/15 15:35:06 扫描错误:sql:列索引 11 上的扫描错误:目标不是指针

所以此时,我不太确定如何从我的数据库调用中填充 AdditionalPrices 的值。

我需要做什么来使用从数据库中获取的值填充AdditionalPrices 映射? 根据我代码中的键,我已经知道要为其分配值的映射键。

【问题讨论】:

    标签: pointers dictionary go struct


    【解决方案1】:

    row.Scan 用于扫描数据库行中的字段。它不能以嵌套的方式扫描字段的值。

    所以只要说&item.AdditionalPrices就可以扫描每一行的additionalPrices字段,如下:

        err := rows.Scan(
            &item.Sku,
            &item.Name,
            &item.Category.ID,
            &item.Category.Name,
            &item.Category.CategoryPosition,
            &item.LongDesc,
            &item.Barcode,
            &item.UnitPrice,
            &item.MinQty,
            &item.MultQty,
            &item.CategoryPosition,
            &item.AdditionalPrices,
            &item.audtdatetime,
        )
    

    【讨论】:

    • 谢谢。如果它是map[string]string 类型,那么它如何获得密钥呢?
    • 使用的数据库引擎是什么?数据库字段additionalPrices 的类型是什么?
    • 数据库为sql server,列类型为decimal(9,2)
    • 我认为additionalPrices 的类型类似于 JSON。如果每个附加价格都有单独的十进制类型列,则无法使用map[string]interface{}进行扫描
    • 这很痛苦。我只需要扫描到一个临时变量,然后手动构建地图。无论如何感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2021-08-12
    • 2012-01-31
    • 2019-06-05
    • 1970-01-01
    相关资源
    最近更新 更多