我有一个用户正在破坏我的其他工作代码,我认为这是因为他的名字有撇号。我尝试使用双撇号和反斜杠来逃避它,但我一直在fatal error: unexpectedly found nil while unwrapping an Optional value
。
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)
答案 0 :(得分:2)
有三个问题:
您在SQL中使用C风格的转义符。 SQLite documentation说
通过将字符串括在单引号(')中形成字符串常量。字符串中的单引号可以通过在行中放入两个单引号来编码 - 如Pascal中所示。不支持使用反斜杠字符的C样式转义,因为它们不是标准SQL。
所以用'
替换''
个字符:
let sanitizedName = correctName?.stringByReplacingOccurrencesOfString("'", withString: "''")
您的sanitizedName
是可选的,因此您必须将其解包,否则它将显示为Optional(...)
:
let wrongAnswerSQLQuery = "SELECT name from member_data where name is not '\(sanitizedName!)' LIMIT 3"
更好的是,你应该删除Gordian结,而不是用这样的字符串值构建SQL语句。
相反,您应该在SQL中使用?
占位符,然后在correctName
中传递withArgumentsInArray
。然后你根本不用担心做任何“消毒”:
let wrongAnswerSQLQuery = "SELECT name from member_data where name is not ? LIMIT 3"
let wrongAnswersResultSet = memberDatabase!.executeQuery(wrongAnswerSQLQuery, withArgumentsInArray: [correctName!])