【问题标题】:How can I search for a phrase Like O'% in MySql?如何在 MySql 中搜索短语 Like O'%?
【发布时间】:2012-01-10 17:31:21
【问题描述】:

我有一个包含人名的 MySql 数据库。当然也有以O'开头的名字。

如果我尝试使用这样的 sql 检索名称“O'Brien”:-

SELECT person_sname
FROM people
WHERE person_sname = 'O\\\'Brien'

然后我得到了预期的结果。但是,如果我尝试像这样检索所有以“O”开头的名称:-

SELECT person_sname
FROM people
WHERE person_sname like 'O\\\'Brien'

然后我得到一个空的结果集。我的目标是搜索like "O\\\'"

是否有任何解释为什么会发生这种情况?我已经搜索了 MySql 手册,但找不到任何解释为什么我的搜索不应该按预期工作。

我发现的其他问题涉及存储转义字符串或使用= 检索它,它可以正常工作,我特别想在这种情况下使用like 子句。

澄清一下:我也尝试了以下方法:-

SELECT person_sname
FROM people
WHERE person_sname like 'O\'Brien' escape "\'"

SELECT person_sname
FROM people
WHERE person_sname like 'O\'Brien'

SELECT person_sname
FROM people
WHERE person_sname LIKE 'O\'Brien'
ESCAPE '~'

字符串在插入 db usimg mysql_real_escape_string() 时被转义并存储为 O\'Brien(例如)。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您正在注入文字反斜杠。这就够了:

    SELECT person_sname
    FROM people
    WHERE person_sname = 'O\'Brien'
    

    测试:

    SELECT 'O\\\'Brien', 'O\'Brien'
    

    更新:已经有一个被接受的答案,所以我将添加一些澄清。

    首先,我忽略了存储数据已损坏的事实。不用说,这就解释了为什么person_sname = 'O\\\'Brien' 是真的。

    其次,\ 字符在 MySQL 语法中有两种用法:

    1. 这是用来组成escape sequences的字符:\n\t...
    2. LIKE expressions 中插入文字%_ 字符是默认转义字符:foo LIKE '%abc\%def%'

    问题是在 LIKE 表达式中插入 \ 符号会触发这两种行为,因此您实际上需要插入 四个 反斜杠来获得 一个

    person_sname like 'O\\\\\'Brien'
    

    ...除非您使用ESCAPE 子句更改第二个含义:

    person_sname like 'O\\\'Brien' escape '|'
    

    当然,如果数据没有损坏,您可以简单地:

    person_sname = 'O\'Brien'
    person_sname like 'O\'Brien'
    

    【讨论】:

    • +1 仍然没有解释为什么它(显然)适用于=
    • 感谢您的更新,这解释了很多。我重构了我的架构以保存“未损坏”的数据,这使我的原始查询能够正常工作。
    【解决方案2】:

    \LIKE 的默认 ESCAPE 字符,因此您需要再次对其进行转义或定义不同的 ESCAPE 字符。

    反正我不会用这样的转义字符来存储名字。

    SELECT 
            CASE WHEN name LIKE 'O\\\'Brien' THEN 1 ELSE 0 END,             /*0*/
            CASE WHEN name LIKE 'O\\\\\'Brien' THEN 1 ELSE 0 END,           /*1*/        
            CASE WHEN name LIKE 'O\\\'Brien' ESCAPE '~' THEN 1 ELSE 0 END,  /*1*/
            CASE WHEN name = 'O\\\'Brien' THEN 1 ELSE 0 END                 /*1*/
    FROM
    (SELECT 'O\\\'Brien' as name) T
    

    【讨论】:

    • 是的,您的查询给了我这些结果,但我不明白它对我有什么帮助。抱歉,太密集了。
    • @vascowhite - WHERE 子句中的最后三个条件中的任何一个都应该匹配。请注意,它们与您已经尝试过的不同。斜线的数量不同。
    • I wouldn't store names with escape characters like that anyway。那我应该如何存储'?我正处于改变这一点没有问题的阶段。
    • @vascowhite - 我将其存储为O'Brien。 `\` 显然不是实际姓/数据的一部分。
    • @vascowhite - 我自己不使用 PHP/MySQL,但我确信必须可以插入像 O'Brien 这样的名称而不必插入转义字符?可能值得另一个问题。
    【解决方案3】:

    这在大多数 SQL 方言中是相当标准的:

    SELECT person_sname
    FROM people
    WHERE person_sname like 'O''Brien' -- same as = 'O''Brien'
    
    SELECT person_sname
    FROM people
    WHERE person_sname like 'O''Brien%' -- O'Brien plus more stuff
    
    SELECT person_sname
    FROM people
    WHERE person_sname like 'O''%' -- O'plus more stuff
    

    请注意,如果ANSI_QUOTES 已打开,则不能将 " 用于字符串,因为 "" 用于标识符。

    【讨论】:

    • OP 出于某种原因将 `\` 存储在名称中,因此他们仍然会遇到该字符的问题。
    • @MartinSmith 这很不幸,而且从问题中也不是很清楚。
    • 那是假设我正确地解释了最后一行(添加为编辑)......
    【解决方案4】:

    like "O'%" 应该足够了。这里不需要任何反斜杠。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多