2016-04-19 83 views
0

http://jinzhu.me/gorm/advanced.html#sql-builder,我應該能夠使用WHERE IN更新多行,單個(?)並將片段傳遞給單個?而不是WHERE IN (?,?,?,?)Golang gorm如何使用'in 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) 

解決方案:

的代碼實際上不是所有的竊聽。我是愚蠢的 - 我在我的實際代碼中有一個額外的參數比我應該有。我只是沒有正確翻譯它的​​堆棧溢出。我的錯。

回答

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) 

UPDATE:

原來Gorm的實施db.Exec方法不使用DBMS的準備功能,而是在驅動程序中連接字符串。

我現在的診斷是依賴關係可能有問題。

你在導入Gorm就像它在http://jinzhu.me/gorm/顯示的那樣?

+0

這正是我已經做的解決方法(非常感謝),但是我認爲我可能做錯了一些事情,因爲庫很清楚地顯示它允許你執行'NOT IN(?)'。 – Gravy

+0

另請參閱他們的測試:https://github.com/jinzhu/gorm/blob/021d7b33143de37b743d1cf660974e9c8d3f80ea/main_test.go#L481和https://github.com/jinzhu/gorm/blob/021d7b33143de37b743d1cf660974e9c8d3f80ea/main_test.go#L449作爲示例使用 – Gravy

+0

@Gravy啊哈,我明白了。你確定你正在導入庫嗎?在我看來,你使用Go的官方sql庫,但不是'gorm',他們有相同的方法,但有不同的實現。 –