为了账号安全,请及时绑定邮箱和手机立即绑定

如何将 [] 切片传递给准备好的 SQL 语句中的 IN 条件以及非 IN 条件?

如何将 [] 切片传递给准备好的 SQL 语句中的 IN 条件以及非 IN 条件?

Go
萧十郎 2021-07-05 13:11:43
假设您有以下 SQL 查询:SELECT *  FROM foo  WHERE type = ?    AND subtype IN (?)并且您有以下可能的数据(我们假设用户界面可以设置这些数据):var Type intvar SubTypes []int在 的情况下SubTypes,我们谈论的是多项选择。现在,以下代码将不起作用:rows, err := sqldb.Query(`SELECT *  FROM foo  WHERE type = ?    AND subtype IN (?)`, Type, SubTypes)因为驱动程序(至少是mysql本示例中使用的驱动程序)无法识别[]slice. 键入以将其SubTypes...分解( ) 也不起作用,因为 A) 您不能拥有多个分解参数,而 B) 即使可以,您的 SQL 也仅支持单个项目 ( (?))。
查看完整描述

2 回答

?
慕工程0101907

TA贡献1887条经验 获得超5个赞

但是,有一个解决方案。首先,由于我们只能有一个爆炸参数而没有其他参数,因此我们应该首先将我们的参数放在一个[]slice:


var params []interface{}

params = append(params, Type)

for _, subtype := range SubTypes {

  params = append(params, SubTypes)

}

由于 SQL 不会自行扩展,让我们扩展该循环:


var params []interface{}

params = append(params, Type)

inCondition := ""

for _, subtype := range SubTypes {

  params = append(params, SubTypes)

  if inCondition != "" {

    inCondition += ", "

  }

  inCondition += "?"

}

假设SubTypes包含[]int{1,2,3},inCondition现在应该包含?, ?, ?。


然后我们将它组合到我们的 SQL 语句中并分解参数:


sqlstr := fmt.Sprintf(`SELECT *

  FROM foo

  WHERE type = ?

    AND subtype IN (%s)`, inCodition)

rows, err := sqldb.Query(sqlstr, params...)

当然,如果您可以简单地将[]slices传递给准备好的语句,并且自动展开,那就太酷了。但是,如果您正在处理更多“未知”数据,这可能会产生一些意想不到的结果。


查看完整回答
反对 回复 2021-07-12
  • 2 回答
  • 0 关注
  • 208 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信