Reputation: 225
I am having a problem accessing sqlite3 database in an xcode swift project. Specifically when binding host parameters in a prepared sql statement to a text (string) value the bind always binds all ? rather than just one. So the results are not what is expected. (NOTE: I am just using the builtin sqlite3 lib with bridging header file specified, not any 3rd party wrappers)
For example: my test database table has a column named str1 whose values are years such as "2010", "2011", etc (not Integers, but Strings). If I use the SQL statement:
SELECT * FROM table1 WHERE str1 BETWEEN '2011' AND '2012'
it gives me all the rows that I expected to get. But if I use the statement:
SELECT * FROM table1 WHERE str1 BETWEEN ? AND ?
and bind the prepared statement with:
sqlite3_bind_text(statement, 1, "2011", -1, nil)
sqlite3_bind_text(statement, 2, "2012", -1, nil)
it returns only the rows for "2012". The prepare was done with:
sqlite3_prepare_v2(db, sql, -1, &statement, tail)
So, the bind is somewhat working, but it seems to always replace ALL ? with the value rather than just one. (It works no differently if I use unique parameter names such as ?1 and ?2 rather than just ? ?)
So, my question is: how to bind sqlite3 host parameter to Swift string value?
Upvotes: 3
Views: 1507
Reputation: 4044
Looking at the source code of GRDB.swift (https://github.com/groue/GRDB.swift/blob/v2.9.0/GRDB/Core/Statement.swift#L179 and https://github.com/groue/GRDB.swift/blob/v2.9.0/GRDB/Core/Database.swift#L14) I think the following code will work:
let SQLITE_TRANSIENT = unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite3_destructor_type.self)
sqlite3_bind_text(statement, index, string, -1, SQLITE_TRANSIENT)
Upvotes: 4