如何结合fmt.Sprintf与strings.Repeat为SQL查询动态添加占位符?
实现动态生成SQL IN语句的占位符
直接看修改后的完整代码,关键逻辑已标注:
import ( "context" "fmt" "strings" // 根据你的数据库操作库导入对应包,比如 database/sql ) func (s *TODOService) DeleteTODO(ctx context.Context, ids []int64) error { // 先处理空ID列表的情况,避免生成无效SQL if len(ids) == 0 { return fmt.Errorf("未提供需要删除的TODO ID") } // 生成与剩余ID数量匹配的占位符前缀(",?") extraPlaceholders := strings.Repeat(",?", len(ids)-1) // 拼接成完整的SQL语句 deleteSQL := fmt.Sprintf(`DELETE FROM todos WHERE id IN (?%s)`, extraPlaceholders) // 执行SQL,把ids切片展开作为参数传入(防止SQL注入) _, err := s.db.ExecContext(ctx, deleteSQL, ids...) return err }
关键逻辑说明:
- 空列表判断:必须添加,否则会生成
IN ()这种不符合SQL语法的语句,直接触发数据库错误。 - 占位符生成:因为模板里已经写了第一个
?,所以只需要用strings.Repeat生成len(ids)-1个",?",拼接后正好对应所有ID的占位符。比如ids有5个元素,最终会生成(?,?,?,?,?)。 - 安全传参:执行SQL时用
ids...展开切片,让数据库驱动自动处理参数绑定,避免手动拼接值导致的SQL注入风险。
内容的提问来源于stack exchange,提问作者user20280341
相关产品推荐
相关产品推荐

