Golang连接数组接口

huangapple go评论164阅读模式
英文:

Golang Join array interface

问题

我尝试创建批量插入。我使用gorm github.com/jinzhu/gorm

import (
    "fmt"
    dB "github.com/edwinlab/api/repositories"
)

func Update() error {
    tx := dB.GetWriteDB().Begin()
    sqlStr := "INSERT INTO city(code, name) VALUES (?, ?),(?, ?)"
    vals := []interface{}{}

    vals = append(vals, "XX1", "Jakarta")
    vals = append(vals, "XX2", "Bandung")

    tx.Exec(sqlStr, vals)

    tx.Commit()

    return nil
}

但是我遇到了一个错误:

Error 1136: Column count doesn't match value count at row 1,因为我返回了错误的查询

INSERT INTO city(code, name) VALUES ('XX1','Jakarta','XX2','Bandung', %!v(MISSING)),(%!v(MISSING), %!v(MISSING))

如果我使用手动查询,它可以工作:

tx.Exec(sqlStr, "XX1", "Jakarta", "XX2", "Bandung")

它将生成:

INSERT INTO city(code, name) VALUES ('XX1', 'Jakarta'),('XX2', 'Bandung')

问题是如何使数组接口生成像"XX1", "Jakarta", ...这样的字符串。

谢谢帮助。

英文:

I try to create bulk insert. I use gorm github.com/jinzhu/gorm

import (
    "fmt"
    dB "github.com/edwinlab/api/repositories"
)

func Update() error {
    tx := dB.GetWriteDB().Begin()
    sqlStr := "INSERT INTO city(code, name) VALUES (?, ?),(?, ?)"
    vals := []interface{}{}

    vals = append(vals, "XX1", "Jakarta")
    vals = append(vals, "XX2", "Bandung")

    tx.Exec(sqlStr, vals)

    tx.Commit()

    return nil
}

But I got an error:

> Error 1136: Column count doesn't match value count at row 1 becuse i return wrong query
>
> INSERT INTO city(code, name) VALUES ('XX1','Jakarta','XX2','Bandung', %!v(MISSING)),(%!v(MISSING), %!v(MISSING))

If I use manual query it works:

tx.Exec(sqlStr, "XX1", "Jakarta", "XX2", "Bandung")

It will generate:

INSERT INTO city(code, name) VALUES ('XX1', 'Jakarta'),('XX2', 'Bandung')

The problem is how to make array interface to generate string like "XX1", "Jakarta", ...

Thanks for help.

答案1

得分: 5

如果你想将切片的元素作为可变参数传递给一个函数,你需要使用...告诉编译器你想逐个传递所有元素,而不是将切片作为单个参数传递。所以你可以这样做:

tx.Exec(sqlStr, vals...)

这在规范中有详细说明:将参数传递给...参数

Tx.Exec()的签名是:

func (tx *Tx) Exec(query string, args ...interface{}) (Result, error)

所以你需要传递vals...。同时不要忘记检查返回的错误,例如:

res, err := tx.Exec(sqlStr, vals...)
if err != nil {
    // 处理错误
}
英文:

If you want to pass elements of a slice to a function with variadic parameter, you have to use ... to tell the compiler you want to pass all elements individually and not pass the slice value as a single argument, so simply do:

tx.Exec(sqlStr, vals...)

This is detailed in the spec: Passing arguments to ... parameters.

Tx.Exec() has the signature of:

func (tx *Tx) Exec(query string, args ...interface{}) (Result, error)

So you have to pass vals.... Also don't forget to check returned error, e.g.:

res, err := tx.Exec(sqlStr, vals...)
if err != nil {
    // handle error
}

huangapple
  • 本文由 发表于 2016年3月21日 15:12:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/36125024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定