【问题标题】:How to use `where in` with slice of ints如何将`where in`与整数切片一起使用
【发布时间】:2016-08-11 04:49:06
【问题描述】:

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)

解决方案:

代码实际上根本没有错误。我是不是很傻 - 我的实际代码中有一个额外的参数,而不是我应该有的。我只是没有正确地将其翻译为堆栈溢出。我的错。

【问题讨论】:

    标签: mysql go slice go-gorm


    【解决方案1】:

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

    db.Exec 在 Go 中的实现是先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)
    

    更新:

    原来Gormdb.Exec 方法的实现没有使用DBMS 的准备功能,而是在驱动程序中连接字符串。

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

    您是否正在导入 Gorm,就像它在 http://jinzhu.me/gorm/ 中显示的那样?

    【讨论】:

    • 这正是我已经做过的解决方法(非常感谢),但是我认为我可能做错了什么,因为该库非常清楚地表明它允许您执行 NOT IN (?)
    • 另外,请参阅他们的测试:github.com/jinzhu/gorm/blob/…github.com/jinzhu/gorm/blob/… 作为示例用法
    • @Gravy 啊哈,我明白了。您确定正确导入库吗?在我看来,您使用的是 Go 的官方 sql 库,而不是 gorm 的,它们具有相同的方法但不同的实现。
    • gorm的源代码(github.com/jinzhu/gorm/blob/…)中,他们对db.Exec方法有不同的实现,它没有使用准备功能来预分析数据库端的查询,但它连接代码中的参数。
    • 问题已解决。我是不是很傻 - 我的实际代码中有一个额外的参数,而不是我应该有的。只是没有正确地将其翻译为堆栈溢出。我的错。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-10-20
    • 2016-06-10
    • 2019-04-02
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    相关资源
    最近更新 更多