Подтвердить что ты не робот

Передача массива в sqlite предложение WHERE IN через FMDB?

Можно ли передать массив в инструкцию SELECT... WHERE... IN через FMDB? Я попытался взорвать массив следующим образом:

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

Что не работает вообще.

Я ничего не нашел в README или образцах на странице gigub на FMDB.

Спасибо, Стефан

4b9b3361

Ответ 2

У меня была такая же проблема, и я понял это, по крайней мере, для собственного приложения. Во-первых, структурируйте свой запрос так, сопоставив количество вопросительных знаков в виде количества данных в массиве:

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

Затем используйте вызов executeQuery:withArgumentsInArray:

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

В моем случае у меня был массив объектов NSString внутри NSArray с именем dataID. Я пробовал всевозможные вещи, чтобы заставить этот SQL-запрос работать, и, наконец, с этой комбинацией вызова sql/function, я смог получить правильные результаты.

Ответ 3

Ну, я думаю, мне нужно использовать 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];

Ответ 4

Если ключи являются строками, я использую следующий код для генерации команды SQL:

(предположим, что strArray является NSArray, содержащим элементы NSString)

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

Обратите внимание: если какие-либо элементы в strArray потенциально могут содержать символы "двойной кавычки", вам нужно написать дополнительные коды (до этих двух строк), чтобы избежать их, написав вместо этого две двойные кавычки.

Ответ 5

Добавление на Wayne Liu, если вы знаете, что строки не содержат одиночных или двойных кавычек, вы можете просто сделать:

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

Ответ 6

Здесь имеется быстрое расширение для FMDatabase, которое разбивает параметры запроса массива на несколько именованных параметров.

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