如何在LIKE中使用PostgreSQL时不使用replace函数进行转义

时间:2012-11-06 20:20:22

标签: postgresql escaping sql-like

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


我正在寻找逃避查询结果而无需使用替换。 因为在这个结果中我有这个char _ inside的路径。因为我在LIKE语句中使用了这个结果,所以它使“_”成为一个喜欢start *的小丑。

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

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

2 个答案:

答案 0 :(得分:4)

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)
    ||
    '%';

答案 1 :(得分: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