【问题标题】:How escape without using replace function in LIKE with PostgreSQL如何在 LIKE 和 PostgreSQL 中不使用替换函数的情况下进行转义
【发布时间】:2012-11-06 20:20:22
【问题描述】:

短版:我需要一个函数来转义字符串以用于LIKE 表达式,因此fr_e%d 变为fr\_e\%d


我正在寻找转义查询结果而不需要使用替换。 因为在这个结果中我有这个 char _ 里面的路径。而且因为我在 LIKE 语句中使用了这个结果,所以它使“_”成为一个像 start * 一样的小丑。

我必须使用 LIKE,因为我在同一个语句中做一些东西连接,需要我使用 LIKE 的事实。

我尝试用 ~ 替换 LIKE 但我会遇到与 char '.' 相同的问题因为〜是使用正则表达式,所以也跳过这个解决方案。

【问题讨论】:

    标签: postgresql escaping sql-like


    【解决方案1】:
    create function quote_like(text) returns text language sql immutable strict as
      $quote_like$
        select regexp_replace($1, $$[_%\\]$$, $$\\\&$$, 'g');
      $quote_like$;
    

    此函数将所有出现的_%\ 在提供的字符串中添加\。例如,您可以像这样使用它:

    select * from tablename
      where tablecolumn like
        '%'
        ||
        (select quote_like(substring) from substrings where substring_id=123)
        ||
        '%';
    

    【讨论】:

    • 使用regexp_replace() 的单次传递——即使是像示例中那样干净、简单的传递——通常比replace() 的三个实例更昂贵。
    • @ErwinBrandstetter:你说得对——replace(replace(replace(... 比单一的regexp_replace 快一些,但速度并不快——在我的测试中提高了 15-20%。
    • 感谢大家的解决方案。
    【解决方案2】:

    更新

    由@Tometzky 的声明触发:

    使用regexp_replace 比简单地使用replace 更好(...)

    我不得不不同意。正则表达式函数功能强大但相对速度较慢
    因此,事件 3x replace() 比单个简单的 regexp_replace() 更快 - 至少在我的测试中:

    CREATE OR REPLACE FUNCTION quote_like2(text)
      RETURNS text LANGUAGE SQL IMMUTABLE STRICT AS
    $func$
    SELECT replace(replace(replace(
             $1
            ,'\', '\\') -- must come first
            ,'_', '\_')
            ,'%', '\%');
    $func$;
    

    请注意,我使用普通单引号而不是美元引号。这需要standard_conforming_strings = on,这是自 PostgreSQL 9.1 以来的默认设置。

    用你的数据试试这两个函数:

    EXPLAIN ANALYZE SELECT quote_like1(col) from tbl;
    

    原答案

    与您的问题标题相反,您通常会使用replace() or a similar string function 来准备您的模式。考虑这个演示:

    SELECT 'abcde' LIKE ('abc_' || '%')  -- TRUE
          ,'abc_e' LIKE ('abc_' || '%')  -- TRUE
          ,'abcde' LIKE (replace('abc_', '_', '\_')  || '%')   -- FALSE
          ,'abc_e' LIKE (replace('abc_', '_', '\_')  || '%');  -- TRUE
    

    【讨论】:

    • 你也是对的,尤其是关于什么解决方案更快。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2015-06-28
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 2020-11-20
    • 2022-11-13
    • 1970-01-01
    相关资源
    最近更新 更多