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 关注
- 298 浏览
添加回答
举报