通过FMDB将数组传递给sqlite WHERE IN子句?

是否有可能通过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]; 

这只适用于数组中只有1个对象的情况,这导致我相信FMDB会在整个内爆string周围添加引号。

所以我试图按照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页面上的示例中,我没有find任何有关它的信息。

谢谢你,斯蒂芬

我遇到了同样的问题,至less对我自己的应用程序来说,我已经知道了。 首先,像这样构造查询,将问号的数量与数组中的数据量进行匹配:

 NSString *getDataSql = @"SELECT * FROM data WHERE dataID IN (?, ?, ?)"; 

然后使用executeQuery:withArgumentsInArray调用:

 FMResultSet *results = [database executeQuery:getDataSql withArgumentsInArray:dataIDs]; 

在我的情况下,我有NSArray中名为dataIDs内的NSString对象的数组。 我尝试了各种各样的事情来获得这个SQL查询工作,最后与这个组合的SQL /函数调用,我能够得到正确的结果。

那么我想我必须使用executeQueryWithFormat (根据FMDB文档不是推荐的方式)。 无论如何,这是我的解决scheme:

 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]; 

如果键是string,我使用下面的代码来生成SQL命令:

(假设strArray是一个包含NSString元素的NSArray)

 NSString * strComma = [strArray componentsJoinedByString:@"\", \""]; NSString * sql = [NSString stringWithFormat:@"SELECT * FROM tableName WHERE fieldName IN (\"%@\")", strComma]; 

请注意:如果strArray中的任何元素都可能包含“双引号”符号,则需要编写额外的代码(在这两行之前),而不是通过写两个双引号来转义它们。

加上Wayne Liu,如果你知道string不包含单引号或双引号,你可以简单地做:

 NSString * delimitedString = [strArray componentsJoinedByString:@"','"]; NSString * sql = [NSString stringWithFormat:@"SELECT * FROM tableName WHERE fieldName IN ('%@')", delimitedString]; 

我创build了一个简单的FMDB扩展来解决这个问题:

FMDB + InOperator在GitHub上

这是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]]) 
Interesting Posts