Golang gorm如何使用`where in` with slice of int

时间:2016-04-19 07:13:54

标签: mysql go slice

http://jinzhu.me/gorm/advanced.html#sql-builder开始,我应该能够使用WHERE IN使用单个(?)更新多行,并将切片传递给单?而不是WHERE IN (?,?,?,?)

来自jinzhu.me的示例如下:db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})。这是一个gorm的测试示例,显示它正常工作。 https://github.com/jinzhu/gorm/blob/021d7b33143de37b743d1cf660974e9c8d3f80ea/main_test.go#L449

然而,这对我不起作用:

var availableIds []int
for _, p := range v.Products {
    availableIds = append(availableIds, p.Id)
}

log.Println(availableIds)

db.Exec("UPDATE product_supplier SET deleted_at=? WHERE supplier_id = ? AND sku NOT IN (?)", time.Now(), 3, availableIds)

输出:

2016/04/19 07:48:44 [336 338 337 306 329 94 79 43 57 313 108 122 126 127 124 125 123 221 93 330 335 333 312]

(sql: expected 2 arguments, got 25)

当我尝试硬编码时,我遇到同样的问题:

db.Exec("UPDATE product_supplier SET deleted_at=? WHERE supplier_id = ? AND sku NOT IN (?)", time.Now(), 3, []int{313, 108})

输出:

(sql: expected 2 arguments, got 4)

解决方案:

代码实际上并没有被窃听。我是愚蠢的 - 我的实际代码中有一个额外的参数比我应该有的。我只是没有正确翻译堆栈溢出。我的坏。

1 个答案:

答案 0 :(得分:0)

prepare功能的自然性阻止您将切片作为参数传递。

Go中db.Exec的实现是首先prepare查询(包括变量占位符),然后发送参数。

如果您想知道为什么prepare阻止您传递切片,请阅读this answer

作为一种解决方法,需要在程序中连接与切片大小相同数量的占位符,这应该生成如下查询:

... WHERE supplier_id = ? AND sku NOT IN (?, ?, ?, ?)

示例代码:

Ids := []int{1, 2, 3}
query := "... WHERE supplier_id = ? AND sku NOT IN (" + genVar(len(Ids)) + ")"
db.Exec(query, 3, Ids)

<强>更新

转向Gorm的{​​{1}}方法的实现不是使用DBMS的准备功能,而是在驱动程序中连接字符串。

我现在的诊断是依赖项可能有问题。

您是否导入了http://jinzhu.me/gorm/中显示的db.Exec