sql:转换参数$ 1类型:不受支持的类型[] int,in中的一个切片

时间:2018-12-31 03:00:34

标签: postgresql go

拥有这个:

somevars := []int{1, 2, 3, 4}
rows, err = db.Query("SELECT c1,c2 FROM table"+tid+" WHERE c1 IN($1,$2,$3,$4);", somevars)

知道了:

sql:转换参数$ 1的类型:不受支持的类型[] int,是int的一部分

有什么方法可以使参数片与lib / pq一起使用?

3 个答案:

答案 0 :(得分:4)

pq.Array是答案:

somevars := []int{1, 2, 3, 4}
rows, err = db.Query("SELECT c1,c2 FROM table"+tid+" WHERE c1 = any($1);", pq.Array(somevars))

答案 1 :(得分:4)

另一种解决方案是

somevars := []interface{}{1, 2, 3, 4}
rows, err = db.Query(
    "SELECT c1,c2 FROM table"+tid+" WHERE c1 IN($1,$2,$3,$4);",
    somevars...)

此处...将切片扩展为多个参数,类似于python *args。已记录在in the language spec中。

db.Query API支持这个所谓的可变参数。

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

此处interface{}被称为空接口,它可以保存任何类型的值。请参见Go tour example here。所以可以像这样使用它

db.Query(stmt, var1, var2)

其中var1 var2可以是不同类型。

根据您的情况,您还可以显式传递slice元素

db.Query(stmt,
         somevars[0], somevars[1], somevars[2], somevars[3])

但是它很冗长,并且当切片长度改变时需要额外的工作。

请注意,如果我们使用interface而不是somevars切片intvars := []int {1, 2, 3, 4}并在intvars中展开db.Query(),则编译器将对{{1 }}

  

不能将[] int文字(类型[] int)用作分配中的[] interface {}类型

类型转换intvars...也不起作用。 language spec FAQ中对此进行了说明。还有一个dedicated wiki page for it

  

语言规范不允许这样做,因为这两种类型在内存中的表示方式不同。

golang intvars.([]interface{})的直观图片是一个具有两个字段的对象,一个字段存储类型,另一个字段存储指针。

答案 2 :(得分:0)

更通用的解决方案是使用sqlx库:https://jmoiron.github.io/sqlx/#inQueries

// assume db is an initialized database handle
somevars := []int{1,2,3,4}
query, args, err := sqlx.In("SELECT * FROM table WHERE id IN (?)", somevars)
if err != nil {
  return err
}
query = db.Rebind(query)
result := db.Select(query, args...)

此解决方案将与多个数据库驱动程序和未知长度的片一起使用。