err = DbSlave.Raw("Select count(*) as chat_count from(select distinct(to_uid) from lu_live_report where uid=? and create_at >=? and create_at <= ? and (video_unix != 0 or voice_unix !=0) group by to_uid) as a",streamer_id,start_unixtime,end_unixtime).Scan(&total).Error
return
}
我有如上的sql,要根据start_unixtime,end_unixtime是否有值进行拼装,但现在的是写死,不支持动态的。应该做拼
我试图拼装了以下的,但不好使
sql := "Select count(*) as chat_count from(select distinct(to_uid) from lu_live_report where uid=?"
if start_unixtime != 0&& end_unixtime != 0{
sql += " and create_at >= ? and create_at <= ?"
}
sql += " and (video_unix != 0 or voice_unix !=0) group by to_uid) as a"
err = DbSlave.Raw(sql,streamer_id,start_unixtime,end_unixtime).Scan(&total).Error
golang gorm拼装sql
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
5条回答 默认 最新
檀越@新空间 2025-10-16 11:01关注上午好☀️☀️☀️️
本答案参考通义千问你目前的SQL拼接逻辑存在几个问题,最核心的问题是:在动态拼接SQL时,参数绑定(
?)的数量和顺序必须与实际传入的参数一一对应。你当前的写法中,当start_unixtime和end_unixtime不为 0 时,会添加两个?,但你只传了三个参数(streamer_id,start_unixtime,end_unixtime),这会导致 GORM 报错。
✅ 正确的处理方式如下:
1. 根据条件动态构建 SQL 语句,并正确管理参数
var sql string var args []interface{} sql = "SELECT count(*) as chat_count FROM (SELECT DISTINCT(to_uid) FROM lu_live_report WHERE uid=?" args = append(args, streamer_id) if start_unixtime != 0 && end_unixtime != 0 { sql += " AND create_at >= ? AND create_at <= ?" args = append(args, start_unixtime, end_unixtime) } sql += " AND (video_unix != 0 OR voice_unix != 0) GROUP BY to_uid) AS a" err := DbSlave.Raw(sql, args...).Scan(&total).Error return err
🔍 说明:
sql是动态构建的 SQL 字符串。args是一个切片,用于存储所有需要绑定的参数。- 使用
args...将切片展开为多个参数传递给Raw()方法。 - 这样可以确保参数数量与 SQL 中的
?数量一致,避免 GORM 报错。
🧠 注意事项:
- 不要使用字符串拼接来构造 SQL 查询,尤其是涉及用户输入的部分,容易造成 SQL 注入攻击。GORM 的
Raw()方法支持参数绑定,应优先使用这种方式。 - 如果你还需要处理
start_unixtime或end_unixtime为 0 的情况,也可以进一步扩展逻辑(例如判断是否为 0,决定是否加上该条件)。
📌 示例扩展(可选):
如果你还想根据
start_unixtime或end_unixtime是否为 0 来动态添加条件,可以这样做:sql := "SELECT count(*) as chat_count FROM (SELECT DISTINCT(to_uid) FROM lu_live_report WHERE uid=?" args := []interface{}{streamer_id} if start_unixtime != 0 { sql += " AND create_at >= ?" args = append(args, start_unixtime) } if end_unixtime != 0 { sql += " AND create_at <= ?" args = append(args, end_unixtime) } sql += " AND (video_unix != 0 OR voice_unix != 0) GROUP BY to_uid) AS a" err := DbSlave.Raw(sql, args...).Scan(&total).Error return err
✅ 总结:
- 使用参数绑定代替字符串拼接,确保安全性和正确性。
- 动态构建 SQL 时,务必同步更新参数列表。
- 使用
args...展开参数,使 GORM 能正确解析 SQL 中的占位符。
如需进一步优化或处理更复杂的查询逻辑,也可以考虑使用 GORM 的链式查询方法(如
.Where()、.Group()等)。本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报