在Swift中,使用带有撇号的SQL查询

时间:2015-06-16 02:12:22

标签: sql swift

我有一个用户正在破坏我的其他工作代码,我认为这是因为他的名字有撇号。我尝试使用双撇号和反斜杠来逃避它,但我一直在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)

1 个答案:

答案 0 :(得分:2)

有三个问题:

  1. 您在SQL中使用C风格的转义符。 SQLite documentation

      

    通过将字符串括在单引号(')中形成字符串常量。字符串中的单引号可以通过在行中放入两个单引号来编码 - 如Pascal中所示。不支持使用反斜杠字符的C样式转义,因为它们不是标准SQL。

    所以用'替换''个字符:

    let sanitizedName = correctName?.stringByReplacingOccurrencesOfString("'", withString: "''")
    
  2. 您的sanitizedName是可选的,因此您必须将其解包,否则它将显示为Optional(...)

    let wrongAnswerSQLQuery = "SELECT name from member_data where name is not '\(sanitizedName!)' LIMIT 3"
    
  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!])