2011-12-05 25 views
12

Có thể truyền một mảng tới câu lệnh SELECT… WHERE… IN qua FMDB không? Tôi cố gắng để nổ tung các mảng như thế này:Vượt qua một mảng để sqlite WHERE IN khoản qua 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]; 

này hoạt động chỉ khi có chính xác 1 đối tượng trong mảng, dẫn tôi để tin rằng FMDB thêm dấu ngoặc kép quanh toàn bộ nổ tung chuỗi.

Vì vậy, tôi cố gắng đi qua các mảng như là phương pháp FMDB của:

NSArray *mergeIds; // An array with NSNumber Objects 
NSString *query = @"SELECT * FROM items WHERE last_merge_id IN (?)"; 
FMResultSet *result = [database executeQuery:query, mergeIds]; 

nào không làm việc ở tất cả.

Tôi không tìm thấy bất kỳ điều gì về nó trong README hoặc các mẫu trên trang github của FMDB.

Cảm ơn, Stefan

Trả lời

9

Vâng, tôi đoán tôi phải sử dụng executeQueryWithFormat (trong đó, theo tài liệu hướng dẫn FMDB là không phải là cách khuyến khích). Dù sao, đây là giải pháp của tôi:

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

Nhưng bằng cách nào đó điều này vẫn không hoạt động khi các đối tượng đang NSStrings thay vì NSNumbers.:-( – Stefan

+4

Điều này sẽ không hoạt động. SQL sanitization sẽ thấy điều này một biến duy nhất. –

5

Nếu các phím được chuỗi, tôi sử dụng đoạn mã sau để tạo ra các lệnh SQL:

(giả strArray là một NSArray chứa yếu tố NSString)

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

Xin lưu ý: nếu bất kỳ phần tử nào trong strArray có thể chứa các ký hiệu "báo giá kép", bạn cần phải viết thêm mã (trước 2 dòng này) để thoát chúng bằng cách viết 2 dấu ngoặc kép thay thế.

11

Tôi đã gặp vấn đề tương tự và tôi đã tìm ra, ít nhất là cho ứng dụng của riêng tôi. Thứ nhất, cấu trúc truy vấn của bạn như vậy, phù hợp với số lượng dấu hỏi như lượng dữ liệu trong mảng:

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

Sau đó sử dụng executeQuery:withArgumentsInArray gọi:

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

Trong trường hợp của tôi, tôi đã có một mảng các đối tượng NSString bên trong NSArray có tên là dataIDs. Tôi đã thử tất cả mọi thứ để có được truy vấn SQL này hoạt động, và cuối cùng với sự kết hợp này của sql/function call, tôi đã có thể nhận được kết quả phù hợp.

4

Thêm vào Wayne Liu, nếu bạn biết rằng các dây không chứa đơn hay ngoặc kép, bạn chỉ có thể làm:

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

Dưới đây là một phần mở rộng Swift cho FMDatabase mà phá vỡ tham số truy vấn mảng thành nhiều tên thông số.

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

} 

Ví dụ:

let sql = "SELECT * FROM things WHERE id IN :thing_ids" 
let rs = db.executQuery(sql, params: ["thing_ids": [1, 2, 3]]) 
Các vấn đề liên quan