如何在Go中构建类型接口的varidics?

时间:2014-07-22 03:10:46

标签: mysql sql go

我正在动态构建mysql查询(由于mysql IN子句),所以我需要传递sql.Query函数所需的参数列表。知道如何做到这一点?我真的不明白可变参数的类型是如何工作的,或者我怎么能够生成'它。如果我传递一个切片,那么sql会抱怨只有一个参数而不是len(in clause params),因此我只能假设该函数将切片视为参数而不是参数的列表(可变参数)。

我的查询/代码

var carsa []string
q := `SELECT field1,field2 FROM cooltable WHERE nicecars IN(?` + strings.Repeat(",?", len(ha.cars)-1) + ")"
hs := strings.Join(carsa, "','")
    hs = "'" + hs + "'"

    rows, err := cx.Query(q, country, hs)

sql Query

func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {

编辑:我尝试运行的实际代码失败,错误为sql: converting Exec argument #0's type: unsupported type []interface {}, a slice

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

func main() {

    argsS := []string{"apple", "greph", "3rd"}

    db, err := sql.Open("mysql", dbUser+":"+dbPass+"@tcp("+dbHost+":3306)/"+dbName)
    if err != nil {
        return
    }
    query := `SELECT id,label FROM fruits WHERE country=? AND stack IN(?` + strings.Repeat(",?", len(args)-1) + ")"

    args := make([]interface{}, len(ha))
    args["country"] = interface{}("France")

    for i, v := range query {
        args[i] = interface{}(v)
    }

    rows, err := db.Query(q, args...)
    if err != nil {
        return
    }
    var id, label string

    for rows.Next() {
        if err = rows.Scan(&id, label); err != nil {
            fmt.Printf("%v", err)
        }
    }
}

1 个答案:

答案 0 :(得分:5)

使用给定的函数,您可以使用变量参数列表调用它:

var query string
var args []interface{}
// initialise variables
cx.Query(query, args...)

这相当于调用Queryargs切片中的每个元素都作为单独的参数as described in the language specification传递。另请注意,切片的类型需要与可变参数函数定义匹配(因此在本例中为interface{}的切片。

另请注意,切片需要表示整个可变参数列表。因此,例如,调用cx.Query(q, country, hs...)会出错。在这种情况下,您需要构建一个包含您想要传递的所有参数的切片。


在问题的更新之后,要将固定参数与变量参数结合起来,您希望代码看起来像这样:

stacks := []string{"apple", "greph", "3rd"}

query := `SELECT id,label FROM fruits WHERE country=? AND stack IN(?` + strings.Repeat(",?", len(stacks)-1) + ")"

args := make([]interface{}, len(stacks)+1)
args[0] = "France"
for i := range stacks {
    args[i+1] = stacks[i]
}

rows, err := cx.Query(query, args...)