猿问

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

假设您有以下 SQL 查询:


SELECT *

  FROM foo

  WHERE type = ?

    AND subtype IN (?)

并且您有以下可能的数据(我们假设用户界面可以设置这些数据):


var Type int

var SubTypes []int

在 的情况下SubTypes,我们谈论的是多项选择。


现在,以下代码将不起作用:


rows, err := sqldb.Query(`SELECT *

  FROM foo

  WHERE type = ?

    AND subtype IN (?)`, Type, SubTypes)

因为驱动程序(至少是mysql本示例中使用的驱动程序)无法识别[]slice. 键入以将其SubTypes...分解( ) 也不起作用,因为 A) 您不能拥有多个分解参数,而 B) 即使可以,您的 SQL 也仅支持单个项目 ( (?))。


萧十郎
浏览 209回答 2
2回答

慕工程0101907

但是,有一个解决方案。首先,由于我们只能有一个爆炸参数而没有其他参数,因此我们应该首先将我们的参数放在一个[]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传递给准备好的语句,并且自动展开,那就太酷了。但是,如果您正在处理更多“未知”数据,这可能会产生一些意想不到的结果。
随时随地看视频慕课网APP

相关分类

Go
我要回答