2012-02-21 20 views
2

文字コードがUTF-8であることを確認して文字コードをシステムに誤って読み込む問題を修正しました。 UTF-8エンコーディングのファイル。データベース全体で文字化けした文字 ` `を検索しています - Oracle

しかし、°Fは、�Fと読み込まれた不正な文字が挿入されたデータベーステーブル全体で多くのレコードを追加してしまいました。この問題を修正したにもかかわらず、この異常を修正するために今データベーステーブルを整理する必要があります。

誰でも私にこれを達成する方法を提案できますか?

+2

をあなたは '<<いくつかの条件は、問題のデータを示し<

> FROMダンプ(<>を、1016年)を選択した場合>>) 'あなたが知っている1つのテーブルの1つの行に問題がありますが、どのバイナリ値が問題の文字として格納されていますか?あなたが認識しているいくつかの異なるケースでテストを繰り返すと、文字は特定のバイナリ値で一貫して表現されていますか? –

+0

これは必ずしも文字化けしているとは限りません。その文字を表示するフォントが不足している可能性があります。 – Arafangion

+0

@Arafangion:そうは間違いありません。私が言ったように、修正が行われ、新しい着信レコードに対して特殊文字を完全に見ることができます。 –

答えて

1

私は同じような問題を抱えていました。幸いにも、影響を受けた列の数は少数に制限されていて、それらの列はデータベース全体で同じ名前でした。

私は次のないスクリプトを書くことで、これを解決:

  1. 無効に外部キー制約
  2. あなたのすべてのテーブルを更新 ターゲット列
  3. が含まれているテーブルのリストを構築 REGEXP_REPLACE
  4. を使用して、リストには、データが制約を再度有効にコミット

これは、適切な動的SQLを使用して、user_constraintsuser_tab_columnsのデータを取得し、対象の特定の列名をフィルタリングしました。

ここでは、開始するための基本的なスケルトンがありますが、すぐに一緒にスローしたため、テストされていません。あなたが心配するトリガを持っている場合にも、あなたも、それらを無効にする必要があります:

-- disable constraints 
BEGIN 
    FOR c IN (
     SELECT c.owner, c.table_name, c.constraint_name, c.constraint_type 
     FROM user_constraints c 
     INNER JOIN user_tables t ON (t.table_name = c.table_name) 
     AND c.status = 'ENABLED' 
     AND c.constraint_type NOT IN ('C', 'P') 
     ORDER BY c.constraint_type DESC 
    ) 
    LOOP 
     dbms_utility.exec_ddl_statement('alter table '||c.table_name||' disable constraint ' || c.constraint_name); 
    END LOOP; 
END; 

-- do the updates 
BEGIN 
    FOR t IN (
     SELECT table_name, column_name 
     FROM user_tab_columns 
     WHERE column_name = 'TEMPERATURE' 
     AND data_type = 'VARCHAR2'; 
    ) 
    LOOP 
     dbms_utility.exec_ddl_statement('UPDATE '||t.table_name||' SET ' ||t.column_name||' = '||''GOOD VALUE''||' WHERE '||t.column_name||' = '||''BAD VALUE''); 
    END LOOP; 
END; 

-- re-enable constraints 
BEGIN 
    FOR c IN (
     SELECT c.owner, c.table_name, c.constraint_name, c.constraint_type 
     FROM user_constraints c 
     INNER JOIN user_tables t ON (t.table_name = c.table_name) 
     AND c.status = 'DISABLED' 
     AND c.constraint_type NOT IN ('C', 'P') 
     ORDER BY c.constraint_type ASC 
    ) 
    LOOP 
     dbms_utility.exec_ddl_statement('alter table '||c.table_name||' enable constraint ' || c.constraint_name); 
    END LOOP; 
END; 
/
+1

'REGEXP_REPLACEを使用してリスト内のすべてのテーブルを更新すると、 ' 'charは特定の文字ではなく無効なコードのプレゼンテーションであるため、これらのシンボルをすべて見つけるのは少し難しくなります – zerkms

+0

@zerkmsどのようにデータが最初の場所で文字化けするようになったのか。 *は、Unicodeプロセッサによって無効なバイトシーケンスの代わりに使用される文字U + FFFD、 "置換文字"です。したがって、Javaがインポートを不正にすると、Javaがそこに置くので、 がデータベースの文字として保存される可能性があります。データがバイナリデータとしてデータベースに挿入され、出力のねじだけが差し込まれていた場合、それは異なるでしょう。 – deceze

+0

あなたが壊れていると分かっている行を見つけて、ターゲット列で 'DUMP'関数を使用してください。これはあなたが探している 'CHAR'コードを与えます。 – ninesided

関連する問題