【问题标题】:How should I escape characters inside this LIKE query?我应该如何在这个 LIKE 查询中转义字符?
【发布时间】:2011-11-11 17:29:37
【问题描述】:

我的一个表中有一个字段包含此字符串:

!"#¤%&/()=?´`?=)(/&%¤#"!\'\'"'

(当然仅用于测试目的)。我已经尝试了无数次查询来正确选择这个字段,当然没有返回任何错误,但我似乎无法正确。

这是我目前使用的查询:

SELECT * FROM mytable WHERE `column` LIKE '%!"#¤%&/()=?´`?=)(/&%¤#"!\\\'\\\'"\'%'

谁能解释一下我做错了什么?还有其他我应该转义的字符(' 除外)吗?我还没有在任何地方读到过它...(不过我确实尝试在百分号之前添加反斜杠)。

【问题讨论】:

  • 执行此操作时到底出了什么问题?
  • 它要么返回“错误 1064”,要么什么都不返回。
  • 我可能已经解决了,但我有点困惑......我在转义字符串末尾的当前 3 个反斜杠后面添加了 2 个额外的反斜杠,这就像我想要的一样它到。为什么我必须使用 5?一个(转义原始字符串中已经存在的反斜杠)和一个转义紧随其后的撇号不就足够了吗?
  • 向我们展示您用于测试的代码。您的问题可能与 PHP 为您取消转义字符串,然后将其传递给数据库的事实有关。按照 nulll 的建议使用 mysql_real_escape_string 而不是自己尝试转义字符可能会解决您的问题。
  • 顺便说一句,我的意思是 PHP 代码,而不是您假设发送到 MySQL 的 SQL 代码。

标签: mysql escaping sql-like


【解决方案1】:

如果您与(模式)进行比较的那个字段不是常量(如您指定的那个:%!"#¤%&/()=?...),您可以像这样在 MySQL 中直接对其进行转义:

SELECT * FROM `mytable` WHERE `column` LIKE REGEXP_REPLACE(pattern, '([%_])', '\\\\$1');

(其中pattern 可以是另一列:column2、MySQL 变量或表达式)

这在存储过程/函数中也很有用。

【讨论】:

    【解决方案2】:

    来自MySQL Manual

    由于 MySQL 在字符串中使用 C 转义语法(例如,“\n”表示换行符),因此您必须将在 LIKE 字符串中使用的任何“\”加倍。例如,要搜索“\n”,请将其指定为“\\n”。搜索“\”,指定为“\\\\”;这是因为反斜杠被解析器剥离一次,并在进行模式匹配时再次剥离,留下一个反斜杠进行匹配。

    因此,您应该分两步为LIKE 运算符转义字符串。

    在 PHP 中可以是这样的:

    // Your search string, for example, from POST field
    $string = $_POST['column'];
    
    // First step - LIKE escaping
    $string = str_replace(array('\\', '_', '%'), array('\\\\', '\\_', '\\%'), $string);
    
    // Second step - literal escaping
    $string = mysql_real_escape_string($string);
    
    // Result query
    mysql_query("SELECT * FROM `table` WHERE `column` LIKE '%".$string."%'");
    

    更新:

    MySQL 扩展在 PHP 5.5.0 中被弃用,并在 PHP 7.0.0 中被删除。相反,应该使用 MySQLiPDO_MySQL 扩展名。

    使用 MySQLi

    // Connect to database
    $mysqli = new mysqli('localhost', 'username', 'password', 'database');
    
    // Your search string, for example, from POST field
    $string = $_POST['column'];
    
    // First step - LIKE escaping
    $string = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $string);
    
    // Second step - literal escaping
    $string = $mysqli->real_escape_string($string);
    
    // Result query
    $mysqli->query("SELECT * FROM `table` WHERE `column` LIKE '%{$string}%'");
    

    使用 PDO

    // Connect to database
    $conn = new PDO('mysql:host=localhost;dbname=database', 'username', 'password');
    
    // Your search string, for example, from POST field
    $string = $_POST['column'];
    
    // First step - LIKE escaping
    $string = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $string);
    
    // Second step - literal escaping
    $string = $conn->quote($string);
    
    // Result query
    $conn->query("SELECT * FROM `table` WHERE `column` LIKE '%{$string}%'");
    

    或者您可以使用 PDO 准备语句,而不是第二步(文字转义):

    // Connect to database
    $conn = new PDO('mysql:host=localhost;dbname=database', 'username', 'password');
    
    // Your search string, for example, from POST field
    $string = $_POST['column'];
    
    // First step - LIKE escaping
    $string = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $string);
    
    // Prepare a statement for execution
    $statement = $conn->prepare("SELECT * FROM `table` WHERE `column` LIKE ?");
    
    // Execute a prepared statement
    $statement->execute(["%{$string}%"]);
    

    【讨论】:

    【解决方案3】:

    你在使用 PHP 吗?如果是这样,您可以尝试以下方法:

    $a = mysql_real_escape_string('%!"#¤%&/()=?´`?=)(/&%¤#"!\'\'"\'%');
    $query_string = "SELECT * FROM mytable WHERE `column` LIKE '$a'";
    

    这能解决你的问题吗?

    【讨论】:

      【解决方案4】:

      不清楚您要获取什么以及出了什么问题。

      顺便说一句,如果你想保护你的查询免受 SQL 注入,你应该使用 mysql_real_escape_string
      http://dev.mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html

      假设你在 PHP 中

      $query = "SELECT * FROM mytable WHERE `column` LIKE '".mysql_real_escape_string($whatever)."'"
      

      但你必须记住,LIKE 运算符有自己的特殊字符(wildchars)
      http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like

      % Matches any number of characters, even zero characters
      _ Matches exactly one character
      

      所以如果你想停止它们的魔法

      ,这个字符必须用反斜杠转义

      假设你在 PHP 我会这样做

      // This removes magic on LIKE wildchars
      $whatever = preg_replace('#(%|_)#', '\\$1', $input);
      
      // This secures the query from sql injection 
      // and hads the trailing % wildchars to the search string
      $query = "SELECT * FROM mytable WHERE `column` LIKE '%".mysql_real_escape_string($whatever)."%'"
      

      【讨论】:

      • 我们是否还需要转义反斜杠本身,以防有人在他们的搜索查询中包含反斜杠?
      猜你喜欢
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多