【问题标题】:Escape single quote character for use in an SQLite query转义单引号字符以在 SQLite 查询中使用
【发布时间】:2022-01-27 17:35:48
【问题描述】:

我在一个文件中编写了数据库模式(目前只有一张表)和该表的 INSERT 语句。然后我创建数据库如下:

$ sqlite3 newdatabase.db
SQLite version 3.4.0
Enter ".help" for instructions
sqlite> .read ./schema.sql
SQL error near line 16: near "s": syntax error

我的文件的第 16 行如下所示:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there\'s');

问题是单引号的转义字符。我也尝试过双重转义单引号(使用\\\' 而不是\'),但这也不起作用。我做错了什么?

【问题讨论】:

    标签: sqlite escaping


    【解决方案1】:

    尝试将单引号加倍(许多数据库都希望这样),所以它会是:

    INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');
    

    来自the documentation的相关引用:

    字符串常量是通过用单引号 (') 将字符串括起来形成的。字符串中的单引号可以通过将两个单引号放在一行中来编码 - 就像在 Pascal 中一样。不支持使用反斜杠字符的 C 样式转义,因为它们不是标准 SQL。 BLOB 文字是包含十六进制数据的字符串文字,前面有一个“x”或“X”字符。 ...文字值也可以是标记“NULL”。

    【讨论】:

    • 另外,如果宿主语言支持绑定参数,请考虑使用它们(大多数支持,但 SQLite shell 不支持)。然后 SQL 将是 INSERT INTO table_name (field1, field2) VALUES (?, ?) 并且将直接提供值(并且没有替换)。
    • 我们不能只使用双引号吗?比如: INSERT INTO table_name (field1, field2) VALUES (123, "Hello there's"); ?
    • 另外,根据字符串的生命周期,第一步可能是将 '' 转换为 ',然后再将它们加倍。
    • @JacksOnF1re 在 SQL 中,双引号用于标识符而不是字符串。就像INSERT INTO "table_name"("field1", "field2") VALUES('value 1', 'value 2'); 一样,双引号完全像文字一样工作,这是一种兼容性的怪癖。见:sqlite.org/…
    【解决方案2】:

    我相信你想通过加倍单引号来逃避:

    INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');
    

    【讨论】:

      【解决方案3】:

      在 C# 中,您可以使用以下命令将单引号替换为双引号:

       string sample = "St. Mary's";
       string escapedSample = sample.Replace("'", "''");
      

      输出将是:

      "St. Mary''s"
      

      而且,如果您直接使用 Sqlite;您可以使用对象而不是字符串并捕获特殊的东西,例如 DBNull:

      private static string MySqlEscape(Object usString)
      {
          if (usString is DBNull)
          {
              return "";
          }
          string sample = Convert.ToString(usString);
          return sample.Replace("'", "''");
      }
      

      【讨论】:

        【解决方案4】:

        以防万一您有需要插入数据库的循环或 json 字符串。尝试用单引号替换字符串。这是我的解决方案。例如,如果您有一个包含单引号的字符串。

        String mystring = "Sample's";
        String myfinalstring = mystring.replace("'","''");
        
         String query = "INSERT INTO "+table name+" ("+field1+") values ('"+myfinalstring+"')";
        

        这在 c# 和 java 中适用于我

        【讨论】:

        • 注意:C# 中的 Replace("'","''")。 (唯一的变化是大写 R。)
        【解决方案5】:

        要替换字符串中的所有 ('),请使用

        .replace(/\'/g,"''")
        

        示例:

        sample = "St. Mary's and St. John's";
        escapedSample = sample.replace(/\'/g,"''")
        

        【讨论】:

          【解决方案6】:

          在 bash 脚本中,我发现在值周围转义双引号对于可能为 null 或包含需要转义的字符(如连字符)的值是必要的。

          在本例中,columnA 的值可以为 null 或包含连字符。:

          sqlite3 $db_name "insert into foo values (\"$columnA\", $columnB)";
          

          【讨论】:

          • sqlite 中的双引号表示“这是一个标识符,而不是字符串”。因此,虽然它对一些黑客行为很好,但你不希望它在生产中使用。
          【解决方案7】:

          演示不需要复杂性或双引号的单引号字符串行为。

          测试:

          SELECT replace('SAMY''S','''''',''''); 
          

          输出:

          SAMY'S
          

          SQLite 版本:

          SELECT sqlite_version();
          

          输出:

          3.36.0
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-07-10
            • 2014-03-21
            • 2013-06-12
            • 2015-07-07
            • 2013-02-10
            • 2017-07-01
            相关资源
            最近更新 更多