-
-
Notifications
You must be signed in to change notification settings - Fork 705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using array in SQL arguments #18
Comments
Hello @chiliec GRDB supports your precise use case through the RowConvertible protocol: struct Book: RowConvertible, DatabaseTableMapping {
static func databaseTableName() -> String { return "table" }
static func fromRow(row: Row) -> Book {
return Book(...)
}
}
dbQueue.inDatabase { db in
// SELECT * FROM table WHERE id IN (?,?,?)
let books = Book.fetchAll(db, keys: [1,2,3])
} More generally speaking, I wish GRDB would support arrays in arguments. I even sent a pull request to FMDB which exactly supports this feature. But I don't know how to make Swift accept as arguments an array of values or arrays of values: // Swift can't express the type of [1,[2,3,4]]
db.execute("SELECT * FROM table WHERE x > ? AND y IN (?)", arguments: [1,[2,3,4]]) Precisely speaking, Swift supports the import Foundation
let a = [1, [2,3,4]] // Array<NSObject>
let b = [nil, [2,3,4]] // error: type of expression is ambiguous without more context |
@chiliec: I'm closing this issue since you did not answer, and since Swift actively prevents us from implementing your feature request. |
@groue I noticed db.execute("UPDATE table SET state = ? where id in (?)", arguments: ["completed", [1,2,3,5,8]] ) |
Hello @siuying For SQLite a A request such as Following the same idea, the arguments to a query are only made of values, and won't accept arrays. Each value in a query arguments matches its own You would thus write something like: let ids = [1,2,3,5,8]
let questionMarks = repeatElement("?", count: ids.count).joined(separator: ",")
let query = "UPDATE t SET state = ? WHERE id IN (\(questionMarks))"
var arguments: StatementArguments = ["completed"]
arguments += StatementArguments(ids)
print(arguments) // Prints ["completed", 1, 2, 3, 5, 8]
try db.execute(query, arguments: arguments) |
Thank you for your pointer! I don't know where do I get the idea I can use array here... everything make sense now, thanks again! |
Is this still the recommend mechanism of injecting an array of IDS into an |
When you build a raw SQL string, you have to embed as many question marks as there are arguments. That's how SQLite interprets SQL: let ids = [1, 2, 3]
let questionMarks = databaseQuestionMarks(count: ids.count) // "?,?,?"
let sql = "SELECT * FROM player WHERE id IN (\(questionMarks))"
let arguments = StatementArguments(ids)
let players = try Player.fetchAll(db, sql: sql, arguments: arguments) You can also use SQL Interpolation: let ids = [1, 2, 3]
let request: SQLRequest<Player> = "SELECT * FROM player WHERE id IN \(ids)"
let players = try request.fetchAll(db) |
I'd like to use in sql expressions with array:
but I get an error:
Contextual type 'DatabaseValueConvertible' cannot be used with array literal
What do you think about this?
The text was updated successfully, but these errors were encountered: