« Mac De Oracle Heterogeneous! #77 | トップページ | Mac De Oracle Heterogeneous! #79 »

2006年3月27日 (月) / Author : Hiroshi Sekiguchi.

Mac De Oracle Heterogeneous! #78

前回のつづき。Generic Connectivyty経由でMySQL4.1.13aの文字型にアクセス。八回目。

LONG型にマッピングされた列を問い合わせることができない! という挙動の調査#2

これまではDMLやDDLを利用してどの型にマッピングされているかを確認してきた。理由は、実際に問合せや更新が可能なのかという点も同時に確かめたかったからなのだが、データディクショナリを参照し、どの型にマッピングされているのか再確認してみることにした。

Generic Connectivityでも異機種データベース側のいくつかのディクショナリがマッピングされており、Oracleの user_tablesビューや、user_tab_columnsビューとして問い合わせることができる。
(尚、Genenric Connectivity経由で、利用できるディクショナリの解説は、マニュアル「Oracle Database Heterogeneous Connectivity 管理者ガイド」の付録Cを参照のこと。

ただ、今回は以下ようにな特殊な構成であるため、

gencon_blog_img1

各データディクショナリ毎にシノニムを作成しなければ、MacOSX上のOracle10gからそれらのディクショナリを参照することはできない。
(単に面倒だったからとうこともあるのだが)今回は、Window XP上のOracle10g上で各リモート表のシノニムに対して sql*plusの descコマンドで確認した。

以下、ディクショナリを確認した結果の型を見て、驚いたのだが、文字セマンティクスでマッピングされている箇所がある。MySQL4.0.25はバイトセマンティクスであるが、一部の型は、文字セマンティクスとしてマッピングされている。明らかに、これはまずいはず。

たとえば、 MySQL4.1.13aで、varchar(20)として定義した列は、VARCHAR2(40)とバイトセマンティクスでマッピングされているのだが、varchar(255)と定義してある列は、VARCHAR2(32256 CHAR)と文字セマンティクスでマッピングされていたのだ。
しかも、文字数も255でななく、32256なのである。

char(n)の nの値と文字セマンティクスか否かでキッチリ判断しているのかと考えていたのだが、それは”甘い”考えだったことに気付く。


SQL> desc varchar_test_mysql4113a_mac_sv;
名前 NULL? 型
----------------------------------------- -------- ----------------------------
id NOT NULL NUMBER(10)
r_varchar_20 VARCHAR2(40)
r_varchar_20_binary VARCHAR2(40)
r_varchar_255 VARCHAR2(32256 CHAR)
r_varchar_255_binary VARCHAR2(32256 CHAR)
r_tinytext LONG
r_tinyblob LONG RAW
r_text LONG
r_blob LONG RAW
r_varchar_256 LONG

マッピングを制御するようなパラメータは存在しないため、バイトセマンティクスになるのか、文字セマンティクスにマッピングするかを制御することはできない。

char_test_mysql4113a_mac_svというシノニムに対応するリモート表において、r_char_127は CHAR(127)、r_char_128は CHAR(128)と定義してあるのだが、Generic Connectivity経由でOracleにマッピングされた結果は、ご覧の通り。MySQL4.1.13aの r_char_127は、CHAR(32256 CHAR)と文字セマンティクス、 r_char_128は、VHARCHAR2(256)とバイトセマンティクスとなっている。

一方、PostgreSQL7.4.9の r_char_127 は、CHAR(127)、r_char_128 は、CHAR(128) と定義されているが、Generic Connectivity経由でOracleの型にマッピングされ、r_char_127は、CHAR(127)とバイトセマンティクス、r_char_128は、CHAR(128 CHAR)と文字セマンティクスとしてマッピングされてしまう。

Generic Connectity経由でアクセスする場合の一番の難所は数値型よりも、文字型のほうかもしれない。
256バイト未満の文字列しか扱っていない場合には、それほど気にしなくとも利用できる可能性は高いと思うが、それを超えるサイズを扱う場合(データベースのキャラクタセットも影響する)や、text型や、blob型を利用する場合には、事前に十分な評価テストは必須である。
(Oracle社とのサポート契約があれば、サポート等から関連する情報を入手したほうが良いだろう。開発コストや、運用保守コストなどを考えれば、Generic Connectivityより、Oracleに移行したほうがベターという結論になる場合もあるだろう。)


SQL> desc char_test_mysql4113a_mac_sv
名前 NULL? 型
----------------------------------------- -------- ----------------------------
id NOT NULL NUMBER(10)
r_char_20 CHAR(40)
r_char_20_binary CHAR(40)
r_char_255 VARCHAR2(32256 CHAR)
r_char_255_binary VARCHAR2(32256 CHAR)
r_char_127 CHAR(32256 CHAR)
r_char_128 VARCHAR2(256)

SQL> desc varchar_test_mysql4025_mac
名前 NULL? 型
----------------------------------------- -------- ----------------------------
id NOT NULL NUMBER(10)
r_varchar_20 VARCHAR2(20)
r_varchar_20_binary VARCHAR2(20)
r_varchar_255 VARCHAR2(32512 CHAR)
r_varchar_255_binary VARCHAR2(32512 CHAR)
r_tinytext LONG
r_tinyblob LONG RAW
r_text LONG
r_blob LONG RAW

SQL> desc char_test_mysql4025_mac
名前 NULL? 型
----------------------------------------- -------- ----------------------------
id NOT NULL NUMBER(10)
r_char_20 CHAR(20)
r_char_20_binary CHAR(20)
r_char_255 CHAR(32512 CHAR)
r_char_255_binary CHAR(32512 CHAR)

SQL> desc char_test_postgresql749_mac
名前 NULL? 型
----------------------------------------- -------- ----------------------------
id NUMBER(10)
r_char_20 CHAR(20)
r_char_2000 VARCHAR2(20480 CHAR)
r_char_2001 VARCHAR2(20736 CHAR)
r_varchar_20 VARCHAR2(20)
r_varchar_4000 VARCHAR2(8192 CHAR)
r_varchar_4001 LONG
r_text LONG
r_char_254 CHAR(32256 CHAR)
r_char_255 CHAR(32512 CHAR)
r_char_127 CHAR(127) 
r_char_128 CHAR(128 CHAR)
r_char_256 VARCHAR2(256)  

ところで、MySQLでは、LONGまたは、LONG RAW型にマッピングされていた列は全く問い合わせることができなかったのだが、PostgreSQLでは問い合わせることができる。

問題は、ODBC Driverなのかもしれないと疑い始めたのだが、Generic Connectivity側に何らかの問題があるという可能性を否定できる情報もない。。。

以下は、PostgreSQLで Generic Connectivity経由で long型にマッピングされる r_text列を問い合わせた結果(MySQLの場合と明らかに違う)


CORYDORAS> col r_text for a40
CORYDORAS> col r_varchar_4001 for a40
CORYDORAS> set linesize 132
CORYDORAS> set null "null"
CORYDORAS> l
1 select
2 "id","r_text","r_varchar_4001"
3 from
4 char_test_postgresql749_mac@oracle10g_win
5 where
6* "id" between 30 and 33

CORYDORAS> /

id r_text r_varchar_4001
---------- ---------------------------------------- ----------------------------------------
30 null null
31 null null
32 12345678901234567890 null
33 12345678901234567890 null

CORYDORAS>

今日はここまで、次回へづづく。

MySQL4.0.x、MySQL4.1.x、PostgreSQL7.4.9の基本的な型をGeneric Connecvitiy経由で Oracleかアクセスするというネタも、次回で一旦終了する。また確認したいことがあれば再開する予定である。

| |

トラックバック


この記事へのトラックバック一覧です: Mac De Oracle Heterogeneous! #78:

コメント

コメントを書く