3 回答

TA貢獻1829條經驗 獲得超9個贊
對于那些感興趣的人,我已經通過一些更新解決了我的問題。
連接時在DSN上有設置
?...&multiStatements=true&interpolateParams=true
添加以上內容后,我開始收到有關排序規則的新錯誤 (
Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='
。我檢查并轉換了數據庫和表utf8mb4_general_ci
,一切都按預期工作。
感謝那些提供解決方案的人,但這是我們最終選擇的路線。

TA貢獻1859條經驗 獲得超6個贊
與大多數查詢接口一樣,該Query()函數一次只能執行一個 SQL 語句。MySQL 的準備語句不適用于多查詢。
SET您可以通過在一次調用中執行語句,然后在第二次調用中執行語句來解決此問題SELECT。但是您必須注意確保它們在同一個數據庫連接上執行,否則連接池很可能在不同的連接上運行它們。所以你需要做類似的事情:
conn, err := d.Conn(context.TODO())
conn.QueryContext(context.TODO(), "SET ...")
conn.QueryContext(context.TODO(), "SELECT ...")
或者,更改準備 ORDER BY 的方式,這樣就不需要用戶定義的變量。
我這樣做的方法是在 Go 代碼中而不是在 SQL 中構建 ORDER BY 語句,使用字符串映射來確保使用有效的列和方向。如果輸入不在地圖中,則將默認順序設置為主鍵。
validOrders := map[string]string{
"type,asc": "type ASC",
"type,desc": "type DESC",
"visible,asc": "visible ASC",
"visible,desc": "visible DESC",
"create_date,asc": "create_date ASC",
"create_date,desc": "create_date DESC",
"update_date,asc": "update_date ASC",
"update_date,desc": "update_date DESC",
}
orderBy, ok := validOrders[srt]
if !ok {
orderBy = "id ASC"
}
query := fmt.Sprintf(`
SELECT ...
WHERE user_id = ?
ORDER BY %s
LIMIT ?, ?
`, orderBy)
這對于 SQL 注入是安全的,因為函數輸入不會插入到查詢中。它是從我的地圖中插入到查詢中的值,并且該值在我的控制之下。如果有人試圖輸入一些惡意值,它不會匹配我地圖中的任何鍵,所以它只會使用默認排序順序。

TA貢獻1770條經驗 獲得超3個贊
除非驅動程序實現特殊接口,否則查詢在執行前首先在服務器上準備好。因此 Bindvars 是特定于數據庫的:
MySQL:使用?上面顯示的變體
PostgreSQL:使用枚舉的 $1、$2 等 bindvar 語法
SQLite:接受兩者?和 $1 語法
Oracle:使用 :name 語法
MsSQL:@(隨你用)
我想這就是為什么你不能用 query() 做你想做的事。
- 3 回答
- 0 關注
- 327 瀏覽
添加回答
舉報