Search code examples
swiftsqlitecore-datanspredicate

Core Data - why is my NSPredicate not resulting in the correct SQL query?


I have tried both these NSPredicates:

            let predicate = NSPredicate(format: “personID == %lld", id)
            let predicate = NSPredicate(format: “personID == %d", id)

I enabled SQL logging and saw this at the end of the SQL query:

WHERE  t0.ZPERSONID = ? 

In variables view, id has a value of Int64(156), but regardless of what I put in place of id, the resulting SQL query has t0.ZPERSONID = ? for its WHERE clause. Because of this, the predicate is useless and I’m getting duplicate record insertions every time. How do I get t0.ZPERSONID = 156?


Solution

  • WHERE  t0.ZPERSONID = ?
    

    is (part of) the prepared statement. To see which values the parameters are bound to, set the Core Data debugging level to 3 (compare How to print Core Data debug values?):

    -com.apple.CoreData.SQLDebug 3
    -com.apple.CoreData.Logging.stderr 1
    

    Also print(predicate) is useful to check the created predicate for correctness.

    In your case the problem is that you pass an NSNumber instance as argument, but the %lld format expects an Int64.

    You can convert the NSNumber to an Int64

    let id = NSNumber(value: Int64(156))
    
    let p1 = NSPredicate(format: "personID == %lld", id.int64Value)
    print(p1) // personID == 156
    

    or even simpler, use the %@ format instead:

    let p2 = NSPredicate(format: "personID == %@", id)
    print(p2) // personID == 156