Oracle DBLINKをコピーするときにChar(1)がChar(3)に変わるのはなぜですか?

StackOverflow https://stackoverflow.com/questions/253971

  •  05-07-2019
  •  | 
  •  

質問

2つのデータベースがあり、 CHAR列を含む既存のテーブルをデータベースAからデータベースBに転送します。

データベースAはOracle 9iであり、エンコーディングWE8ISO8859P1があり、テーブル" foo"が含まれています。 CHAR(1 char)型の列が少なくとも1つある。データベースAのテーブルは、サードパーティのセットアップの一部であるため変更できません。

データベースBは、あらゆる種類の理由でAL32UTF8エンコーディングを使用する独自のOracle 10gデータベースであり、fooをこのデータベースにコピーしたいです。

データベースBからデータベースAへのデータベースリンクを設定します。次に、次のコマンドを発行します。

* select#from#link#.foo; *

としてテーブルバーを作成します

データはうまくコピーされますが、列のタイプを確認すると、CHAR(1 char)がCHAR(3 char)に変換されていることがわかります。データベースBのデータを照会すると、すべてスペースで埋めます。

水中のどこかで、Oracleはそれ自身のバイトと文字を混同していると思います。 CHAR(1 byte)はCHAR(1 char)などとは異なります。それについてすべて読みました。

データ型がパディングされたCHAR(3文字)に変更されるのはなぜですか。Oracleがこれを実行しないようにするにはどうすればよいですか

編集:Oracle 9と10の2つの特定のパッチレベル間でCHARを転送することに関係しているようです。これは本当にバグのようです。判明次第、アップデートを投稿します。一方、私が説明したように、CHARをデータベース間で移動しようとしないでください。 VARCHAR2は正常に動作します(テスト済み)。

編集2:答えを見つけてここに投稿しました: Oracle DBLINKをコピーするときにChar(1)がChar(3)に変わるのはなぜですか? 問題が解決したため、自分の答えを受け入れることができません。

役に立ちましたか?

解決

この問題は、Oracleが元の列の長さの定義に基づいて異なる文字セット間の文字変換を処理する方法が原因です。文字型の列のサイズをバイト単位で定義すると、Oracleは変換の方法を認識せず、変換します。 解決策は、文字タイプの長さを常に文字で定義することです

問題の詳細な説明と、これをどのように理解したかについては、 http://www.rolfje.com / 2008/11/04 / transporting-oracle-chars-over-a-dblink /

他のヒント

YOuは、WE8ISO8859P1 NLS(1バイトに文字を格納する)と、最大4バイトに文字を格納するAL32UTF8の違いを学習する必要があります。 Oracle National Language Support(NLS)ドキュメント。 Oracleは、役立つように、データベースリンクを介して自動的に変換を行います。

SQLプロンプトから次を試してください:

ALTER SESSION NLS_NCHAR WE8ISO8859P1 
create table bar as select * from #link#.foo;

最初に試すことは、CTASとしてではなく、列定義のリストを使用してテーブルを作成し、最初の数千行の挿入を実行することです。それが成功しなかった場合、その理由は非常に明確です...そして、トーマス・ローが正確に死んでいることをすぐに確認できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top