mysql 我应该如何转义这个LIKE查询中的字符?

p4tfgftt  于 2023-06-28  发布在  Mysql
关注(0)|答案(5)|浏览(159)

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

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

(Only当然是为了测试目的)。我尝试了无数的查询来正确选择这个字段,当然没有返回任何错误,但我似乎就是不能正确选择。
这是我目前使用的查询:

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

有谁能告诉我我哪里做得不对吗?是否还有其他字符(除了')需要转义?我没在任何地方读到过...(不过,我确实尝试在当前符号之前添加反斜杠)。

7ajki6be

7ajki6be1#

MySQL手册:
MySQL在字符串中使用C转义语法(例如,\n表示换行符)。如果希望LIKE字符串包含文字\,则必须将其加倍。(除非启用了NO_BACKSLASH_ESCAPES SQL模式,在这种情况下不使用转义字符。)例如,要搜索\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 prepared statement代替第二步(字面转义):

// 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}%"]);
pwuypxnk

pwuypxnk2#

不清楚你想得到什么,出了什么问题。
顺便说一下,如果你想保护你的查询不受SQL注入的影响,你应该使用mysql_真实的_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)."%'"
pftdvrlh

pftdvrlh3#

在某些情况下,使用LOCATE更简单:https://www.w3schools.com/sql/func_mysql_locate.asp
我不能确定什么是更快的:MySQL LIKE vs LOCATE
ORM也不是问题:

  • 教义-https://www.doctrine-project.org/projects/doctrine-orm/en/2.15/reference/dql-doctrine-query-language.html#dql-functions
  • Hibernate -https://docs.oracle.com/html/E24396_01/ejb3_langref.html#ejb3_langref_string_fun

对于99%的项目,LOCATE比LIKE更好。你不会为特殊字符而头痛。为什么你需要LIKE的主要原因是一个全文搜索,如果你使用LIKE的目的,那么这意味着你不需要什么特别的东西。

z6psavjg

z6psavjg4#

你在用PHP吗?如果是这样,你可以尝试以下操作:

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

这能解决你的问题吗

cygmwpex

cygmwpex5#

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

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

(其中pattern可以是另一列:column2、MySQL变量或表达式)
这在存储过程/函数中也很有用。

相关问题