我需要使用编译时长度未知的参数数组运行SQLite查询(我使用的是FMDB,但如果需要,可以使用原生SQLite)。到目前为止,我已经根据数组长度手动将正确数量的绑定插入到字符串中:
func getBindString (_ arrayCount: Int) -> String {
return [String](repeating: "?", count: arrayCount).joined(separator: ",")
}
let someArray = ["foo","bar"]
let sqlString = "delete from someTable where someColumn in (\(getBindString(someArray.count)))"
db.executeUpdate(sqlString, withArgumentsIn: someArray)
/* delete from someTable where someColumn in ('foo','bar') */
感觉真的很不优雅。有没有“适当的”处理方式?我在网上找到的所有东西都已经过时了几年,所有人都建议直接插值,这更糟糕。
答案 0 :(得分:1)
我没有看到这个“不优雅”的东西。您正在使用基于字符串的语言(SQL),并且您可以非常巧妙地实时构建字符串。
你的代码与我写的不完全相同;我不喜欢不需要的字符串插值,这里不需要它,所以我会提出更像这样的东西(我也认为使用map
而不是Array(repeating:)
很好):
let someArray = ["foo","bar"]
let bindString = someArray.map{_ in "?"}.joined(separator: ",")
let sqlString = "delete from someTable where someColumn in (" + bindString + ")"
如果你必须多次形成像bindString
这样的字符串,那么一定要把它变成一个实用函数。但后来我会把它写成Array的扩展名:
extension Array {
var bindString : String {
return "(" + self.map{_ in "?"}.joined(separator: ",") + ")"
}
}
这样,你的字符串结构将如下所示:
let someArray = ["foo","bar"]
let sqlString = "delete from someTable where someColumn in " + someArray.bindString
但所有这些都是纯粹的风格调整;你正在做的事情中没有没有错误。