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

Ios 通过FMDB将数组传递给sqlite WHERE IN子句?,ios,sqlite,fmdb,where-in,Ios,Sqlite,Fmdb,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

是否可以通过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

我想我必须使用
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];

如果键是字符串,我将使用以下代码生成SQL命令:

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


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

我也遇到了同样的问题,我已经解决了,至少在我自己的应用程序中。首先,像这样构造查询,将问号的数量与数组中的数据量相匹配:

NSString *getDataSql = @"SELECT * FROM data WHERE dataID IN (?, ?, ?)";
然后使用
executeQuery:withArgumentsInArray
调用:

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

在我的例子中,NSArray中有一个名为DataID的NSString对象数组。我尝试了各种方法来让这个SQL查询工作,最后通过SQL/函数调用的组合,我得到了正确的结果。

再加上Wayne Liu,如果您知道字符串不包含单引号或双引号,您可以简单地执行:

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

这里是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)
    }

}

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


但是,当对象是NSStrings而不是NSNumbers时,这仍然不起作用:-(这不起作用。SQL清理将把它看作一个变量。
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]])