我有一个用户破坏了我原本可以正常工作的代码,我认为这是因为他的名字有一个撇号。我尝试使用双撇号和反斜杠转义它,但我不断收到 fatal error: unwhile unwrapping an Optional value
时意外发现 nil。
let querySQL = "SELECT name from member_data ORDER BY RANDOM() LIMIT 1"
rightAnswer = memberDatabase!.executeQuery(querySQL, withArgumentsInArray: nil)
rightAnswer!.next()
correctName = rightAnswer!.stringForColumn("name")!
println("Correct answer is \(correctName)")
//prints as Optional("Sam O\'Neal")
let sanitizedName = correctName?.stringByReplacingOccurrencesOfString("'", withString: "\'")
//tried many combinations of this
let wrongAnswerSQLQuery = "SELECT name from member_data where name is not '\(sanitizedName)' LIMIT 3"
let wrongAnswersResultSet:FMResultSet = memberDatabase!.executeQuery(wrongAnswerSQLQuery, withArgumentsInArray: nil)
最佳答案
存在三个问题:
您在 SQL 中使用了 C 风格的转义符。 SQLite documentation说
A string constant is formed by enclosing the string in single quotes ('). A single quote within the string can be encoded by putting two single quotes in a row - as in Pascal. C-style escapes using the backslash character are not supported because they are not standard SQL.
所以用
''
替换'
字符:let sanitizedName = correctName?.stringByReplacingOccurrencesOfString("'", withString: "''")
您的
sanitizedName
是可选的,因此您必须将其解包,否则它将显示为Optional(...)
:let wrongAnswerSQLQuery = "SELECT name from member_data where name is not '\(sanitizedName!)' LIMIT 3"
更好的是,您应该快刀斩乱麻,根本不要使用这样的字符串值构建 SQL 语句。
相反,您应该在 SQL 中使用
?
占位符,然后在withArgumentsInArray
中传递correctName
。那么你根本不必担心做任何这种“ sanitizer ”:let wrongAnswerSQLQuery = "SELECT name from member_data where name is not ? LIMIT 3" let wrongAnswersResultSet = memberDatabase!.executeQuery(wrongAnswerSQLQuery, withArgumentsInArray: [correctName!])
关于sql - 在 Swift 中,使用带有撇号的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30857759/