web-dev-qa-db-ja.com

DB2で特殊文字を見つける方法は?

何百万ものレコードを含むDB2データベースがあります。一部のchar()またはvarchar()フィールドに、格納してはならない特殊文字が含まれていることがわかりました。アプリケーションが壊れたデータを受け取ったか、いくつかのコードがそれを作ったと思います。

とにかく、特殊文字(アルファベットではない)であるこれらの壊れたデータを持つレコードを見つけたいと思います。

クエリを使用して方法を見つけようとしましたが、見つかりませんでした。誰かが良い質問やアドバイスを知っていますか?

6
nick

DB2 TRANSLATE()関数を使用して、英数字以外の文字を分離できます。これは、Oracle互換モードでは機能しないことに注意してください。その場合、DB2はOracleと同様に、空の文字列をNULLとして扱います。

SELECT *
FROM yourtable
WHERE LENGTH(TRANSLATE(
  yourcolumn,
  '', -- empty string
  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
)) > 0 -- after translating ASCII characters to empty strings 
       -- there's still something left
15
mustaccio

私はこれが古いスレッドであることを知っています...しかし、トンを読んだ後...これは私の正確な問題であり、問​​題の行を特定するために私が思いついた解決策です...私が入って手動でそれらを修正できるように。参考までに-ユーザーがWordからアプリにコピー/貼り付けしているため、問題が発生します。はい、保存する前に修正する必要があることはわかっています...しかし、揚げる魚はもっと大きいです。

SELECT * FROM TABLE_A where ASCII(TRIM(TRANSLATE( COLUMN_A, ' ', -- empty string '()<>!;%$#*?@+&^=-":/''.,0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ))) not in (10,64)

いくつかのメモ:

  • 私たちはiSeriesDB2を使用しており、これはうまく機能します
  • 翻訳機能では、すべてのスペースをそのままにしておくようにしてください...使用する文字ごとに1つのスペースが必要です
  • Translate関数の3番目のパラメーターには、2つの一重引用符が隣り合っており、最初の引用符は単に他の引用符をエスケープします(知らない人のために)
7
user4342423

特殊文字が印刷不可能な文字を意味する場合は、次の文字を使用できます。

_select yourfield, hex(trim(yourfield)),TRANSLATE(
  yourfield,
  ' ', 
  x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
from yourtable
where yourfield <> TRANSLATE(
  yourfield,
  ' ', 
  x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
_

奇数文字HEX()が40未満であることがわかるでしょう。

とにかく、奇数/特殊文字のHEX()を知っている場合は、このアプローチを使用して、スペースまたは永続的に必要なものに置き換えることができます。

_Update yourtable
set yourfield= Translate(yourfield, 
                            ' ', 
                            x'000102030405060708090A0B0C0D0E101112131415161718191A1B1C1D1E202122232425262728292A2B2C2D2E303132333435363738393A3B3C3D3E0F1F2F3F')
where yourfield <> Translate(yourfield, 
                            ' ', 
                            x'000102030405060708090A0B0C0D0E101112131415161718191A1B1C1D1E202122232425262728292A2B2C2D2E303132333435363738393A3B3C3D3E0F1F2F3F')
_
2
gugol

無効な文字を取得するために正規表現を使用できます。ただし、このプロセスは、すべてのデータを読み取ってから処理する必要があるため、非常にコストがかかります。

DB2で正規表現を使用するには、環境を適合させる必要があります。これは、この機能がインストールのSQLでは使用できないためです。次の3つのオプションがあります。

有効な文字(/[^a-zA-Z0-9]/など)を無視する正規表現を定義したら、データベースで実行できます。行を検出できる他の列(列IDなど)を取得してから、更新を実行するか、無効な文字を削除するために削除することを忘れないでください。

正規表現の使用方法がわからない場合は、ここに優れた情報源があります: http://www.regular-expressions.info/ 特に http:// www。正規表現.info/charclass.html

正規表現に関する関連する質問があります: DB2 SQLの正規表現

2
AngocA