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

Gab*_*lla 3 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)
Run Code Online (Sandbox Code Playgroud)

收到:

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

有什么办法可以使一部分参数与lib / pq一起使用?

Gab*_*lla 6

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))
Run Code Online (Sandbox Code Playgroud)

  • 您正在用“=”替换“IN”。在这种情况下他们会做同样的事情吗?这是在哪里记录的? (3认同)

nos*_*nos 6

替代解决方案是

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

在这里,...将切片扩展为多个参数,类似于python *args。它的记录中的语言规范

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

func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
Run Code Online (Sandbox Code Playgroud)

这里interface{}称为空接口,它可以保存任何类型的值。请参阅此处“游览”示例。这样就可以像

db.Query(stmt, var1, var2)

哪里var1 var2可能是不同类型的。

您也可以显式传递slice元素

db.Query(stmt,
         somevars[0], somevars[1], somevars[2], somevars[3])
Run Code Online (Sandbox Code Playgroud)

但这很冗长,并且在切片长度发生变化时需要额外的工作。

请注意,如果不是使用interfaceslice somevars而是使用in进行intvars := []int {1, 2, 3, 4}扩展,则编译器会抱怨intvarsdb.Query()intvars...

不能在分配中使用[] int文字(类型[] int)作为类型[] interface {}

类型转换intvars.([]interface{})也不起作用。语言规范FAQ中对此进行了记录。还有一个专用的Wiki页面

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

golang的直观图片interface是一个具有两个字段的对象,一个字段存储类型,另一个字段存储指针。


小智 6

更通用的解决方案是使用该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...)
Run Code Online (Sandbox Code Playgroud)

该解决方案将适用于多个数据库驱动程序和未知长度的切片。