是否可以通过FMDB将数组传递给SELECT ... WHERE ... IN语句? 我试图像这样破坏数组:
NSArray *mergeIds; // An array with NSNumber Objects
NSString *mergeIdString = [mergeIds componentsJoinedByString:@","];
NSString *query = @"SELECT * FROM items WHERE last_merge_id IN (?)";
FMResultSet *result = [database executeQuery:query, mergeIdString];
这只有在数组中只有一个对象时才有效,这让我相信FMDB会在整个内爆字符串周围添加引号。
所以我尝试将数组按原样传递给FMDB的方法:
NSArray *mergeIds; // An array with NSNumber Objects
NSString *query = @"SELECT * FROM items WHERE last_merge_id IN (?)";
FMResultSet *result = [database executeQuery:query, mergeIds];
根本不起作用。
我在自述文件或FMDB的github页面上的示例中没有找到任何相关信息。
谢谢,Stefan
答案 0 :(得分:11)
我遇到了同样的问题,我想出来了,至少对我自己的应用来说。首先,像这样构造您的查询,将问号的数量与数组中的数据量相匹配:
NSString *getDataSql = @"SELECT * FROM data WHERE dataID IN (?, ?, ?)";
然后使用executeQuery:withArgumentsInArray
电话:
FMResultSet *results = [database executeQuery:getDataSql withArgumentsInArray:dataIDs];
在我的例子中,我在NSArray中有一个名为dataIDs的NSString对象数组。我尝试了各种各样的东西来使这个SQL查询工作,最后通过这个sql / function调用的组合,我能够得到正确的结果。
答案 1 :(得分:9)
嗯,我想我必须使用executeQueryWithFormat
(根据FMDB文档不推荐的方式)。无论如何,这是我的解决方案:
NSArray *mergeIds; // An array of NSNumber Objects
NSString *mergeIdString = [mergeIds componentsJoinedByString:@","];
NSString *query = @"SELECT * FROM items WHERE last_merge_id IN (?)";
FMResultSet *res = [self.database executeQueryWithFormat:query, mergeIdString];
答案 2 :(得分:5)
如果键是字符串,我使用以下代码生成SQL命令:
(假设strArray是一个包含NSString元素的NSArray)
NSString * strComma = [strArray componentsJoinedByString:@"\", \""];
NSString * sql = [NSString stringWithFormat:@"SELECT * FROM tableName WHERE fieldName IN (\"%@\")", strComma];
请注意:如果strArray中的任何元素可能包含“双引号”符号,则需要编写额外的代码(在这两行之前)以通过编写2个双引号来转义它们。
答案 3 :(得分:4)
添加到Wayne Liu上,如果您知道字符串不包含单引号或双引号,您可以这样做:
NSString * delimitedString = [strArray componentsJoinedByString:@"','"];
NSString * sql = [NSString stringWithFormat:@"SELECT * FROM tableName WHERE fieldName IN ('%@')", delimitedString];
答案 4 :(得分:1)
我创建了一个简单的FMDB扩展来解决问题:
{{3}}
答案 5 :(得分:0)
这是FMDatabase的Swift扩展,它将数组查询参数分解为多个命名参数。
extension FMDatabase {
func executeQuery(query: String, params:[String: AnyObject]) -> FMResultSet? {
var q = query
var d = [String: AnyObject]()
for (key, val) in params {
if let arr = val as? [AnyObject] {
var r = [String]()
for var i = 0; i < arr.count; i++ {
let keyWithIndex = "\(key)_\(i)"
r.append(":\(keyWithIndex)")
d[keyWithIndex] = arr[i]
}
let replacement = ",".join(r)
q = q.stringByReplacingOccurrencesOfString(":\(key)", withString: "(\(replacement))", options: NSStringCompareOptions.LiteralSearch, range: nil)
}
else {
d[key] = val
}
}
return executeQuery(q, withParameterDictionary: d)
}
}
示例:
let sql = "SELECT * FROM things WHERE id IN :thing_ids"
let rs = db.executQuery(sql, params: ["thing_ids": [1, 2, 3]])