2012-02-10 4 views
0

私は、私が取り組んできたアプリケーションを今夜見つけました。クエリが作られますが、問題を示している。バージョン間で異なるPostgreSQL正規表現

select 
    '123' ~ '^\d+$' as result_1, 
    '123' ~ '^[0-9]+$' as result_2 

私は、Windows 7上で稼動しているPostgreSQL V9.1を持っていると私は私が手にこのクエリを実行します。

をT、T

私はUbuntuの10.04でのPostgreSQL V9.0上のクエリを実行すると

はしかし、私が取得:

F、T

PostgreSQLは、 "\ d"の扱いでv9.0とv9.1の間で変更されたか、WindowsとUbuntuの間にインストールされたlibsの違いがあります。

いずれにしても、あなたのチェック制約などが2つの間で同じように動作しない可能性があると私は思っています(私は確かにそうしませんでした)。

注:残念ながら、私は9.0を実行しているWindows 7ボックスに簡単にアクセスできないし、そこでもテストします。

誰でもこれを説明できますか?それがよくわかっているなら、私を許してください。私はそれをgoogledときに私は答えを見ていない。明らかに安全なことは、両方の場所で動作するので[0-9]だけを使用することです。しかし、再び、私はなぜこれが起こっているのか知りたいと思います。

答えて

2

あなたはエスケープ問題があります。 fine 9.1 manual on string quotingから:

設定パラメータstandard_conforming_stringsはオフになっている場合は、PostgreSQLはバックスラッシュは通常の文字列定数を逃れるの両方でエスケープ認識しています。しかし、PostgreSQL 9.1以降、デフォルトはオンです。つまり、バックスラッシュエスケープはエスケープ文字列定数でのみ認識されます。

so 9.1は'\d'と同じ方法で、'd'のように見えます。 9.1では、あなたのバックスラッシュをエスケープしてE''standard_conforming_strings過去取得するには、文字列表記を「エスケープ」を使用したいと思います:

select 
    '123' ~ E'^\\d+$' as result_1, 
    '123' ~ '^[0-9]+$' as result_2 

それともdollar quotingを試みることができる:

select 
    '123' ~ $re$^\d+$$re$ as result_1, 
    '123' ~ '^[0-9]+$' as result_2 

が、それはかなり醜いと難しいです正規表現(特に末尾を固定するのに$を使用する正規表現)で読むこと。、あなたにも以前のバージョンで'\d'に関する警告を見てきたはずです

select 
    '123' ~ '^[[:digit:]]+$' as result_1, 
    '123' ~ '^[0-9]+$' as result_2 

このようなもののためにあなたのログを確認します:

別のオプションではなく\dPOSIX character classを用いることであろう

WARNING: nonstandard use of escape in a string literal 
LINE 1: select '\d'; 
      ^
HINT: Use the escape string syntax for escapes, e.g., E'\r\n'. 
+0

ありがとう!素晴らしい答えと説明。私は '123'〜E '^ \\ d + $'をresult_1としてテストしました.WindowsとLinuxの両方、そして9.0と9.1の両方で動作します。 –