1

短いバージョン:LIKE式で使用するために文字列をエスケープする関数が必要なので、 にfr_e%dなりfr\_e\%dます。


置換を使用せずにクエリの結果をエスケープする方法を探しています。この結果には、この char _ を含むパスがあるためです。そして、この結果を LIKE ステートメントで使用するため、"_" が start * のようなジョーカーになります。

LIKE を使用する必要があるという事実を必要とするこの同じステートメントでいくつかの連結を行っているため、LIKE を使用する必要があります。

~ を LIKE に置き換えようとしましたが、文字 '.' で同じ問題が発生します。~ は正規表現を使用するため、このソリューションもスキップしてください。

4

2 に答える 2

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)
    ||
    '%';
于 2012-11-06T23:19:04.350 に答える
2

アップデート

@Tometzkyの主張によって引き起こされました:

使用するregexp_replaceことは単にreplace(...)

私は反対しなければなりません。正規表現関数は強力ですが、比較的低速です。
したがって、イベント 3xreplace()は、単一のシンプルなイベントよりも高速です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()または同様の文字列関数を使用してパターンを準備します。次のデモを検討してください。

SELECT 'abcde' LIKE ('abc_' || '%')  -- TRUE
      ,'abc_e' LIKE ('abc_' || '%')  -- TRUE
      ,'abcde' LIKE (replace('abc_', '_', '\_')  || '%')   -- FALSE
      ,'abc_e' LIKE (replace('abc_', '_', '\_')  || '%');  -- TRUE
于 2012-11-06T21:28:51.933 に答える