GORM 中的 sql.Named 参数来构建子句

问题描述

我正在使用 GORM 来查询这样的数据库

query := `
    SELECT *
    ...
    ORDER BY col @colOrder`
result := DB.Raw(
    query,sql.Named("colOrder","ASC"),)

我从数据库收到语法错误,因为 sql.Named 将“ASC”转换为这样的字符串:

SELECT *
...
ORDER BY col 'ASC'

我怎样才能让 GORM 这样解释它:

SELECT * 
...
ORDER BY col ASC

谢谢!

解决方法

根据 documentation 自定义排序可以这样做:

query := `
    SELECT *
    ...
    FROM table`
result := DB.Raw(query).Order("col ASC")
,

命名参数用于将实际数据传递给查询,因此它会引用字符串并导致您的错误。

为了传递查询本身的位,您可以使用 go 的普通字符串处理工具(fmt.Sprintfstrings.Replace 等)修改字符串只要这些字符串不直接来自用户输入,否则您将面临 SQL 注入漏洞的风险。

不要做

order := request.Query().Get("order")
query := fmt.Sprintf(`SELECT ... ORDER BY col %s`,order)

可以做到

order := "ASC"
if request.Query().Get("order") == "desc" {
    order = "DESC"
}
query := fmt.Sprintf(`SELECT ... ORDER BY col %s`,order)

您也可以在使用查询构建器时对 Order 函数执行相同操作:

query := db.Model(...).
    ...
    Order(fmt.Sprintf("col %s",order)).
    Find(...)