web-dev-qa-db-ja.com

OracleのREGEXP_LIKEではない

電話番号のある大きなテーブルがあります。電話番号はすべて文字列であり、「+ 9628789878」または類似の番号であると想定されています。 (「+」記号の後に9〜13桁が続きます。)

ユーザーのバグにより、「+ 987 + 9873678298」という文字列のある行が見つかりました。明らかにそこにあるべきではないので、このエラーまたは他のそのようなエラーが他にいくつあるかを調べたいと思います。

このクエリを試しましたが、仕事をしていません。私の考えは、この文字列のようなものではありません。 (ああ、テーブルはphone_numberでインデックス付けされていません。)

SELECT user_key,
       first_name,
       last_name,
       phone_number
FROM   users u
WHERE  regexp_like(phone_number, '[^\+[0-9]*]')
AND    phone_number IS NOT NULL
9
SAR622

phone_numberが正確に'+'に続いて9-13桁の数字で作られていないすべての行を見つける必要がある場合、これは作業を行う必要があります。

select *
from users 
where not regexp_like(phone_number, '^\+[0-9]{9,13}$')

それが何をする:

  • ^文字列の先頭、'XX +123456789'のようなことを避けるため
  • \+ '+'
  • [0-9]{9,13} 9〜13桁のシーケンス
  • $文字列の末尾。'+123456789 XX'などの文字列を避けるため

正規表現を使用しない別の方法は次のとおりです。

where not (
                /* strings of 10-14 chars */
                length(phone_number) between 10 and 14 
                /* ... whose first is a + */
            and substr(phone_number, 1, 1 ) = '+' 
                /* ...and that become a '+' after removing all the digits */
            and nvl(translate(phone_number, 'X0123456789', 'X'), '+') = '+' 
          )

これは、より多くの条件に基づいている場合でも、正規表現アプローチよりも速くなる可能性がありますが、どのテストが最もパフォーマンスが良いかをテストで判断できると思います。

19
Aleksej