You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang BUN ORM WHERE子句解析异常:参数未替换为具体数值

Golang BUN ORM中WHERE子句占位符未被替换的问题

问题重现

执行以下代码生成SQL时,WHERE子句的?占位符没有被替换为传入的数值1:

type UserBun struct {
    bun.BaseModel `bun:"table:users,alias:u"`
    ID         int64 `bun:"id"`
}
    
query := db.NewSelect().Model(&UserBun{}).Where("id = ?", 1).String()

fmt.Println(query) 
// 实际结果: SELECT "u"."id", "u"."employee_id" FROM "users" AS "u" WHERE (id = ?)
// 预期结果: SELECT "u"."id", "u"."employee_id" FROM "users" AS "u" WHERE (id = 1)

原因说明

BUN ORM的String()方法仅负责生成带占位符的SQL模板,不会直接将参数替换进SQL字符串中。这是BUN的设计逻辑:它默认依赖数据库的预编译语句机制,参数会在执行查询时由数据库驱动安全注入,以此避免SQL注入风险,同时提升查询性能。

调试时查看带参数的完整SQL

如果只是为了调试需要看到参数替换后的SQL,可以用以下两种方式:

  • 方式一:开启Debug模式执行查询
    调用Debug()方法后执行查询,BUN会在日志中输出包含具体参数的完整SQL:

    ctx := context.Background()
    db.Debug().NewSelect().Model(&UserBun{}).Where("id = ?", 1).Scan(ctx)
    
  • 方式二:使用QueryDump获取SQL和参数
    通过QueryDump()方法可以分别获取SQL模板和参数列表,按需查看或拼接:

    ctx := context.Background()
    sqlTemplate, args := db.NewSelect().Model(&UserBun{}).Where("id = ?", 1).QueryDump(ctx)
    fmt.Printf("SQL模板: %s\n参数列表: %v\n", sqlTemplate, args)
    // 若要手动拼接(仅调试用,生产环境禁止):
    debugSQL := sqlTemplate
    for _, arg := range args {
        debugSQL = strings.Replace(debugSQL, "?", fmt.Sprintf("%v", arg), 1)
    }
    fmt.Println("调试用完整SQL:", debugSQL)
    

内容的提问来源于stack exchange,提问作者Артур Леополдбь

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 01:07:20