2008年10月 1日 (水)

さて・・

Oracle11gMySQL5.0PostgreSQL8.3、(FireBird2.1もやるか)、それにOpenfiler2.3なども利用して旧リリースで試していたことを再度試しておこうかそろそろ。
たとえば、HeterogeneousRACのネタなど。まず、RACからやりますか..。

| | コメント (0) | トラックバック (0)

2006年5月27日 (土)

Mac De Mac De Oracle Heterogeneous! #80

久々のGeneric Connectivityネタです

今回は、Firebird 1.5と Heterogeneous! 。 ただ、ODBCドライバに影響されやすい
Generic Connectivityなので、Firebird_ODBC_1.2.0.69-Win32だと問題があるようだ。

踏み台にするWindowsには、Oracle10g EE R2を利用した。前回までは、Oracle10g EE R1。

踏み台側の環境は以下。
Windows XP Professional SP2
  Firebird V1.5.3.4870 for Windows
  Firebird_ODBC_1.2.0.69-Win32
 
  Oracle10g EE R2 10.2.0.1.0 for Windows

Mac側は以前の記事を参考にしてほしい。

1.ODBC

システムDSN
DSN:
firebird_windows

ここがポイント!
For a Windows server:
servername:DriveLetter:¥filesystem-path¥database-file

という形式で指定しないとデータベースを 見つけられない。

以下のようにFirebirdのサンプルデータベースを指定した。
Database:
catfish:C:¥Program Files¥Firebird¥Firebird_1_5¥examples¥EMPLOYEE.FDB

ユーザ名とパスワードはサンプルデータベースのユーザとパスワードを指定した。

Odbc

2. init.ora

initfirebird_windows.ora

#
# HS init parameters
#
HS_FDS_CONNECT_INFO = firebird_windows
HS_FDS_TRACE_LEVEL = off
HS_FDS_SHAREABLE_NAME = C:¥WINNT¥system32¥IscDbc.dll

3.listener.ora

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = E:¥oracle¥product¥10.2.0¥catfish)
(PROGRAM = extproc)
)

(SID_DESC =
(SID_NAME = mysqldb4026_windows)
(ORACLE_HOME = E:¥oracle¥product¥10.2.0¥catfish)
(PROGRAM = hsodbc)
)

(SID_DESC =
(SID_NAME = firebird_windows)
(ORACLE_HOME = E:¥oracle¥product¥10.2.0¥catfish)

(PROGRAM = hsodbc)
)
)

LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
(ADDRESS = (PROTOCOL = TCP)(HOST = catfish)(PORT = 1521))
)
)

4.tnsnames.ora

FIREBIRD_WIN =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = catfish)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = firebird_windows)
)
(HS = OK)
)

MYSQL4026_WIN =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = catfish)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = mysql4026_windows)
)
(HS = OK)
)

5. SQL*Plusから

以下のデータベースリンクを作成(パブリックデータベースリンクでもOK)
create database link firebird_win
connect to "SYSDBA" identified by "masterkey" using 'FIREBIRD_WIN';

Oracle10g R1では、指定したデータベースリンク名に一致する
データベースリンク名を作成することができたのだが、
Oracle10g R2では、.REGRESS.RDBMS.DEV.US.ORACLE.COMという
ドメイン名がご丁寧に付加される。(悪さはしていない模様。)

SQL> select db_link from user_db_links;

DB_LINK
---------------------------------------------------
FIREBIRD_WIN.REGRESS.RDBMS.DEV.US.ORACLE.COM
MYSQL4026_WIN.REGRESS.RDBMS.DEV.US.ORACLE.COM

SQL>

ディクショナリビューは問題なく問い合わせられる。が・・・

SQL> select table_name from user_tables@firebird_win;

TABLE_NAME
--------------------------------------------------------------

RDB$CHARACTER_SETS
RDB$CHECK_CONSTRAINTS
RDB$COLLATIONS
RDB$DATABASE

中略

DEPARTMENT
EMP
EMPLOYEE
EMPLOYEE_PROJECT
FISHES
JOB
PROJECT
PROJ_DEPT_BUDGET
SALARY_HISTORY
SALES

44行が選択されました。

SQL>
SQL>

一般の表では、文字型の表示がだめ。
(エンコーディング関連で逃げられるものなのか・・・???)

ODBCドライバ側の問題なのだろうかね。(可能性としては高そう)

SQL> select * from "FISHES"@firebird_win;

ID NAME
---------- ---------------------------------------------------
1 discus
2 atfish
3 on tetra

SQL>
SQL> insert into "FISHES"@firebird_win values(4,'guppy');

1行が作成されました。

SQL> commit;

コミットが完了しました。

SQL> select * from "FISHES"@firebird_win;

ID NAME
---------- -----------------------------------------------------------
1 discus
2 atfish
3 on tetragu
4 py

SQL>

Firebirdの isqlから fishes表を問合せた結果をみると
Oracle側から insertしたデータでも正しく問い合わせられる。

SQL> select * from fishes;

ID NAME
============ ==========

1 discus
2 catfish
3 neon tetra
4 guppy

SQL>

と現時点ではこんな感じなので、FirebirdとHeterogeneous! ネタはいずれまた。
今回は、Firebird_ODBC_1.2.0.69-Win32 というODBCドライバを利用したが
v2.0のODBCドライバもリリースされているようなので時間があったら 
ODBCドライバ v2.0でも試してみましょうかね。

尚、この内容は OTN-Jの掲示板FirebirdへのODBC接続に投稿したものとほぼ同じ内容です。 

| | コメント (0) | トラックバック (0)

2006年3月28日 (火)

Mac De Oracle Heterogeneous! #79

前回のつづき
Generic Connectivyty経由でMySQL4.0.x、MySQL4.1.13aの文字型にアクセス最終回

この検証でそれなりにネタは仕入れる事ができたので、この辺りでGeneric Connectivityは一旦終了する。

=========まとめ=======

利用している MyODBCドライバなどはこちら

Generic Connectivityの文字型マッピング
MySQL Oracle10g R1 Generic Connectivityでの利用 備 考
サイズ binary属性 文字長セマンティクス version サイズ 文字長セマンティクス
char型 20 -- バイト 4.0.25 char型 20 バイト

問合せ、登録、更新とも問題ないのだが、MySQL側でbinary属性が指定されていない場合には、DMLの書き方により、リモートソートが実行され、英字の大文字小文字が区別されなかったり、nullや空文字は、昇順ソートの場合先頭に置かれる。検証では、リモートマップされるクエリをインラインビューに書き換え、そのインラインビューに対して、NO_MERGEヒントを付加することで回避することができた。Oracleは空文字をnullとして扱うので、その点には注意。

定義したサイズを超える文字列を登録した場合には、エラーとなる。但し、char(20)まででしか確認していない。データディクショナリで確認したところ、char(255)では、MySQL側がバイトセマンティクスであるはずなのに、Oracle側では文字セマンティクスで、32512文字とマッピングされている。今回の検証ではこの件については深く検証していないので要注意。

binary バイト
255 -- バイト 32512 文字
binary 文字
20 -- 文字 4.1.13a char型 40 バイト

問合せ、登録、更新とも問題ないのだが、MySQL側でbinary属性が指定されていない場合には、DMLの書き方により、リモートソートが実行され、英字の大文字小文字が区別されなかったり、nullや空文字は、昇順ソートの場合先頭に置かれる。検証では、リモートマップされるクエリをインラインビューに書き換え、そのインラインビューに対して、NO_MERGEヒントを付加することで回避することができた。Oracleは空文字をnullとして扱うので、その点には注意。

定義したサイズを超える文字列を登録した場合には、エラーとなる。但し、char(20)まででしか確認していない。データディクショナリで確認したところ、char(255)では、MySQL側がバイトセマンティクスであるはずなのに、Oracle側では文字セマンティクスで、32256文字とマッピングされ、MySQL4.0.25の場合とより多少少ない。今回の検証ではこの件については深く検証していないので要注意。

binary バイト
255 -- 文字 varchar2型 32256 文字
binary 文字
127 -- 文字 char型 32256 文字

char(127)はSJISで254バイトのchar(254)でなく、なんと、char(32256 char)としてマッピングされている。登録に関しては未テスト。

128 -- 文字 varchar2型 256 バイト char(255)とchar(128)の差からは想像できない、varchar2(32256 char)とvarchar2(256)というマッピングの差があるので要注意。
varchar型 20 -- バイト 4.0.25 varchar2型 20 バイト

問合せ、登録、更新とも問題ないのだが、MySQL側でbinary属性が指定されていない場合には、DMLの書き方により、リモートソートが実行され、英字の大文字小文字が区別されなかったり、nullや空文字は、昇順ソートの場合先頭に置かれる。検証では、リモートマップされるクエリをインラインビューに書き換え、そのインラインビューに対して、NO_MERGEヒントを付加することで回避することができた。Oracleは空文字をnullとして扱うので、その点には注意。

定義したサイズを超える文字列を登録した場合には、エラーとなる。但し、varchar(20)まででしか確認していない。データディクショナリで確認したところ、varchar(255)では、MySQL側がバイトセマンティクスであるはずなのに、Oracle側では文字セマンティクスで、32512文字とマッピングされている。今回の検証ではこの件については深く検証していないので要注意。

binary バイト
255 -- バイト varchar2型 32512 文字
binary 文字
20 -- 文字 4.1.13a varchar2型 40 バイト

問合せ、登録、更新とも問題ないのだが、MySQL側でbinary属性が指定されていない場合には、DMLの書き方により、リモートソートが実行され、英字の大文字小文字が区別されなかったり、nullや空文字は、昇順ソートの場合先頭に置かれる。検証では、リモートマップされるクエリをインラインビューに書き換え、そのインラインビューに対して、NO_MERGEヒントを付加することで回避することができた。Oracleは空文字をnullとして扱うので、その点には注意。

定義したサイズを超える文字列を登録した場合には、エラーとなる。但し、varchar(20)まででしか確認していない。データディクショナリで確認したところ、varchar(255)では、MySQL側がバイトセマンティクスであるはずなのに、Oracle側では文字セマンティクスで、32256文字とマッピングされ、MySQL4.0.25の場合とより多少少ない。今回の検証ではこの件については深く検証していないので要注意。

binary バイト
255 -- 文字 varchar2型 32256 文字
binary
256 -- 文字 long型 -- バイト × varchar(256)を超えるとlong型にマッピングされてしまうので、tinytext型、text型と同じ扱いになる。binary属性が付いていれば、tinyblob型やblob型と同じ扱いになる。
tinytext型 -- -- バイト 4.0.25 long型 -- バイト × tinytext型の最大サイズは255バイト。登録、更新は可能なのだが、long型にマッピングされているためほとんどの関数は利用できない。ソートは未確認だが、binary属性の無いchar型又は、varchar型と同じであると考えている。また、問合せについて、この検証ではまったく問い合わせることができなかったため、Generic Connectivity経由での利用は諦めたほうがよいと思われる。(ODBCドライバなどを替えれば動作する可能せもあるだろうが、その検証にかかるコストも考慮する必要あり。)Oracleは空文字をnullとして扱うので注意。
-- -- バイト 4.1.13a long型 -- バイト
tinyblob型 -- -- バイト 4.0.25 long raw型 -- バイト × tinyblob型の最大サイズは255バイト。登録、更新は可能なのだが、long raw型にマッピングされているためほとんどの関数は利用できない。ソートは未確認だが、binary属性のchar型又は、varchar型と同じであると考えている。また、問合せに関して、この検証ではまったく問い合わせることができなかったため、Generic Connectivity経由での利用は諦めたほうがよいと思われる。(ODBCドライバなどを替えれば動作する可能せもあるだろうが、その検証にかかるコストも考慮する必要あり。)Oracleは空文字をnullとして扱うので注意。
-- -- バイト 4.1.13a long raw型 -- バイト
text型 -- -- バイト 4.0.25 long型 -- バイト × text型の最大サイズは65535バイト。登録、更新は可能なのだが、long型にマッピングされているためほとんどの関数は利用できない。ソートは未確認だが、binary属性の無いchar型又は、varchar型と同じであると考えている。また、問合せに関しては、この検証ではまったく問い合わせることができなかったため、Generic Connectivity経由での利用は諦めたほうがよいと思われる。(ODBCドライバなどを替えれば動作する可能せもあるだろうが、その検証にかかるコストも考慮する必要あり。)Oracleは空文字をnullとして扱うので注意。
-- -- バイト 4.1.13a long型 -- バイト
blob型 -- -- バイト 4.0.25 long raw型 -- バイト × blob型の最大サイズは65535バイト。登録、更新は可能なのだが、long raw型にマッピングされているためほとんどの関数は利用できない。ソートは未確認だが、binary属性のchar型又は、varchar型と同じであると考えている。また、問合せに関しては、この検証ではまったく問い合わせることができなかったため、Generic Connectivity経由での利用は諦めたほうがよいと思われる。(ODBCドライバなどを替えれば動作する可能せもあるだろうが、その検証にかかるコストも考慮する必要あり。)Oracleは空文字をnullとして扱うので注意。
-- -- バイト 4.1.13a long raw型 -- バイト


さて、久々にGeneric Connectivity以外のネタにしますかね。次回からは。

| | コメント (0) | トラックバック (0)

2006年3月27日 (月)

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かアクセスするというネタも、次回で一旦終了する。また確認したいことがあれば再開する予定である。

| | コメント (0) | トラックバック (0)

2006年3月26日 (日)

Mac De Oracle Heterogeneous! #77

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

LONG型にマッピングされた列を問い合わせることができない!

7.TINYTEXT型、TINYBLOB型、TEXT型、BLOB型(追加検証)

以前簡単に触れた事なのだが、TINYTEXT型、TINYBLOB型、TEXT型、BLOB型は、 Generic Connectivity経由で、OracleのLONG型にマッピングされていると判断したのは以下のような結果からだった。
この判断間違っていたのか?・・・。


CORYDORAS> l
1* create table hoge as select "id","r_blob" from varchar_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /
create table hoge as select "id","r_blob" from varchar_test_mysql4113a_mac_sv@oracle10g_win
*
行1でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS> l
1* create table hoge as select "id","r_tinytext" from varchar_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /
create table hoge as select "id","r_tinytext" from varchar_test_mysql4113a_mac_sv@oracle10g_win
*
行1でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS> l
1* create table hoge as select "id","r_tinyblob" from varchar_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /
create table hoge as select "id","r_tinyblob" from varchar_test_mysql4113a_mac_sv@oracle10g_win
*
行1でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS>

OracleのLONG型にマッピングされている、TINYTEXT型、TINYBLOB型、TEXT型、BLOB型の列には、Generic Connectivity経由でデータ登録可能なのだが、

OracleのLONG型にマッピングされている関係でほとんどのスカラ関数は利用できない。

さらに、MySQL4.0.25、MySQL4.1.13aともLONG型にマッピングされたデータを問い合わせることが出来ないという現象に遭遇してしまったのだ。(これはまずい)
LONG型ならば問い合わせることができるはずなのだが、TINYTEXT型、TINYBLOB型、TEXT型、BLOB型の単純なクエリ全てがエラーとなってしまうのだ。
以下の結果を観る限り、シンタックスエラーが返されているためGeneric Connectivity経由でリモートサイトに割り振っているSQL文がまずいのかもしれない。(MyODBCの問題なのか、OracleのGeneric Connectivityの問題なのか? いずれにしても、SQLが多少書き換えられているのは間違いないので、書き換えるための元の情報が間違っているのか、書き換える処理に問題があるのかのいずれかということになる。)


CORYDORAS> select "r_tinytext" from varchar_test_mysql4113a_mac_sv@oracle10g_win;
ERROR:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][MySQL][ODBC 3.51 Driver][mysqld-4.1.13a]You
have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near '"varchar_test" WHERE
"id"=1' at line 1 (SQL State: 37000; SQL Code: 1064)
ORA-02063: 先行のエラー・メッセージを参照してください2
lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

レコードが選択されませんでした。

前述のクエリに、条件を加えてみたところ興味深いエラーが返された。
The column 'A1.r_tinytext' is a chapter or a BLOB という部分である。
BLOBにマッピングされているのか?? と疑心暗鬼。 


CORYDORAS> l
1 select "r_tinytext" from varchar_test_mysql4113a_mac_sv@oracle10g_win
2* where "r_tinytext" = ''
CORYDORAS> /
select "r_tinytext" from varchar_test_mysql4113a_mac_sv@oracle10g_win
*
行1でエラーが発生しました。:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A03C] The column 'A1.r_tinytext' is a chapter
or a BLOB, it can't be used in expressions, ORDER/GROUP BY clause or DISTINCT
query
ORA-02063: 先行のエラー・メッセージを参照してください2
lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS>

どの型にマップされているのかを再確認した。
MySQL側で、TINYTEXT型だけの列を持つ表を作成しデータを登録しておく。(一意性制約や、主キー制約も付加していない点に注目)
次に、Generic Connectivity経由で該当する列を問い合わせてみると、やはりエラーになる。


mysql> create table hoge (test_tinytext tinytext);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into hoge values('あいう');
Query OK, 1 row affected (0.01 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from hoge;
+---------------+
| test_tinytext |
+---------------+
| あいう |
+---------------+
1 row in set (0.00 sec)

mysql>

mysql> desc hoge
-> ;
+---------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+----------+------+-----+---------+-------+
| test_tinytext | tinytext | YES | | NULL | |
+---------------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)

Generic Connectivity経由で問い合わせた結果。


CORYDORAS> select "test_tinytext" from hoge_mysql4113a_mac_sv@oracle10g_win;
select "test_tinytext" from hoge_mysql4113a_mac_sv@oracle10g_win
*
行1でエラーが発生しました。:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][D015] The table hoge contains a chapter or a
blob. It must also contain a column with unique index.
ORA-02063: 先行のエラー・メッセージを参照してください2
lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

エラーメッセージに従い、主キー制約を追加してみた。。。


mysql> alter table hoge add column id int primary key;
Query OK, 1 row affected (0.38 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> desc hoge;
+---------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+----------+------+-----+---------+-------+
| test_tinytext | tinytext | YES | | NULL | |
| id | int(11) | | PRI | 0 | |
+---------------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql>
mysql> update hoge set id =1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

Generic Connectivity経由で問い合わせた結果。
主キー制約を追加したのだが、結果はやはりシンタックスエラーとなる。(だめだな、こりゃ)


CORYDORAS> select "id","test_tinytext" from hoge_mysql4113a_mac_sv@oracle10g_win;
ERROR:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][MySQL][ODBC 3.51 Driver][mysqld-4.1.13a]You
have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near '"hoge" WHERE "id"=0' at
line 1 (SQL State: 37000; SQL Code: 1064)
ORA-02063: 先行のエラー・メッセージを参照してください2
lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

LONG型ではなくLOB型にマッピングされているとすれば、主キー制約又一意制約が必要であると、マニュアルに記載されている通りの挙動だとは思うのだが・・・・。(尚、MySQL4.0.25でも同じ結果であった。)

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

| | コメント (0) | トラックバック (0)

2006年3月25日 (土)

Mac De Oracle Heterogeneous! #76

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

6.文字列の登録

char(20)へのデータ登録。特に気になる点はない。


CORYDORAS> insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3 values(300,null);

1行が作成されました。

CORYDORAS> insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3 values(301,'');

1行が作成されました。

CORYDORAS> insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3 values(302,' あ ');

1行が作成されました。

CORYDORAS> insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3 values(303,'12345678901234567890');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3 values(304,'123456789012345678901');

1行が作成されました。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3* values(305,'1234567890123456789012345678901234567890')
CORYDORAS> /

1行が作成されました。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3* values(305,'12345678901234567890123456789012345678901')
CORYDORAS> /
insert into
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_char_20 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS> insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3 values(304,'12345678901234567890');

1行が作成されました。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 insert into
2 char_test_mysql4113a_mac_sv@oracle10g_win("id","r_char_20")
3* values(304,'123456789012345678901')
CORYDORAS> /
insert into
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_char_20 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS>


varchar(20)へのデータ登録。特に気になる点はない。


CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(300,null);

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(301,'');

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(302,' あ ');

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(303,'12345678901234567890');

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(304,'12345678901234567890');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(305,'1234567890123456789012345678901234567890');

1行が作成されました。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2* values(305,'12345678901234567890123456789012345678901')
CORYDORAS> /
insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_varchar_20 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
2 values(306,'123456789012345678901');
insert into varchar_test_mysql4113a_mac_sv@oracle10g_win("id","r_varchar_20")
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_varchar_20 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4113A_MAC_SV)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>


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

| | コメント (0) | トラックバック (0)

2006年3月24日 (金)

Mac De Oracle Heterogeneous! #75

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

5.ソート

MySQL4.0.xの場合と同じデータを登録してある。


CORYDORAS> col hex_sjis for a20
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 dump("r_varchar_20",16) as hex_sjis
5 from
6 varchar_test_mysql4113a_mac_sv@oracle10g_win
7 where
8* "id" between 1 and 18
CORYDORAS> /

id r_varchar_20 HEX_SJIS
---------- ---------------------------------------- --------------------
1 C Typ=1 Len=1: 43
2 c Typ=1 Len=1: 63
3 B Typ=1 Len=1: 42
4 b Typ=1 Len=1: 62
5 A Typ=1 Len=1: 41
6 a Typ=1 Len=1: 61
7 お Typ=1 Len=2: 82,a8
8 え Typ=1 Len=2: 82,a6
9 う Typ=1 Len=2: 82,a4
10 い Typ=1 Len=2: 82,a2
11 あ Typ=1 Len=2: 82,a0
12 ぉ Typ=1 Len=2: 82,a7
13 ぇ Typ=1 Len=2: 82,a5
14 ぅ Typ=1 Len=2: 82,a3
15 ぃ Typ=1 Len=2: 82,a1
16 ぁ Typ=1 Len=2: 82,9f
17 null NULL
18 null NULL

18行が選択されました。

CORYDORAS>

"r_varchar_20"は、binary属性がないため、MySQL側でソート処理が行われるとソート結果が異ってしまうのだが、以下のようにOracle側にしか存在しない関数があることでOracle側でソートされている。

CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 dump("r_varchar_20",16) as hex_sjis
5 from
6 varchar_test_mysql4113a_mac_sv@oracle10g_win
7 where
8 "id" between 1 and 18
9 order by
10* "r_varchar_20"
CORYDORAS> /

id r_varchar_20 HEX_SJIS
---------- ---------------------------------------- --------------------
5 A Typ=1 Len=1: 41
3 B Typ=1 Len=1: 42
1 C Typ=1 Len=1: 43
6 a Typ=1 Len=1: 61
4 b Typ=1 Len=1: 62
2 c Typ=1 Len=1: 63
16 ぁ Typ=1 Len=2: 82,9f
11 あ Typ=1 Len=2: 82,a0
15 ぃ Typ=1 Len=2: 82,a1
10 い Typ=1 Len=2: 82,a2
14 ぅ Typ=1 Len=2: 82,a3
9 う Typ=1 Len=2: 82,a4
13 ぇ Typ=1 Len=2: 82,a5
8 え Typ=1 Len=2: 82,a6
12 ぉ Typ=1 Len=2: 82,a7
7 お Typ=1 Len=2: 82,a8
17 null NULL
18 null NULL

18行が選択されました。

dump()関数を取り去ると、文全てがリモートマップされ、ソート結果もMySQL側のソート結果となってしまう。


CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select
2 "id",
3 "r_varchar_20"
4 from
5 varchar_test_mysql4113a_mac_sv@oracle10g_win
6 where
7 "id" between 1 and 18
8 order by
9* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
17 null
18 null
5 A
6 a
3 B
4 b
1 C
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お

18行が選択されました。

さて、MySQL4.0.25の場合と同様、インラインビューに書き換え、NO_MERGEヒントを追加する。このように書き換えることでリモートソート回避を強制させることが出来る。


CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select *
2 from
3 (
4 select /*+ NO_MERGE */
5 "id",
6 "r_varchar_20"
7 from
8 varchar_test_mysql4113a_mac_sv@oracle10g_win
9 where
10 "id" between 1 and 18
11 )
12 order by
13* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
5 A
3 B
1 C
6 a
4 b
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お
17 null
18 null

18行が選択されました。

オートトレースで実行計画と統計情報を取得してみると、確かにOracle側でソートされている。


CORYDORAS> set null ""
CORYDORAS> set autot on
CORYDORAS> l
1 select *
2 from
3 (
4 select /*+ NO_MERGE */
5 "id",
6 "r_varchar_20"
7 from
8 varchar_test_mysql4113a_mac_sv@oracle10g_win
9 where
10 "id" between 1 and 18
11 )
12 order by
13* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
5 A
3 B
1 C
6 a
4 b
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お
17
18

18行が選択されました。

実行計画
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=53 Card=5 Bytes=275)
1 0 SORT (ORDER BY) (Cost=53 Card=5 Bytes=275)
2 1 VIEW (Cost=52 Card=5 Bytes=275)
3 2 REMOTE* (Cost=52 Card=5 Bytes=275) ORACLE10G_WIN

3 SERIAL_FROM_REMOTE SELECT "id","r_varchar_20" FROM "VARCHAR_TES
T_MYSQL4113A_MAC_SV" "VARCHAR_TEST_M

統計
----------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
812 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
18 rows processed

CORYDORAS>

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

| | コメント (0) | トラックバック (0)

2006年3月23日 (木)

Mac De Oracle Heterogeneous! #74

前回のつづき

4.tinytext型、tinyblob型、text型、blob型

MySQL4.0.xの場合と同様の結果(length関数等が利用できない)であったためlong型にマッピングされていると思っていたのだが、ほんとうにlong型なのか?という挙動に気付いた。その挙動については別途まとめる予定であり、合わせてPostgreSQL7.4.9のtext型についても再検証する予定であるが、今回はlength()関数等の利用でエラーとなったログだけを載せておく。

CORYDORAS> select
2 "id",
3 "r_tinytext",
4 length("r_tinytext") as "文字数",
5 lengthb("r_tinytext") as "文字サイズ",
6 substr(
7 dump("r_tinytext",16),
8 1,
9 instr(dump("r_tinytext",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14 "id" = 30;
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではLENGTHをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> l
1 select
2 "id",
3 "r_tinyblob",
4 length("r_tinyblob") as "文字数",
5 lengthb("r_tinyblob") as "文字サイズ",
6 substr(
7 dump("r_tinyblob",16),
8 1,
9 instr(dump("r_tinyblob",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" = 30
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではLENGTHをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> l
1 select
2 "id",
3 "r_text",
4 length("r_text") as "文字数",
5 lengthb("r_text") as "文字サイズ",
6 substr(
7 dump("r_text",16),
8 1,
9 instr(dump("r_text",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" = 30
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではLENGTHをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> l
1 select
2 "id",
3 "r_blob",
4 length("r_blob") as "文字数",
5 lengthb("r_blob") as "文字サイズ",
6 substr(
7 dump("r_blob",16),
8 1,
9 instr(dump("r_blob",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" = 30
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではLENGTHをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS>

今日はここまで。

Mac, Oracle, Oracle以外のデータベース, Tiger Server De Oracle10g, 異機種間接続サービス(Oracle Generic Connectivity) | | コメント (0) | トラックバック (0)

Mac De Oracle Heterogeneous! #73

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

3.varchar型

MySQL4.0.xとは異なり、文字セマンティクスになっているという点以外は注意する点はないだろう。Oracleのvarchat2型にマッピングされている。

1)varchar(20)で、binary属性の有無のみ異なる2列。

CORYDORAS> set null "null"
CORYDORAS> col r_varchar_20 for a40
CORYDORAS> col dump for a20
CORYDORAS> set linesize 132
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 length("r_varchar_20") as "文字数",
5 lengthb("r_varchar_20") as "文字サイズ",
6 substr(
7 dump("r_varchar_20",16),
8 1,
9 instr(dump("r_varchar_20",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" between 19 and 23
CORYDORAS> /

id r_varchar_20 文字数 文字サイズ dump
---------- ---------------------------------------- ---------- ---------- --------------------
19 あ 2 3 Typ=1
20 null null null null
21 null null null null
22 12345678901234567890 20 20 Typ=1
23 12345678901234567890 20 40 Typ=1

CORYDORAS>
CORYDORAS> col r_varchar_20_binary for a40
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20_binary",
4 length("r_varchar_20_binary") as "文字数",
5 lengthb("r_varchar_20_binary") as "文字サイズ",
6 substr(
7 dump("r_varchar_20_binary",16),
8 1,
9 instr(dump("r_varchar_20_binary",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" between 24 and 28
CORYDORAS> /

id r_varchar_20_binary 文字数 文字サイズ dump
---------- ---------------------------------------- ---------- ---------- --------------------
24 あ 2 3 Typ=1
25 null null null null
26 null null null null
27 12345678901234567890 20 20 Typ=1
28 12345678901234567890 20 40 Typ=1

CORYDORAS>

2)varchar(255)で、binary属性の有無がことなる2列。
CORYDORAS> col r_varchar_255 for a40
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_255",
4 length("r_varchar_255") as "文字数",
5 lengthb("r_varchar_255") as "文字サイズ",
6 substr(
7 dump("r_varchar_255",16),
8 1,
9 instr(dump("r_varchar_255",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" = 29
CORYDORAS> /

id r_varchar_255 文字数 文字サイズ dump
---------- ---------------------------------------- ---------- ---------- --------------------
29 **************************************** 255 255 Typ=1
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>
CORYDORAS> col r_varchar_255_binary for a40
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_255_binary",
4 length("r_varchar_255_binary") as "文字数",
5 lengthb("r_varchar_255_binary") as "文字サイズ",
6 substr(
7 dump("r_varchar_255_binary",16),
8 1,
9 instr(dump("r_varchar_255_binary",16),' ')
10 ) as "dump"
11 from
12 varchar_test_mysql4113a_mac_sv@oracle10g_win
13 where
14* "id" = 29
CORYDORAS> /

id r_varchar_255_binary 文字数 文字サイズ dump
---------- ---------------------------------------- ---------- ---------- --------------------
29 **************************************** 255 255 Typ=1
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>

MySQL4.1.x以降ではvarchar(256)以上のサイズを定義すると、自動的に text型に変換されるので用注意。

mysql> alter table varchar_test add column r_varchar_256 varchar(256);
Query OK, 34 rows affected, 1 warning (0.92 sec)
Records: 34 Duplicates: 0 Warnings: 0

mysql> desc varchar_test;
+----------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_varchar_20 | varchar(20) | YES | | NULL | |
| r_varchar_20_binary | varchar(20) | YES | | NULL | |
| r_varchar_255 | varchar(255) | YES | | NULL | |
| r_varchar_255_binary | varchar(255) | YES | | NULL | |
| r_tinytext | tinytext | YES | | NULL | |
| r_tinyblob | tinyblob | YES | | NULL | |
| r_text | text | YES | | NULL | |
| r_blob | blob | YES | | NULL | |
| r_varchar_256 | text | YES | | NULL | |
+----------------------+--------------+------+-----+---------+-------+
10 rows in set (0.01 sec)

mysql>


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

| | コメント (0) | トラックバック (0)

2006年3月22日 (水)

Mac De Oracle Heterogeneous! #72

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

さて、MySQl4.0.xと比べ、文字セマンティクスである点に注意が必要だと書いたが、char(255)及び、char(255) binaryとして定義した列ではその違いを再確認できる。

char(255)と定義すると、MySQL4.1.xでは、文字セマンティクスであることから、255文字(SJISでは510バイト)ということになる。
Generic Connectivity経由で問い合わせた以下結果を見てもらいたい。dump関数が返すデータ型がvarchar2型になっている点に気付いていただけただろうか? 
ODBC Driverが ODBCデータ型である、SQL_CHAR型とSQL_VARCHAR型とのマッピング変更をデータサイズにより変更している。

CORYDORAS> col r_char_255 for a40
CORYDORAS> l
1 select
2 "r_char_255",
3 length("r_char_255") as "文字数",
4 lengthb("r_char_255") as "文字サイズ",
5 substr(
6 dump("r_char_255"),
7 1,
8 instr(dump("r_char_255"),' ')
9 ) as "dump"
10 from
11 char_test_mysql4113a_mac_sv@oracle10g_win
12 where
13* "id" = 11
CORYDORAS> /

r_char_255 文字数 文字サイズ dump
---------------------------------------- ---------- ---------- --------------------
**************************************** 255 255 Typ=1
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>
CORYDORAS> col r_char_255_binary for a40
CORYDORAS> l
1 select
2 "r_char_255_binary",
3 length("r_char_255_binary") as "文字数",
4 lengthb("r_char_255_binary") as "文字サイズ",
5 substr(
6 dump("r_char_255_binary"),
7 1,
8 instr(dump("r_char_255_binary"),' ')
9 ) as "dump"
10 from
11 char_test_mysql4113a_mac_sv@oracle10g_win
12 where
13* "id" = 11
CORYDORAS> /

r_char_255_binary 文字数 文字サイズ dump
---------------------------------------- ---------- ---------- --------------------
**************************************** 255 255 Typ=1
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>

char_test表に char(127) と char(128)の2列を追加して検証した結果を以下に示す。
文字セマンティクスでは、キャラクタセットがSJISであれば127文字は254バイト、128文字は256バイトである。

mysql> desc char_test;
+-------------------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_char_20 | char(20) | YES | | NULL | |
| r_char_20_binary | char(20) | YES | | NULL | |
| r_char_255 | char(255) | YES | | NULL | |
| r_char_255_binary | char(255) | YES | | NULL | |
| r_char_127 | char(127) | YES | | NULL | |
| r_char_128 | char(128) | YES | | NULL | |
+-------------------+-----------+------+-----+---------+-------+

CORYDORAS> set linesize 132
CORYDORAS>
CORYDORAS> l
1 select
2 "r_char_127",
3 length("r_char_127") as "文字数",
4 lengthb("r_char_127") as "文字サイズ",
5 substr(
6 dump("r_char_127",16),
7 1,
8 instr(dump("r_char_127",16),' ')
9 ) as "dump"
10 from
11 char_test_mysql4113a_mac_sv@oracle10g_win
12 where
13* "id" = 99
CORYDORAS> /

r_char_127 文字数 文字サイズ dump
---------------------------------------- ---------- ---------- --------------------
**************************************** 254 254 Typ=96
****************************************
****************************************
*******

CORYDORAS> col r_char_128 for a40
CORYDORAS> l
1 select
2 "r_char_128",
3 length("r_char_128") as "文字数",
4 lengthb("r_char_128") as "文字サイズ",
5 substr(
6 dump("r_char_128",16),
7 1,
8 instr(dump("r_char_128",16),' ')
9 ) as "dump"
10 from
11 char_test_mysql4113a_mac_sv@oracle10g_win
12 where
13* "id" = 100
CORYDORAS> /

r_char_128 文字数 文字サイズ dump
---------------------------------------- ---------- ---------- --------------------
**************************************** 128 128 Typ=1
****************************************
****************************************
********

CORYDORAS>

予想どおり、127×2=254までは、ODBCのSQL_CHAR型 -> OracleのCHAR型に、128×2=256で ODBCのSQL_VARCHAR型->OracleのVARCHAR2型に、ぞれぞれマッピングされている。

文字列の実サイズは、r_char_128列に登録しているデータの方が短い(この例では)ため、見た目は結構歪なマッピングに見えてしまう・・・・。文字セマンティクスになっている影響がここにも現れている。


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

| | コメント (0) | トラックバック (0)

2006年3月21日 (火)

Mac De Oracle Heterogeneous! #71

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

2.char型


char(20)及び、char(20) binaryとして定義した列は、Generic Connectivity経由ではOracleのchar型にマッピングされる。
型のマッピングに関してはMySQL4.0.xと同じなので特に問題はなさそうだ。ただし、MySQL4.1.xでは、文字セマンティクスになっているため char(20)と定義した場合には、20文字という意味になり、キャラクタセットがSJISである下記例においては、最大40バイトであるという点に注意が必要である。

CORYDORAS> set null "null"
CORYDORAS> col dump for a20
CORYDORAS> l
1 select
2 "r_char_20",
3 length("r_char_20") as "文字数",
4 lengthb("r_char_20") as "文字サイズ",
5 substr(
6 dump("r_char_20",16),
7 1,
8 instr(dump("r_char_20",16),' ')
9 ) as "dump"
10 from
11 char_test_mysql4113a_mac_sv@oracle10g_win
12 where
13* "id" <=5
CORYDORAS> /

r_char_20 文字数 文字サイズ dump
---------------------------------------- ---------- ---------- --------------------
あ 39 40 Typ=96
null null null null
40 40 Typ=96
12345678901234567890 40 40 Typ=96
12345678901234567890 20 40 Typ=96

CORYDORAS>
CORYDORAS> col r_char_20_binary for a40
CORYDORAS> l
1 select
2 "r_char_20_binary",
3 length("r_char_20_binary") as "文字数",
4 lengthb("r_char_20_binary") as "文字サイズ",
5 substr(
6 dump("r_char_20_binary",16),
7 1,
8 instr(dump("r_char_20_binary",16),' ')
9 ) as "dump"
10 from
11 char_test_mysql4113a_mac_sv@oracle10g_win
12 where
13* "id" between 6 and 10
CORYDORAS> /

r_char_20_binary 文字数 文字サイズ dump
---------------------------------------- ---------- ---------- --------------------
あ 39 40 Typ=96
null null null null
40 40 Typ=96
12345678901234567890 40 40 Typ=96
12345678901234567890 20 40 Typ=96

CORYDORAS>

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

| | コメント (0) | トラックバック (0)

2006年3月20日 (月)

Mac De Oracle Heterogeneous! #70

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

MySQL4.0.13aは、Generic Connectivityを介して以下の経路でアクセスする。
(尚、MySQL4.0.25のまとめは、MySQL4.1.13aのまとめに含める予定である。)

gencon_blog_mac_my

1.準備

MacOSX Serverに構築したMySQL4.1.13aには、char_test表と、varchar_test表を作成してあり、以下のようなデータを登録しておいた。

mysql> select
-> id,
-> r_char_20,
-> r_char_20_binary
-> from
-> char_test;
+----+------------------------------------------+------------------------------------------+
| id | r_char_20 | r_char_20_binary |
+----+------------------------------------------+------------------------------------------+
| 1 | あ | NULL |
| 2 | NULL | NULL |
| 3 | | NULL |
| 4 | 12345678901234567890 | NULL |
| 5 | 12345678901234567890 | NULL |
| 6 | NULL | あ |
| 7 | NULL | NULL |
| 8 | NULL | |
| 9 | NULL | 12345678901234567890 |
| 10 | NULL | 12345678901234567890 |
+----+------------------------------------------+------------------------------------------+
10 rows in set (0.02 sec)

mysql>
mysql> select
-> id,
-> length(r_char_255),
-> length(r_char_255_binary)
-> from
-> char_test
-> where
-> id = 11;
+----+--------------------+---------------------------+
| id | length(r_char_255) | length(r_char_255_binary) |
+----+--------------------+---------------------------+
| 11 | 255 | 255 |
+----+--------------------+---------------------------+
1 row in set (0.07 sec)

mysql>
mysql> select
-> id,
-> r_varchar_20,
-> r_varchar_20_binary
-> from
-> varchar_test;
+----+--------------+---------------------+
| id | r_varchar_20 | r_varchar_20_binary |
+----+--------------+---------------------+
| 1 | C | C |
| 2 | c | c |
| 3 | B | B |
| 4 | b | b |
| 5 | A | A |
| 6 | a | a |
| 7 | お | お |
| 8 | え | え |
| 9 | う | う |
| 10 | い | い |
| 11 | あ | あ |
| 12 | ぉ | ぉ |
| 13 | ぇ | ぇ |
| 14 | ぅ | ぅ |
| 15 | ぃ | ぃ |
| 16 | ぁ | ぁ |
| 17 | NULL | NULL |
| 18 | | |
+----+--------------+---------------------+
18 rows in set (0.00 sec)

mysql>
mysql> select
-> id,
-> r_varchar_20,
-> r_varchar_20_binary
-> from
-> varchar_test
-> where
-> id between 19 and 28;
+----+------------------------------------------+------------------------------------------+
| id | r_varchar_20 | r_varchar_20_binary |
+----+------------------------------------------+------------------------------------------+
| 19 | あ | NULL |
| 20 | NULL | NULL |
| 21 | | NULL |
| 22 | 12345678901234567890 | NULL |
| 23 | 12345678901234567890 | NULL |
| 24 | NULL | あ |
| 25 | NULL | NULL |
| 26 | NULL | |
| 27 | NULL | 12345678901234567890 |
| 28 | NULL | 12345678901234567890 |
+----+------------------------------------------+------------------------------------------+
10 rows in set (0.02 sec)

mysql>
mysql> select
-> id,
-> length(r_varchar_255),
-> length(r_varchar_255_binary)
-> from
-> varchar_test
-> where
-> id = 29;
+----+-----------------------+------------------------------+
| id | length(r_varchar_255) | length(r_varchar_255_binary) |
+----+-----------------------+------------------------------+
| 29 | 255 | 255 |
+----+-----------------------+------------------------------+
1 row in set (0.00 sec)

mysql> select
-> id,
-> length(r_tinytext),
-> length(r_tinyblob)
-> from
-> varchar_test
-> where
-> id = 30;
+----+--------------------+--------------------+
| id | length(r_tinytext) | length(r_tinyblob) |
+----+--------------------+--------------------+
| 30 | 255 | 255 |
+----+--------------------+--------------------+
1 row in set (0.00 sec)

mysql> select
-> id,
-> length(r_text),
-> length(r_blob)
-> from
-> varchar_test
-> where
-> id between 31 and 34;
+----+----------------+----------------+
| id | length(r_text) | length(r_blob) |
+----+----------------+----------------+
| 31 | 2000 | 2000 |
| 32 | 2001 | 2001 |
| 33 | 4000 | 4000 |
| 34 | 4001 | 4001 |
+----+----------------+----------------+
4 rows in set (0.00 sec)

mysql>

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

| | コメント (0) | トラックバック (0)

2006年3月19日 (日)

Mac De Oracle Heterogeneous! #69

前回のつづき。Generic Connectivyty経由でMySQL4.0.25の文字型にアクセス。最終回。

3.文字列の登録

varchar型へ、NULL、空文字、' あ '、最大サイズの文字列登録。特に問題になるようなことは無さそうだ。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20") values(100,null);

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20") values(101,'');

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20") values(102,' あ ');

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20") values(103,'12345678901234567890');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。


MySQL4.0.25上で実行した場合とは異なり文字列の切り捨てはエラーとして処理される。(バイトセマンティクスなので、varchar(20)では、20バイトを超える文字列はエラーとなる。Generic Connectivity経由でOracleと連携する場合には都合が良さそうだ。)

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20")
2 values(104,'12345678901234567890');
insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20")
*
行1でエラーが発生しました。:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_varchar_20 exceeds
column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4025_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20")
2 values(104,'12345678901');
insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20")
*
行1でエラーが発生しました。:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_varchar_20 exceeds
column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4025_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


20バイト(SJISなので全角なら10文字まで)分のデータを登録しておく。

CORYDORAS> l
1 insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_varchar_20")
2* values(104,'1234567890')
CORYDORAS> /

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS>

char型についても、varchar型と同じデータを登録。

CORYDORAS> insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(200,null);

1行が作成されました。

CORYDORAS> insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(201,'');

1行が作成されました。

CORYDORAS> insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(202,' あ ');

1行が作成されました。

CORYDORAS> insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(203,'12345678901234567890');

1行が作成されました。

CORYDORAS> insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(204,'1234567890');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。


varchar型と同様、char型でも超過分の文字が切り捨てられて登録される危険性はないようだ。

CORYDORAS> insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(205,'123456789012345678901');
insert into char_test_mysql4025_mac@oracle10g_win("id","r_char_20") values(205,'123456789012345678901')
*
行1でエラーが発生しました。:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_char_20 exceeds
column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(MYSQL4025_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS> rollback;

ロールバックが完了しました。


tinytext型、tinyblob型、text型、blob型にもデータを登録。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_tinytext","r_tinyblob") values(205,'あいう','えお');

1行が作成されました。

CORYDORAS> insert into varchar_test_mysql4025_mac@oracle10g_win("id","r_text","r_blob") values(206,'かきく','けこ');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。


Genericn Connectivity経由で登録したデータの確認。(tinytext型、tinyblob型、text型、blob型を除く)

CORYDORAS> select
2 "id",
3 "r_char_20",
4 lengthb("r_char_20") as "bytes"
5 from
6 char_test_mysql4025_mac@oracle10g_win
7 where
8 "id" >= 200;

id r_char_20 bytes
---------- ---------------------------------------- ----------
200 null null
201 20
202 あ 20
203 12345678901234567890 20
204 1234567890 20

CORYDORAS>
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 lengthb("r_varchar_20") as "bytes"
5 from
6 varchar_test_mysql4025_mac@oracle10g_win
7 where
8* "id" between 100 and 104
CORYDORAS> /

id r_varchar_20 bytes
---------- ---------------------------------------- ----------
100 null null
101 null null
102 あ 3
103 12345678901234567890 20
104 1234567890 20

CORYDORAS>

tinytext型、tinyblob型、text型、blob型についてはデータ登録だけを行った。MySQL4.1.13aの同型の検証に含める予定である。
次回は、Generic Connectivity経由で、MySQL4.1.13aの文字型にアクセス。

| | コメント (0) | トラックバック (0)

2006年3月18日 (土)

Mac De Oracle Heterogeneous! #68

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

前回のおさらい。
リモートソートが行われる場合と、そうでない場合があるということであった。
異機種間接続サービスにおいて、コストベースオプティマイザが行う最適化に、リモートソートの排除という記述があるのだが、なにもせず常にそれが行われるということでないようだ。

下記、クエリでは、DML全体がリモートで実行されているため、ソートもリモートソートとなり MySQLのbinary属性のないvarchar型のソート結果(つまり、NULLや空文字が昇順で先頭になり、英字大文字小文字を区別しない)となっている。 

CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20"
4 from
5 varchar_test_mysql4025_mac@oracle10g_win
6 where
7 "id" between 1 and 18
8 order by
9* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
17
18
5 A
6 a
3 B
4 b
1 C
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お

18行が選択されました。

実行計画
----------------------------------------------------------
0 SELECT STATEMENT (REMOTE) Optimizer=ALL_ROWS (Cost=53 Card=5 Bytes=175)
1 0 SORT (ORDER BY) (Cost=53 Card=5 Bytes=175)
2 1 REMOTE* (Cost=52 Card=5 Bytes=175) MYSQL4025_MAC

2 SERIAL_FROM_REMOTE SELECT "id","r_varchar_20" FROM "varchar_tes
t" WHERE "id">=1 AND "id"<=18

統計
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
755 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
18 rows processed

ということで、コストベースオプティマイザの動きを制御できないか? といろいろ調べるた結果、下記の書き換えと、ヒントを利用することにした。
ヒントを利用しなくとも、利用する関数によっては Oracle(ローカル)側でソートするようになるのだが、これも状況次第なので、ご自分の環境で十分なテストを行うことをお勧めする。

まず、該当部分だけをインラインビューに書き換える。(これだけでは全てリモートマップされてしまう)

CORYDORAS> l
1 select *
2 from
3 (
4 select
5 "id",
6 "r_varchar_20"
7 from
8 varchar_test_mysql4025_mac@oracle10g_win
9 where
10 "id" between 1 and 18
11 )
12 order by
13* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
17
18
5 A
6 a
3 B
4 b
1 C
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お

18行が選択されました。

実行計画
----------------------------------------------------------
0 SELECT STATEMENT (REMOTE) Optimizer=ALL_ROWS (Cost=53 Card=5 Bytes=175)
1 0 SORT (ORDER BY) (Cost=53 Card=5 Bytes=175)
2 1 REMOTE* (Cost=52 Card=5 Bytes=175) MYSQL4025_MAC

2 SERIAL_FROM_REMOTE SELECT "id","r_varchar_20" FROM "varchar_tes
t" WHERE "id">=1 AND "id"<=18

統計
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
755 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
18 rows processed

CORYDORAS>

次に、異機種間接続機能向けに使えそうなヒントは NO_MERGEヒント、DRIVING_SITEヒント、REMOTE_MAPPEDヒントのようなのだが、REMOTE_MAPPEDヒントは明文化されていないのとクエリをリモートサイトで実行させるためと思われる名称のヒントであるため対象外とした。

まずは、NO_MERGEヒントから試してみた、

CORYDORAS> set autot on
CORYDORAS> l
1 select *
2 from
3 (
4 select /*+ NO_MERGE */
5 "id",
6 "r_varchar_20"
7 from
8 varchar_test_mysql4025_mac@oracle10g_win
9 where
10 "id" between 1 and 18
11 )
12 order by
13* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
5 A
3 B
1 C
6 a
4 b
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お
17
18

18行が選択されました。

実行計画
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=53 Card=5 Bytes=175)
1 0 SORT (ORDER BY) (Cost=53 Card=5 Bytes=175)
2 1 VIEW (Cost=52 Card=5 Bytes=175)
3 2 REMOTE* (Cost=52 Card=5 Bytes=175) ORACLE10G_WIN

3 SERIAL_FROM_REMOTE SELECT "id","r_varchar_20" FROM "VARCHAR_TES
T_MYSQL4025_MAC" "VARCHAR_TEST_MYSQL

統計
----------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
812 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
18 rows processed

CORYDORAS>
 
思い通りのソート結果を得られた。自動トレースの実行計画、統計情報からソートがローカルデータベース側(つまり、Oracle側)で実行されているという状況を確認できた。


NO_MERGEヒントで目的の結果を得られたので、DRIVING_SITEヒントの確認は省略。
NO_MERGEヒントを利用したクエリとそうでないクエリの実行計画を explain plan文と、utlxpls.sqlスクリプトでさらに確認した結果は以下。

CORYDORAS> l
1 explain plan for
2 select *
3 from
4 (
5 select
6 "id",
7 "r_varchar_20"
8 from
9 varchar_test_mysql4025_mac@oracle10g_win
10 where
11 "id" between 1 and 18
12 )
13 order by
14* "r_varchar_20"
CORYDORAS> /

解析されました。

CORYDORAS> @?/rdbms/admin/utlxpls

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 4028966153

-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT REMOTE| | 5 | 175 | 53 (2)| 00:00:01 |
| 1 | SORT ORDER BY | | 5 | 175 | 53 (2)| 00:00:01 |
| 2 | REMOTE | | 5 | 175 | 52 (0)| 00:00:01 |
-------------------------------------------------------------------------------

Note
-----
- fully remote statement

13行が選択されました。

CORYDORAS> select id,other from plan_table where operation='REMOTE';

ID OTHER
---------- --------------------------------------------------------------------------------
2 SELECT "id","r_varchar_20" FROM "varchar_test" WHERE "id">=1 AND "id"<=18

CORYDORAS>

以下は、NO_MERGEヒントを利用した結果。

CORYDORAS> l
1 explain plan for
2 select *
3 from
4 (
5 select /*+ NO_MERGE */
6 "id",
7 "r_varchar_20"
8 from
9 varchar_test_mysql4025_mac@oracle10g_win
10 where
11 "id" between 1 and 18
12 )
13 order by
14* "r_varchar_20"
CORYDORAS> /

解析されました。

CORYDORAS> @?/rdbms/admin/utlxpls

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 4108374534

-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 175 | 53 (2)| 00:00:01 |
| 1 | SORT ORDER BY | | 5 | 175 | 53 (2)| 00:00:01 |
| 2 | VIEW | | 5 | 175 | 52 (0)| 00:00:01 |
| 3 | REMOTE | | 5 | 175 | 52 (0)| 00:00:01 |
-------------------------------------------------------------------------

10行が選択されました。

CORYDORAS> select id,other from plan_table where operation='REMOTE';

ID OTHER
---------- --------------------------------------------------------------------------------
3 SELECT "id","r_varchar_20" FROM "VARCHAR_TEST_MYSQL4025_MAC" "VARCHAR_TEST_MYSQL
       4025_MAC" WHERE "id">=1 AND "id"<=18

CORYDORAS>

さらに、プランスタビリティ機能を利用すればアクセスプランを固定化できるはずである。
今日はここまで、次回へつづく。

| | コメント (0) | トラックバック (0)

2006年3月16日 (木)

Mac De Oracle Heterogeneous! #67

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

2.文字列のソート

ソートする前の状態

CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 dump("r_varchar_20",16) as hex_sjis
5 from
6 varchar_test_mysql4025_mac@oracle10g_win
7 where
8* "id" between 1 and 18
CORYDORAS> /

id r_varchar_20 HEX_SJIS
---------- ---------------------------------------- --------------------
1 C Typ=1 Len=1: 43
2 c Typ=1 Len=1: 63
3 B Typ=1 Len=1: 42
4 b Typ=1 Len=1: 62
5 A Typ=1 Len=1: 41
6 a Typ=1 Len=1: 61
7 お Typ=1 Len=2: 82,a8
8 え Typ=1 Len=2: 82,a6
9 う Typ=1 Len=2: 82,a4
10 い Typ=1 Len=2: 82,a2
11 あ Typ=1 Len=2: 82,a0
12 ぉ Typ=1 Len=2: 82,a7
13 ぇ Typ=1 Len=2: 82,a5
14 ぅ Typ=1 Len=2: 82,a3
15 ぃ Typ=1 Len=2: 82,a1
16 ぁ Typ=1 Len=2: 82,9f
17 NULL
18 NULL

18行が選択されました。

昇順でソートした結果
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 dump("r_varchar_20",16) as hex_sjis
5 from
6 varchar_test_mysql4025_mac@oracle10g_win
7 where
8 "id" between 1 and 18
9 order by
10* "r_varchar_20"
CORYDORAS> /

id r_varchar_20 HEX_SJIS
---------- ---------------------------------------- --------------------
5 A Typ=1 Len=1: 41
3 B Typ=1 Len=1: 42
1 C Typ=1 Len=1: 43
6 a Typ=1 Len=1: 61
4 b Typ=1 Len=1: 62
2 c Typ=1 Len=1: 63
16 ぁ Typ=1 Len=2: 82,9f
11 あ Typ=1 Len=2: 82,a0
15 ぃ Typ=1 Len=2: 82,a1
10 い Typ=1 Len=2: 82,a2
14 ぅ Typ=1 Len=2: 82,a3
9 う Typ=1 Len=2: 82,a4
13 ぇ Typ=1 Len=2: 82,a5
8 え Typ=1 Len=2: 82,a6
12 ぉ Typ=1 Len=2: 82,a7
7 お Typ=1 Len=2: 82,a8
17 NULL
18 NULL

18行が選択されました。

MySQL側ではbinary属性がないと大文字小文字は区別されず、nullや、空文字の扱いも異なるためソート結果が異なるのだが、
Generic Connectivity経由ではbinary属性が無い場合でもソート順に問題はなさそうでだ。。
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20_binary",
4 dump("r_varchar_20_binary",16) as hex_sjis
5 from
6 varchar_test_mysql4025_mac@oracle10g_win
7 where
8 "id" between 1 and 18
9 order by
10* "r_varchar_20_binary"
CORYDORAS>
CORYDORAS>
CORYDORAS> /

id r_varchar_20_binary HEX_SJIS
---------- ---------------------------------------- --------------------
5 A Typ=1 Len=1: 41
3 B Typ=1 Len=1: 42
1 C Typ=1 Len=1: 43
6 a Typ=1 Len=1: 61
4 b Typ=1 Len=1: 62
2 c Typ=1 Len=1: 63
16 ぁ Typ=1 Len=2: 82,9f
11 あ Typ=1 Len=2: 82,a0
15 ぃ Typ=1 Len=2: 82,a1
10 い Typ=1 Len=2: 82,a2
14 ぅ Typ=1 Len=2: 82,a3
9 う Typ=1 Len=2: 82,a4
13 ぇ Typ=1 Len=2: 82,a5
8 え Typ=1 Len=2: 82,a6
12 ぉ Typ=1 Len=2: 82,a7
7 お Typ=1 Len=2: 82,a8
17 NULL
18 NULL

18行が選択されました。

と安心するのはまだ早い!
クエリの書き方によってソート結果が異なるのだ。
以下の結果を見る限り、リモートソート(以下の場合は、MySQL側でソート処理が行われ、リモートソートの排除が行われていない)が行われているということになる。
CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20"
4 from
5 varchar_test_mysql4025_mac@oracle10g_win
6 where
7 "id" between 1 and 18
8 order by
9* "r_varchar_20"
CORYDORAS> /

id r_varchar_20
---------- ----------------------------------------
17 null
18 null
5 A
6 a
3 B
4 b
1 C
2 c
16 ぁ
11 あ
15 ぃ
10 い
14 ぅ
9 う
13 ぇ
8 え
12 ぉ
7 お

18行が選択されました。

以下に、MySQL側で行ったソート結果を示す。
mysql> edit
-> ¥p
--------------
select
id,
r_varchar_20
from
varchar_test
where
id between 1 and 18
order by
r_varchar_20
--------------

-> ¥g
+----+--------------+
| id | r_varchar_20 |
+----+--------------+
| 17 | NULL |
| 18 | |
| 5 | A |
| 6 | a |
| 3 | B |
| 4 | b |
| 1 | C |
| 2 | c |
| 16 | ぁ |
| 11 | あ |
| 15 | ぃ |
| 10 | い |
| 14 | ぅ |
| 9 | う |
| 13 | ぇ |
| 8 | え |
| 12 | ぉ |
| 7 | お |
+----+--------------+
18 rows in set (0.00 sec)

mysql>

常にリモートソートを排除するようなクエリの書き方は存在するのか?
今日はここまで、次回へつづく。

| | コメント (0) | トラックバック (0)

2006年3月15日 (水)

Mac De Oracle Heterogeneous! #66

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

3)tinytext型、tinyblob型、text型、blob型

Oracleで、blob型というとlob型(ラージオブジェクト)をイメージするが、MySQLでは文字型なので少々戸惑う。Generic Connectivity経由ではどの型にマッピングされているのかを確認したところ、PostgreSQLでlong型にマッピングされていた状況に類似したエラーが返される。

CORYDORAS> col r_tinytext for a40
CORYDORAS> l
1 select
2 "r_tinytext",
3 lengthb("r_tinytext") as "bytes",
4 substr(
5 dump("r_tinytext",16),
6 1,
7 instr(dump("r_tinytext",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 30
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4025_MACはこのコンテキストではLENGTHBをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> col r_tinyblob for a40
CORYDORAS> l
1 select
2 "r_tinyblob",
3 lengthb("r_tinyblob") as "bytes",
4 substr(
5 dump("r_tinyblob",16),
6 1,
7 instr(dump("r_tinyblob",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 30
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4025_MACはこのコンテキストではLENGTHBをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> col r_text for a40
CORYDORAS> l
1 select
2 "r_text",
3 lengthb("r_text") as "bytes",
4 substr(
5 dump("r_text",16),
6 1,
7 instr(dump("r_text",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 31
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4025_MACはこのコンテキストではLENGTHBをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> col r_blob for a40
CORYDORAS> l
1 select
2 "r_blob",
3 lengthb("r_blob") as "bytes",
4 substr(
5 dump("r_blob",16),
6 1,
7 instr(dump("r_blob",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 31
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4025_MACはこのコンテキストではLENGTHBをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS>

create table文で確認してみると、はやり、long型にマッピングされている。

CORYDORAS> create table temp_tab as       
2 select "id","r_tinytext" from
3 varchar_test_mysql4025_mac@oracle10g_win
4 where "id" = 30;
select "id","r_tinytext" from
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS> create table temp_tab as
2 select "id","r_tinyblob" from
3 varchar_test_mysql4025_mac@oracle10g_win
4 where "id" = 30;
select "id","r_tinyblob" from
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS> create table temp_tab as
2 select "id","r_text" from
3 varchar_test_mysql4025_mac@oracle10g_win
4 where "id" = 31;
select "id","r_text" from
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS> create table temp_tab as
2 select "id","r_blob" from
3 varchar_test_mysql4025_mac@oracle10g_win
4 where "id" = 31;
select "id","r_blob" from
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS>

MyODBC Driverにはtext型や、blob型の文字列をOracleのvarchar2型にマッピングするようなオプションは存在しないため、直接利用するのであればlong型のまま利用することになる。
MySQL4.0.25 では、PostgreSQLのように、char型や、varchar型で2000バイトや、4000バイトを定義することはできないため、256バイト以上の文字列は、text型か、blob型で定義されている場合が多いと思われる。定義されている表をそのままGeneric Connecvity経由でアクセスするのであれば、long型で利用することになる。
long型で利用するのが不便であれば他の方法を検討するなり、Generic Connectivityを諦める必要はありそうだ。ちなみに、long型にマッピングされているので使いやすいlob型に変換しようと思ってもそう簡単には行かない。
to_lob()関数などの関数はリモート表には利用できないためだ。(long型をうまく扱うための方法を考えなければ。。。)

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select
2 "id",to_lob("r_tinytext") as "r_tinytext"
3 from
4 varchar_test_mysql4025_mac@oracle10g_win
5 where
6* "id" = 30
CORYDORAS> /
"id",to_lob("r_tinytext") as "r_tinytext"
*
行2でエラーが発生しました。:
ORA-22992: リモート表から選択されたLOBロケータは使用できません。


今日はここまで。

===================================
いろいろな伏線を張ったまま、放置する可能性もあるので、ご注意を。m(_ _)m 
Generic Connectiviyを利用するどうかの判断は、MySQL、PostgreSQLやODBCのバージョン、プラットフォームに影響される上、実際にどのようなスキーマを持っているかがポイントになる。従って、一概にMySQL4.0.xだから適用できるとか、PostgreSQLだと今ひとつだとか、言い切ることができない。
実システム又は、同等のテスト環境を利用し検証した結果を元に判断するしか無い、というのが現実である。
うまくハマれば、便利な機能であるのも事実。その分かれ目を見極めるためにも検証作業が大切。

| | コメント (0) | トラックバック (0)

2006年3月14日 (火)

Mac De Oracle Heterogeneous! #65

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

1.マッピングされる型の確認

Generic Connectivity経由でMySQL4.0.25の文字型がOracleのどの型にマップされるかを確認。

1)char型

MySQL4.0.25でchar(20)、char(20) binary、char(255)、char(255) binaryとして定義した場合、Oracle側ではchar型にマッピングされる。

CORYDORAS> set null "null"
CORYDORAS> l
1 select
2 "r_char_20",
3 lengthb("r_char_20") as "bytes",
4 substr(
5 dump("r_char_20",16),
6 1,
7 instr(dump("r_char_20",16),' ')
8 ) as "dump"
9 from
10 char_test_mysql4025_mac@oracle10g_win
11 where
12* "id" <= 5
CORYDORAS> /

r_char_20 bytes dump
---------------------------------------- ---------- ----------
あ 20 Typ=96
null null null
20 Typ=96
12345678901234567890 20 Typ=96
1234567890 20 Typ=96

CORYDORAS>
CORYDORAS> l
1 select
2 "r_char_20_binary",
3 lengthb("r_char_20_binary") as "bytes",
4 substr(
5 dump("r_char_20_binary",16),
6 1,
7 instr(dump("r_char_20_binary",16),' ')
8 ) as "dump"
9 from
10 char_test_mysql4025_mac@oracle10g_win
11 where
12* "id" between 6 and 10
CORYDORAS> /

r_char_20_binary bytes dump
---------------------------------------- ---------- ----------
あ 20 Typ=96
null null null
20 Typ=96
12345678901234567890 20 Typ=96
1234567890 20 Typ=96

CORYDORAS>
CORYDORAS> l
1 select
2 "r_char_255",
3 lengthb("r_char_255") as "bytes",
4 substr(
5 dump("r_char_255",16),
6 1,
7 instr(dump("r_char_255",16),' ')
8 ) as "dump"
9 from
10 char_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 11
CORYDORAS> /

r_char_255 bytes dump
---------------------------------------- ---------- ----------
**************************************** 255 Typ=96
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>
CORYDORAS> col r_char_255_binary for a40
CORYDORAS> l
1 select
2 "r_char_255_binary",
3 lengthb("r_char_255_binary") as "bytes",
4 substr(
5 dump("r_char_255_binary",16),
6 1,
7 instr(dump("r_char_255_binary",16),' ')
8 ) as "dump"
9 from
10 char_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 11
CORYDORAS> /

r_char_255_binary bytes dump
---------------------------------------- ---------- ----------
**************************************** 255 Typ=96
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>


2)varchar型

MySQL4.0.25で、varchar(20)、varchar(20) binary、varchar(255)、varchar(255) binaryとして定義した場合、Oracle側では varchar2型にマッピングされる。

CORYDORAS> l
1 select
2 "r_varchar_20",
3 lengthb("r_varchar_20") as "bytes",
4 substr(
5 dump("r_varchar_20",16),
6 1,
7 instr(dump("r_varchar_20",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" between 19 and 23
CORYDORAS> /

r_varchar_20 bytes dump
---------------------------------------- ---------- ----------
あ 3 Typ=1
null null null
null null null
12345678901234567890 20 Typ=1
1234567890 20 Typ=1

CORYDORAS>
CORYDORAS> l
1 select
2 "r_varchar_20_binary",
3 lengthb("r_varchar_20_binary") as "bytes",
4 substr(
5 dump("r_varchar_20_binary",16),
6 1,
7 instr(dump("r_varchar_20_binary",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" between 24 and 28
CORYDORAS> /

r_varchar_20_binary bytes dump
---------------------------------------- ---------- ----------
あ 3 Typ=1
null null null
null null null
12345678901234567890 20 Typ=1
1234567890 20 Typ=1

CORYDORAS>
CORYDORAS> col r_varchar_255 for a40
CORYDORAS> l
1 select
2 "r_varchar_255",
3 lengthb("r_varchar_255") as "bytes",
4 substr(
5 dump("r_varchar_255",16),
6 1,
7 instr(dump("r_varchar_255",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 29
CORYDORAS> /

r_varchar_255 bytes dump
---------------------------------------- ---------- ----------
**************************************** 255 Typ=1
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>
CORYDORAS> col r_varchar_255_binary for a40
CORYDORAS> l
1 select
2 "r_varchar_255_binary",
3 lengthb("r_varchar_255_binary") as "bytes",
4 substr(
5 dump("r_varchar_255_binary",16),
6 1,
7 instr(dump("r_varchar_255_binary",16),' ')
8 ) as "dump"
9 from
10 varchar_test_mysql4025_mac@oracle10g_win
11 where
12* "id" = 29
CORYDORAS> /

r_varchar_255_binary bytes dump
---------------------------------------- ---------- ----------
**************************************** 255 Typ=1
****************************************
****************************************
****************************************
****************************************
****************************************
***************

CORYDORAS>

今日はここまで。

| | コメント (0) | トラックバック (0)

2006年3月13日 (月)

Mac De Oracle Heterogeneous! #64

前回のつづき
今回から、Generic Connectivity経由でPowerBook G4 MacOSX 10.4.5のMySQL4.0.25及び、PowerMac G5 Dual2.7GhzのMySQL4.1.13aの文字型にアクセスし、その挙動を検証する。

アクセス経路は以下

gencon_blog_mac_my


MySQL4.0.25及び、MySQL4.1.13aには、以前の記事で解説したような理由から、このような2表を作成してある。

Generic Connectivyty経由でMySQL4.0.25の文字型にアクセス。一回目。

MySQL4.0.25のchar_test表には以下のデータを登録しておく。

mysql> select
-> id,
-> r_char_20,
-> r_char_20_binary
-> from
-> char_test;
+----+----------------------+----------------------+
| id | r_char_20 | r_char_20_binary |
+----+----------------------+----------------------+
| 1 | あ | NULL |
| 2 | NULL | NULL |
| 3 | | NULL |
| 4 | 12345678901234567890 | NULL |
| 5 | 1234567890 | NULL |
| 6 | NULL | あ |
| 7 | NULL | NULL |
| 8 | NULL | |
| 9 | NULL | 12345678901234567890 |
| 10 | NULL | 1234567890 |
+----+----------------------+----------------------+
10 rows in set (0.02 sec)

mysql>
mysql> select
-> id,
-> length(r_char_255),
-> length(r_char_255_binary)
-> from
-> char_test
-> where
-> id = 11;
+----+--------------------+---------------------------+
| id | length(r_char_255) | length(r_char_255_binary) |
+----+--------------------+---------------------------+
| 11 | 255 | 255 |
+----+--------------------+---------------------------+
1 row in set (0.26 sec)

mysql>

MySQL4.0.25のvarchar_test表には以下のデータを登録しておく。

mysql> select
-> id,
-> r_varchar_20,
-> r_varchar_20_binary
-> from
-> varchar_test;
+----+--------------+---------------------+
| id | r_varchar_20 | r_varchar_20_binary |
+----+--------------+---------------------+
| 1 | C | C |
| 2 | c | c |
| 3 | B | B |
| 4 | b | b |
| 5 | A | A |
| 6 | a | a |
| 7 | お | お |
| 8 | え | え |
| 9 | う | う |
| 10 | い | い |
| 11 | あ | あ |
| 12 | ぉ | ぉ |
| 13 | ぇ | ぇ |
| 14 | ぅ | ぅ |
| 15 | ぃ | ぃ |
| 16 | ぁ | ぁ |
| 17 | NULL | NULL |
| 18 | | |
+----+--------------+---------------------+
18 rows in set (0.00 sec)

mysql>
mysql> select
-> id,
-> r_varchar_20,
-> r_varchar_20_binary
-> from
-> varchar_test
-> where
-> id between 19 and 28;
+----+----------------------+----------------------+
| id | r_varchar_20 | r_varchar_20_binary |
+----+----------------------+----------------------+
| 19 | あ | NULL |
| 20 | NULL | NULL |
| 21 | | NULL |
| 22 | 12345678901234567890 | NULL |
| 23 | 1234567890 | NULL |
| 24 | NULL | あ |
| 25 | NULL | NULL |
| 26 | NULL | |
| 27 | NULL | 12345678901234567890 |
| 28 | NULL | 1234567890 |
+----+----------------------+----------------------+
10 rows in set (0.42 sec)

mysql>
mysql> select
-> id,
-> length(r_varchar_255),
-> length(r_varchar_255_binary),
-> length(r_tinytext),
-> length(r_tinyblob),
-> length(r_text),
-> length(r_blob)
-> from
-> varchar_test
-> where
-> id between 29 and 34;
+----+-----------------------+------------------------------+--------------------+--------------------+----------------+----------------+
| id | length(r_varchar_255) | length(r_varchar_255_binary) | length(r_tinytext) | length(r_tinyblob) | length(r_text) | length(r_blob) |
+----+-----------------------+------------------------------+--------------------+--------------------+----------------+----------------+
| 29 | 255 | 255 | NULL | NULL | NULL | NULL |
| 30 | NULL | NULL | 255 | 255 | NULL | NULL |
| 31 | NULL | NULL | NULL | NULL | 2000 | 2000 |
| 32 | NULL | NULL | NULL | NULL | 2001 | 2001 |
| 33 | NULL | NULL | NULL | NULL | 4000 | 4000 |
| 34 | NULL | NULL | NULL | NULL | 4001 | 4001 |
+----+-----------------------+------------------------------+--------------------+--------------------+----------------+----------------+
6 rows in set (0.01 sec)

mysql>


準備が出来たところで、つづきは次回。

| | コメント (0) | トラックバック (0)

2006年3月12日 (日)

Mac De Oracle Heterogeneous! #63

続きです。Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 最終回のつづき(なんじゃそりゃ)。

=========まとめ=======

利用しているODBC driverはこちらで解説しているドライバー

Generic Connectivityの文字型マッピング
PostgreSQL7.4.9Oracle10g R1Generic Connectivityでの利用備 考
char型 char型 PostgreSQLでのchar型の定義とODBCデータソースのvarchar型最大サイズの設定によりマップされる型が異なる。

char(n)の n が、ODBC データソースの設定でVARCHAR型最大サイズ以下である場合、char型にマップされる。

ただし、本テストでは、n=1024でvarchar2型にマップされた。(255〜1024のどの値でchar型からvarchar2型に切り替わるのかは未確認。単なるバグなのか??)。

n > ODBCデータソースの設定のVARCHRA型最大サイズである場合には、long型にマップされる。

また、Oracle側にマッピングされる際は、常にバイトセマンティクスとして解釈されるため、PostgreSQL側の文字型にマルチバイトが格納されている場合且つ、バイトサイズが n を超える文字は切り捨てられる点に注意すること。そのような列をアクセスする必要がある場合には、PostgreSQL側の影響がなければ、PostgreSQL側の文字型の最大サイズを大きくすることで対応可能だろう。また、これも影響がないことが前提だが、text型に変更して文字の切り捨てを防ぐという方法も使えるかもしれないが、その場合、long型にマッピングされるので要注意。影響が大きくそのような対処ができないのならば、Generic Connectivityを利用せず、外部表を利用したり他の方法を考えたほうが無難。ストアドプロシージャを利用して解決する方法もあるかもしれないが未確認である。
varchar2型
long型
varchar型 varchar2型 PostgreSQLでのvarchar型の定義とODBCデータソースのvarchar型最大サイズの設定によりマップされる型が異なる。

varchar(n)の n が、ODBC データソースの設定でVARCHAR型最大サイズ以下である場合、varchar型にマップされる。

n > ODBCデータソースの設定のVARCHRA型最大サイズである場合には、long型にマップされる。

また、Oracle側にマッピングされる際は、常にバイトセマンティクスとして解釈されるため、PostgreSQL側の文字型にマルチバイトが格納されている場合且つ、バイトサイズが n を超える文字は切り捨てられる点に注意すること。そのような列をアクセスする必要がある場合には、PostgreSQL側の影響がなければ、PostgreSQL側の文字型の最大サイズを大きくすることで対応可能だろう。また、これも影響がないことが前提だが、text型に変更して文字の切り捨てを防ぐという方法も使えるかもしれないが、その場合、long型にマッピングされるので要注意。影響が大きくそのような対処ができないのならば、Generic Connectivityを利用せず、外部表を利用したり他の方法を考えたほうが無難。ストアドプロシージャを利用して解決する方法もあるかもしれないが未確認である。
long型
text型 long型 通常は、long型にマッピングされるが、ODBCデータソーソの設定で、「text型を長文字列として扱う」をチェックしなければ、varchar2型にマッピング(本当にマッピングされるか未確認。m(_ _)m )される。
varchar2型
(未確認)

ソート時の注意
PostgreSQLでは、空文字は、NULLとは区別されているが、Oracleは、空文字をNULLとして扱うので注意が必要である。例として検索時に、 where 列名 = '' 又は、 where 列名 != ''と記述した場合、Oracleでは、 列名 = NULL 又は、列名 != NULLと解釈され不定され正しい結果は得られない、 '' は利用せず、 列名 IS NULL又は、 列名 IS NOT NULLと書くべし。(Oracleを長年利用してきた方ならば間違うことはない事なのだが・・・)

次回、こんどこそ本当にMySQLの文字型にアクセスへつづく。

| | コメント (0) | トラックバック (0)

2006年3月11日 (土)

Mac De Oracle Heterogeneous! #62

続きです。Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 最終回。

5)文字ソート

空文字は、Oracle側では、NULLとして扱われる点に注意。

CORYDORAS> l
1 select
2 "id",
3 "r_varchar_20",
4 lengthb("r_varchar_20"),
5 dump("r_varchar_20",16) as hex_sjis
6 from
7 char_test_postgresql749_mac@oracle10g_win
8 where
9 "id" between 1 and 18
10 order by
11* "r_varchar_20"
CORYDORAS> /

id r_varchar_20 LENGTHB("R_VARCHAR_20") HEX_SJIS
---------- -------------------- ----------------------- --------------------
5 A 1 Typ=1 Len=1: 41
3 B 1 Typ=1 Len=1: 42
1 C 1 Typ=1 Len=1: 43
6 a 1 Typ=1 Len=1: 61
4 b 1 Typ=1 Len=1: 62
2 c 1 Typ=1 Len=1: 63
16 ぁ 2 Typ=1 Len=2: 82,9f
11 あ 2 Typ=1 Len=2: 82,a0
15 ぃ 2 Typ=1 Len=2: 82,a1
10 い 2 Typ=1 Len=2: 82,a2
14 ぅ 2 Typ=1 Len=2: 82,a3
9 う 2 Typ=1 Len=2: 82,a4
13 ぇ 2 Typ=1 Len=2: 82,a5
8 え 2 Typ=1 Len=2: 82,a6
12 ぉ 2 Typ=1 Len=2: 82,a7
7 お 2 Typ=1 Len=2: 82,a8
17 NULL NULL NULL
18 NULL NULL NULL

18行が選択されました。

CORYDORAS>

=======おまけ========

6) 文字を登録。

利用できる関数はかなり制限されているのだが、DMLをパススルーしてやればなんとかなるだろうね。(以前実験済み

CORYDORAS> list
1 insert into char_test_postgresql749_mac@oracle10g_win("id","r_varchar_4000")
2 values(101,lpad('*',4000,'*'))
CORYDORAS> /
insert into char_test_postgresql749_mac@oracle10g_win("id","r_varchar_4000")
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではLPADをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


CORYDORAS> insert into
2 char_test_postgresql749_mac@oracle10g_win("id","r_varchar_20")
3 values(101,'01234567890');
insert into
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_varchar_20 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 insert into
2 char_test_postgresql749_mac@oracle10g_win("id","r_varchar_20")
3* values(101,'0123456789')
CORYDORAS> /

1行が作成されました。

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>
CORYDORAS> insert into
2 char_test_postgresql749_mac@oracle10g_win("id","r_char_20")
3 values(101,'012345678901234567890');
insert into
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_char_20 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 insert into
2 char_test_postgresql749_mac@oracle10g_win("id","r_char_20")
3* values(101,'01234567890123456789')
CORYDORAS> /

1行が作成されました。


次回、Generic Connectivity経由でPostgreSQL7.4.9の文字型をアクセスする場合の注意点などのまとめへつづく。

| | コメント (0) | トラックバック (0)

2006年3月10日 (金)

Mac De Oracle Heterogeneous! #61

続きです。Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 五回目。

前回は、PostgreSQL7.4.9のchar(2000)がOracleのlong型にマッピングされているという状況だった。
ということで、PostgreSQL7.4.9のchar型、varchar型が、Oracleのchar型又は、varchar2型にマッピングされるのか、long型にマッピングされるのか? その境界値を探る。また、その値を変更することは可能なのかも合わせて調査する。(ODBCの影響が一番強いと思うのだが。。。)

4−1)100バイトは?
char(100)及び、varchar(100)として定義したデータは、それぞれ、Oracleのchar型、varchar2型として 問い合わせる事ができた。

CORYDORAS> select dump("char100") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("CHAR100")
--------------------------------------------------------------------------------
Typ=96 Len=100: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42
,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

CORYDORAS> select dump("varchar100") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("VARCHAR100")
--------------------------------------------------------------------------------
Typ=1 Len=100: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42
,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

4−2)255バイトではどう?
char(255)として定義した列は LONG型にマッピングされている。101文字以上255文字未満ということのようだ。

CORYDORAS> select dump("char255") from char_len_tet_postgresql749_mac@oracle10g_win;
select dump("char255") from char_len_tet_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-02070:
データベースPOSTGRESQL749_MACはこのコンテキストではDUMPをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


そこで、思い出したのが、psqlODBCのデータソースの設定。

odbc_before

4−3)じゃ、254バイトまでだな!!
varcharの最大サイズが254文字に設定されているので char(254)として定義した列を問い合わせると、正しく問い合わせる事ができた。

CORYDORAS> select dump("char254") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("CHAR254")
--------------------------------------------------------------------------------
Typ=96 Len=254: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,

中略

,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42
,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

4−4)ODBCのvarchar型の最大サイズを4000バイトにしてみた!

psqlODBCの設定を254から 4000に変更した。

odbc_after


char(254)はいままで通りで問題ない。

CORYDORAS> select dump("char254") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("CHAR254")
--------------------------------------------------------------------------------
Typ=96 Len=254: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42
,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,

中略

42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42
,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

さて、次が問題なのだが、お〜〜。うまく問い合わせることができた。

CORYDORAS> select dump("char255") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("CHAR255")
--------------------------------------------------------------------------------
Typ=96 Len=255: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,

中略

42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42
,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

char(1024)として定義した列なのでが、Oracle側のchar型ではなく、varchar2型にマッピングされてはいるものの、問題なく問い合わせることができた。(Oracleのchar型ではなく、varchar2型にマッピングされてしまったことによる問題は多少あるだろうね)
CORYDORAS> select dump("char1024") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("CHAR1024")
--------------------------------------------------------------------------------
Typ=1 Len=1024: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

中略

42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

varchar(1024)として定義した列も正常に問い合わせることができた。こちらもvarchar2型にマッピングされた。

CORYDORAS> select dump("varchar1024") from char_len_tet_postgresql749_mac@oracle10g_win;

DUMP("VARCHAR1024")
--------------------------------------------------------------------------------
Typ=1 Len=1024: 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

中略

,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,4
2,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42

CORYDORAS>

PostgreSQL7.4.9のchar型及び、varchar型をGeneric Connectivity経由で利用する場合には、psqlODBCのvarchar型の最大サイズの調整しないと、255バイト以上のデータはSQL_LONGVARCHARというODBCデータ型にマッピングされ、結果的に、Oracle型ではLONG型にマッピングされる。psqlODBCのvarchar型最大サイズを調整すればなんとか対応できそうではある。(ODBC Driver次第なので、不安もあるが・・・ま、いいか。)
とちょっとだけ、ほっとしたところで、次回へつづく。

| | コメント (0) | トラックバック (0)

2006年3月 9日 (木)

Mac De Oracle Heterogeneous! #60

続きです。Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 四回目。

4)Oracleのchar型、varchar2型の最大サイズ及び、それを超えるサイズで定義した列にアクセス。

以下、問い合わせた結果。

CORYDORAS> select 
2 "id",
3 lengthb("r_char_2000"),
4 lengthb("r_char_2001"),
5 lengthb("r_varchar_4000"),
6 lengthb("r_varchar_4001")
7 from
8 char_test_postgresql749_mac@oracle10g_win
9 where
10 "id" between 34 and 35;
select
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではLENGTHBをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

おや? これは、text型の時と同じ症状?!にみえる。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select
2 "id",
3 "r_char_2000"
4 from
5 char_test_postgresql749_mac@oracle10g_win
6 where
7* "id" between 34 and 35
CORYDORAS> /

id r_char_2000
---------- --------------------------------------------------------------------------------
34 ********************************************************************************
35 NULL

単純に問い合わせる事はできるようだ。とすると・・・・・。

CORYDORAS> create table temp1
2 as select "id","r_char_2000"
3 from char_test_postgresql749_mac@oracle10g_win
4 where "id" = 34;
as select "id","r_char_2000"
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

やっぱり! long型にマッピングされている!

ちなみに、以下すべてが long型にマッピングされている。char(20)やvarchar(20)ではchar型、varchar2型にマッピングされていたが、long型に切り替えられる境界は? その境界を調整できるのだろうか?(別途調査予定)

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 create table temp1
2 as select "id","r_char_2001"
3 from char_test_postgresql749_mac@oracle10g_win
4* where "id" = 34
CORYDORAS> /
as select "id","r_char_2001"
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。


CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 create table temp1
2 as select "id","r_varchar_4000"
3 from char_test_postgresql749_mac@oracle10g_win
4* where "id" = 35
CORYDORAS> /
as select "id","r_varchar_4000"
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。


CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 create table temp1
2 as select "id","r_varchar_4001"
3 from char_test_postgresql749_mac@oracle10g_win
4* where "id" = 35
CORYDORAS> /
as select "id","r_varchar_4001"
*
行2でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。


CORYDORAS>

さてどうしよう・・・・。


次回へつづく。

| | コメント (0) | トラックバック (0)

2006年3月 8日 (水)

Mac De Oracle Heterogeneous! #59

続きです。Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 三回目。

3)text型として定義した列を問い合わせる

以下、問い合わせた結果。

CORYDORAS> select
2 "id",
3 lengthb("r_text"),
4 length("r_text"),
5 substr(dump("r_text",16),1,7),
6 "r_text"
7 from
8 char_test_postgresql749_mac@oracle10g_win
9 where
10 "id" between 29 and 33;
select
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではLENGTHBをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select
2 "id",
3 substr(dump("r_text",16),1,7),
4 "r_text"
5 from
6 char_test_postgresql749_mac@oracle10g_win
7 where
8* "id" between 29 and 33
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではSUBSTRをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select
2 "id",
3 "r_text"
4 from
5 char_test_postgresql749_mac@oracle10g_win
6 where
7* "id" between 29 and 33
CORYDORAS> /

id r_text
---------- --------------------------------------------------------------------------------
29 あ
30 NULL
31 NULL
32 12345678901234567890
33 12345678901234567890

CORYDORAS> edit
file afiedt.bufが書き込まれました。

1 select
2 "id",
3 dump("r_text",16),
4 "r_text"
5 from
6 char_test_postgresql749_mac@oracle10g_win
7 where
8* "id" between 29 and 33
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではDUMPをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

CORYDORAS> create table temp as
2 select
3 "id",
4 "r_text"
5 from
6 char_test_postgresql749_mac@oracle10g_win
7 where
8 "id" between 29 and 33;
"r_text"
*
行4でエラーが発生しました。:
ORA-00997: LONGデータ型は使用できません。

CORYDORAS>

PostgreSQLのtext型は、Oracleのlong型にマッピングされる。
単純に問い合わせるだけならchar(20)や、varchar(20)の場合のような文字の切り捨ては発生しないためよさそうなのだが、long型は対応している関数が少ないので注意が必要だ。(他の型、例えば、CLOB型などに変換してから利用すれば使い勝手もよくできるかもしれないが、さらに検証が必要だ。)


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

| | コメント (0) | トラックバック (0)

2006年3月 7日 (火)

Mac De Oracle Heterogeneous! #58

続きです。Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 二回目。

1. char型

1) char(20)として定義した列を問い合わせる

以下、問い合わせた結果。

CORYDORAS> set null 'NULL'
CORYDORAS> list
1 select
2 "id",
3 lengthb("r_char_20"),
4 length("r_char_20"),
5 substr(dump("r_char_20",16),1,7),
6 "r_char_20"
7 from
8 char_test_postgresql749_mac@oracle10g_win
9 where
10* "id" between 19 and 23
CORYDORAS> /

id LENGTHB("R_CHAR_20") LENGTH("R_CHAR_20") SUBSTR(DUMP("R r_char_20
---------- -------------------- ------------------- -------------- --------------------
19 20 19 Typ=96 あ
20 NULL NULL NULL NULL
21 20 20 Typ=96
22 20 20 Typ=96 12345678901234567890
23 20 10 Typ=96 1234567890

CORYDORAS>

char(20)は、Oracle側のchar型にマップされている。 
PostgreSQL上で問い合わせた結果と比較すると、文字数やバイト数が1文字及び1バイトづつ少ない。ODBCの問題である可能性も無いとは言えないが、Oracleはバイトセマンティクスでchar(20)をハンドリングしているようにみえる。id=19,23のデータは文字が切り捨てられている点に注意してもらいたい。ただ、20バイトで単純に切り捨てられているということではなく、文字列として20バイト以内に収まる文字数で切り捨てられているようにも見える。'1234567890123456789あ' という20文字を登録しておき、Generic Connectivity経由でOralce側から問い合わせると、'1234567890123456789'が返されたためだなのだが、状況証拠だけなので偶々という可能性もある。尚、alter session文で、バイトセマンティクスから文字セマンティクスに変更しても状況は変わらない。
PostgreSQLのchar(20)を Oracleのchar(20 char)にマッピングする回避方法はあるのか? 無理矢理だがPostgreSQL側のchar(20)をchar(40)へ変更してしまうという方法で回避できるようならそれでもよいかもしれないが、列サイズの変更により既存プログラムへの影響が懸念される。それ以外の方法としては外部表がお手軽かもしれない。他にはパススルークエリーを利用すればなんとかなるか??。(パススルークエリを利用した回避方法は別途調査してみるか・・)


2)varchar(20)として定義した列を問い合わせる

以下、問い合わせた結果

CORYDORAS> l
1 select
2 "id",
3 lengthb("r_varchar_20"),
4 length("r_varchar_20"),
5 substr(dump("r_varchar_20",16),1,7),
6 "r_varchar_20"
7 from
8 char_test_postgresql749_mac@oracle10g_win
9 where
10* "id" between 24 and 28
CORYDORAS> /

id LENGTHB("R_VARCHAR_20") LENGTH("R_VARCHAR_20") SUBSTR(DUMP("R r_varchar_20
---------- ----------------------- ---------------------- -------------- --------------------
24 4 3 Typ=1 L あ
25 NULL NULL NULL NULL
26 NULL NULL NULL NULL
27 20 20 Typ=1 L 12345678901234567890
28 20 10 Typ=1 L 1234567890

CORYDORAS>

varchar(20)は、Oracleのvarchar2型にマップされている。注意する点は、char(20)のid=23のデータと同じ。

今日はここまで。次回につづく。

| | コメント (0) | トラックバック (0)

2006年3月 6日 (月)

Mac De Oracle Heterogeneous! #57

前回のつづき、Generic Connectivity経由でPostgreSQL7.4.9の文字型にアクセス 一回目。

アクセス経路は以下の通り。

gencon_blog_mac_pos

PostgreSQL7.4.9には以下のような表を作成した。
Oracleへのマッピングも考慮し、Oracleのchar型及び、varchar2型の最大サイズ及び、最大サイズを超えるサイズで定義した。

postgresql749=> ¥d char_test;
Table "scott.char_test"
Column | Type | Modifiers
----------------+-------------------------+-----------
id | integer | not null
r_char_20 | character(20) |
r_char_2000 | character(2000) |
r_char_2001 | character(2001) |
r_varchar_20 | character varying(20) |
r_varchar_4000 | character varying(4000) |
r_varchar_4001 | character varying(4001) |
r_text | text |
Indexes:
"char_test_pkey" primary key, btree (id)

postgresql749=>

事前に以下のデータを登録してある。

 id | r_varchar_20 | octet_length | hex_euc | hex_sjis | hex_utf8 
----+--------------+--------------+---------+----------+----------
18 | | 0 | | |
5 | A | 1 | 41 | 41 | 41
3 | B | 1 | 42 | 42 | 42
1 | C | 1 | 43 | 43 | 43
6 | a | 1 | 61 | 61 | 61
4 | b | 1 | 62 | 62 | 62
2 | c | 1 | 63 | 63 | 63
16 | ぁ | 2 | a4a1 | 829f | e38181
11 | あ | 2 | a4a2 | 82a0 | e38182
15 | ぃ | 2 | a4a3 | 82a1 | e38183
10 | い | 2 | a4a4 | 82a2 | e38184
14 | ぅ | 2 | a4a5 | 82a3 | e38185
9 | う | 2 | a4a6 | 82a4 | e38186
13 | ぇ | 2 | a4a7 | 82a5 | e38187
8 | え | 2 | a4a8 | 82a6 | e38188
12 | ぉ | 2 | a4a9 | 82a7 | e38189
7 | お | 2 | a4aa | 82a8 | e3818a
17 | | | | |
(18 rows)

postgresql749=>

postgresql749=> select
postgresql749-> id,
postgresql749-> r_char_20,
postgresql749-> length(r_char_20) as length,
postgresql749-> octet_length(r_char_20) as octet_length
postgresql749-> from
postgresql749-> char_test
postgresql749-> where
postgresql749-> id between 19 and 23;
id | r_char_20 | length | octet_length
----+------------------------------------------+--------+--------------
19 | あ | 20 | 21
20 | | |
21 | | 20 | 20
22 | 12345678901234567890 | 20 | 20
23 | 12345678901234567890 | 20 | 40
(5 rows)

postgresql749=>

postgresql749=> select
postgresql749-> id,
postgresql749-> r_varchar_20,
postgresql749-> length(r_varchar_20) as length,
postgresql749-> octet_length(r_varchar_20) as octet_length
postgresql749-> from
postgresql749-> char_test
postgresql749-> where
postgresql749-> id between 24 and 28;
id | r_varchar_20 | length | octet_length
----+------------------------------------------+--------+--------------
24 | あ | 3 | 4
25 | | |
26 | | 0 | 0
27 | 12345678901234567890 | 20 | 20
28 | 12345678901234567890 | 20 | 40
(5 rows)

postgresql749=>

postgresql749=> select
postgresql749-> id,
postgresql749-> r_text,
postgresql749-> length(r_text) as length,
postgresql749-> octet_length(r_text) as octet_length
postgresql749-> from
postgresql749-> char_test
postgresql749-> where
postgresql749-> id between 29 and 33;
id | r_text | length | octet_length
----+------------------------------------------+--------+--------------
29 | あ | 3 | 4
30 | | |
31 | | 0 | 0
32 | 12345678901234567890 | 20 | 20
33 | 12345678901234567890 | 20 | 40
(5 rows)

postgresql749=>

postgresql749=> select
postgresql749-> octet_length(r_char_2000),
postgresql749-> octet_length(r_char_2001),
postgresql749-> octet_length(r_varchar_4000),
postgresql749-> octet_length(r_varchar_4001)
postgresql749-> from
postgresql749-> char_test
postgresql749-> where
postgresql749-> id between 34 and 35;
octet_length | octet_length | octet_length | octet_length
--------------+--------------+--------------+--------------
2000 | 2001 | |
| | 4000 | 4001
(2 rows)

postgresql749=>

次回へつづく。

| | コメント (0) | トラックバック (0)

2006年3月 5日 (日)

Mac De Oracle Heterogeneous! #56

前回からのつづき。Generic Connectivity経由でMySQL4.0.25、MySQL4.1.13a及び、PostgreSQL7.4.9の文字型にアクセス。(準備)

まず、Windows XP上で踏み台にするOracle10g にMySQL4.0.25、MySQL4.1.13a及び、PostgreSQL7.4.9の各表をアクセスするためのシノニムを作成する。(この例では、プライベートシノニム)

Generic Connectivity用のデータベースリンクを介してアクセスする各表をシノニムとして定義し、
そのシノニムへMacOSX上のOracle10gからOracleの分散データベース機能を利用してアクセスする。この方法で、現時点ではGeneric Connectivityが実装されていないMacOSX上のOracle10gから異機種データベースをアクセスする。

尚、Generic Connectivity経由で、MySQL4.1.13aへ発行する count()関数は正しい結果を得られないためrownum疑似列をmax()関数で取得するという方法で代用している。

作業は赤で囲んだOracle10g上で行っている。

gencon_blog_win_ora


SQL> create synonym char_test_postgresql749_mac for "char_test"@postgresql749_mac;

シノニムが作成されました。

SQL> create synonym char_test_mysql4025_mac for "char_test"@mysql4025_mac;

シノニムが作成されました。

SQL> create synonym varchar_test_mysql4025_mac for "varchar_test"@mysql4025_mac;

シノニムが作成されました。

SQL> create synonym char_test_mysql4113a_mac_sv for "char_test"@mysql4113a_mac_sv;

シノニムが作成されました。

SQL> create synonym varchar_test_mysql4113a_mac_sv for "varchar_test"@mysql4113a_mac_sv;

シノニムが作成されました。

SQL> select synonym_name,table_name,substr(db_link,1,20) as db_link from user_synonyms;

SYNONYM_NAME TABLE_NAME DB_LINK
------------------------------ -------------------- --------------------
EMP_MYSQL4025_MAC emp MYSQL4025_MAC
INNO_EMP_MYSQL4025_MAC inno_emp MYSQL4025_MAC
EMP_MYSQL4026_WIN emp MYSQL4026_WIN
EMP_MYSQL4113A_MAC_SV emp MYSQL4113A_MAC_SV
EMP_POSTGRESQL749_MAC emp POSTGRESQL749_MAC
ORACLE_EMP_MYSQL4026_WIN oracle_emp MYSQL4026_WIN
DATE_TEST_MYSQL4026_WIN date_test MYSQL4026_WIN
DATE_TEST_MYSQL4113A_MAC_SV date_test MYSQL4113A_MAC_SV
DATE_TEST_POSTGRESQL749_MAC date_test POSTGRESQL749_MAC
NUM_TEST_POSTGRESQL749_MAC num_test POSTGRESQL749_MAC
NUM_TEST_MYSQL4113A_MAC_SV num_test MYSQL4113A_MAC_SV
NUM_TEST_MYSQL4025_MAC num_test MYSQL4025_MAC
CHAR_TEST_POSTGRESQL749_MAC char_test POSTGRESQL749_MAC
CHAR_TEST_MYSQL4025_MAC char_test MYSQL4025_MAC
VARCHAR_TEST_MYSQL4025_MAC varchar_test MYSQL4025_MAC
CHAR_TEST_MYSQL4113A_MAC_SV char_test MYSQL4113A_MAC_SV
VARCHAR_TEST_MYSQL4113A_MAC_SV varchar_test MYSQL4113A_MAC_SV

17行が選択されました。

SQL>
SQL> select count(*) from char_test_postgresql749_mac;

COUNT(*)
----------
35

SQL> select count(*) from char_test_mysql4025_mac;

COUNT(*)
----------
11

SQL> select count(*) from varchar_test_mysql4025_mac;

COUNT(*)
----------
34

SQL> select count(*) from char_test_mysql4113a_mac_sv;

COUNT(*)
----------
12593

SQL> select count(*) from varchar_test_mysql4113a_mac_sv;

COUNT(*)
----------
13363

SQL> select max(rownum) from char_test_mysql4113a_mac_sv;

MAX(ROWNUM)
-----------
11

SQL> select max(rownum) from varchar_test_mysql4113a_mac_sv;

MAX(ROWNUM)
-----------
34

SQL>

Windows上で、Generic Connectivityの接続を確認できたので、MacOSXのOracle10gから、WindowsのOracle10g経由で各データベースへの接続を確認する。
Generic Connectivity経由でアクセスする経路は以下の通り。

gencon_blog_my_pos


尚、Generic Connectivity経由で、MySQL4.1.13aへ発行する count()関数は正しい結果を得られないためrownum疑似列をmax()関数で取得するという方法で代用している。

SYS> conn corydoras
パスワードを入力してください:
接続されました。
CORYDORAS>
CORYDORAS>
CORYDORAS>
CORYDORAS> select db_link from user_db_links;

DB_LINK
--------------------------------------------------------------------------------
ORACLE10G_WIN

CORYDORAS> select synonym_name from user_synonyms;

レコードが選択されませんでした。


CORYDORAS> select count(*) from char_test_postgresql749_mac@oracle10g_win;

COUNT(*)
----------
35

CORYDORAS> select count(*) from char_test_mysql4025_mac@oracle10g_win;

COUNT(*)
----------
11

CORYDORAS> select count(*) from varchar_test_mysql4025_mac@oracle10g_win;

COUNT(*)
----------
34

CORYDORAS> select count(*) from char_test_mysql4113a_mac_sv@oracle10g_win;

COUNT(*)
----------
12593

CORYDORAS> select max(rownum) from char_test_mysql4113a_mac_sv@oracle10g_win;

MAX(ROWNUM)
-----------
11

CORYDORAS> select count(*) from varchar_test_mysql4113a_mac_sv@oracle10g_win;

COUNT(*)
----------
13363

CORYDORAS> select max(rownum) from varchar_test_mysql4113a_mac_sv@oracle10g_win;

MAX(ROWNUM)
-----------
34

CORYDORAS>

Generic Connectivity経由の接続を確認することができた。
次回、Generic Connectivity経由でPostgreSQLの文字型にアクセス 一回目につづく。

| | コメント (0) | トラックバック (0)

2006年3月 4日 (土)

Mac De Oracle Heterogeneous! #55

前回の続き。
MySQLの文字型の最終回。

今回はbinary属性の有無によるソート結果の違いを確認する。

登録したデータは以下。(id列は登録順に昇順とした)

insert into varchar_test(id, r_varchar_20) values(1,'C');
insert into varchar_test(id, r_varchar_20) values(2,'c');
insert into varchar_test(id, r_varchar_20) values(3,'B');
insert into varchar_test(id, r_varchar_20) values(4,'b');
insert into varchar_test(id, r_varchar_20) values(5,'A');
insert into varchar_test(id, r_varchar_20) values(6,'a');
insert into varchar_test(id, r_varchar_20) values(7,'お');
insert into varchar_test(id, r_varchar_20) values(8,'え');
insert into varchar_test(id, r_varchar_20) values(9,'う');
insert into varchar_test(id, r_varchar_20) values(10,'い');
insert into varchar_test(id, r_varchar_20) values(11,'あ');
insert into varchar_test(id, r_varchar_20) values(12,'ぉ');
insert into varchar_test(id, r_varchar_20) values(13,'ぇ');
insert into varchar_test(id, r_varchar_20) values(14,'ぅ');
insert into varchar_test(id, r_varchar_20) values(15,'ぃ');
insert into varchar_test(id, r_varchar_20) values(16,'ぁ');

binary属性が無い場合、char型、varchar型は英字大文字小文字を区別しない。(MySQL4.0.25、MySQL4.1.13aとも同じ)
mysql> 
mysql> select
-> id,
-> r_varchar_20,
-> hex(r_varchar_20) as hex_sjis
-> from
-> varchar_test
-> where
-> id between 1 and 16
-> order by
-> r_varchar_20;
+----+--------------+----------+
| id | r_varchar_20 | hex_sjis |
+----+--------------+----------+
| 5 | A | 41 |
| 6 | a | 61 |
| 3 | B | 42 |
| 4 | b | 62 |
| 1 | C | 43 |
| 2 | c | 63 |
| 16 | ぁ | 829F |
| 11 | あ | 82A0 |
| 15 | ぃ | 82A1 |
| 10 | い | 82A2 |
| 14 | ぅ | 82A3 |
| 9 | う | 82A4 |
| 13 | ぇ | 82A5 |
| 8 | え | 82A6 |
| 12 | ぉ | 82A7 |
| 7 | お | 82A8 |
+----+--------------+----------+
16 rows in set (0.07 sec)

mysql>

binary属性付きの場合、英字大文字に続き、英字小文字の順にソートされる。

mysql> select
-> id,
-> r_varchar_20_binary,
-> hex(r_varchar_20_binary) as hex_sjis
-> from
-> varchar_test
-> where
-> id between 17 and 32
-> order by
-> r_varchar_20_binary;
+----+---------------------+----------+
| id | r_varchar_20_binary | hex_sjis |
+----+---------------------+----------+
| 21 | A | 41 |
| 19 | B | 42 |
| 17 | C | 43 |
| 22 | a | 61 |
| 20 | b | 62 |
| 18 | c | 63 |
| 32 | ぁ | 829F |
| 27 | あ | 82A0 |
| 31 | ぃ | 82A1 |
| 26 | い | 82A2 |
| 30 | ぅ | 82A3 |
| 25 | う | 82A4 |
| 29 | ぇ | 82A5 |
| 24 | え | 82A6 |
| 28 | ぉ | 82A7 |
| 23 | お | 82A8 |
+----+---------------------+----------+
16 rows in set (0.00 sec)

mysql>


ちなみに、Oracleで同じことを行うとのと同じ結果になるのは、binary属性があるchar型又は、varchar型なのである。
SQL> list
1 select
2 string,
3 dump(string, 16) as "hex"
4 from
5 test
6 order by
7 string
SQL> /

STRING hex
------ ------------------------------
A Typ=1 Len=1: 41
B Typ=1 Len=1: 42
C Typ=1 Len=1: 43
a Typ=1 Len=1: 61
b Typ=1 Len=1: 62
c Typ=1 Len=1: 63
ぁ Typ=1 Len=2: 82,9f
あ Typ=1 Len=2: 82,a0
ぃ Typ=1 Len=2: 82,a1
い Typ=1 Len=2: 82,a2
ぅ Typ=1 Len=2: 82,a3
う Typ=1 Len=2: 82,a4
ぇ Typ=1 Len=2: 82,a5
え Typ=1 Len=2: 82,a6
ぉ Typ=1 Len=2: 82,a7
お Typ=1 Len=2: 82,a8

16行が選択されました。


さらにおまけ。
Oracleでは、nlssort()関数を利用した言語ソートを行うこともできる。

SQL> list
1 select
2 string,
3 dump(string, 16) as "hex"
4 from
5 test
6 order by
7 nlssort(string, 'NLS_SORT = japanese')
SQL> /

STRING hex
------ ------------------------------
a Typ=1 Len=1: 61
A Typ=1 Len=1: 41
b Typ=1 Len=1: 62
B Typ=1 Len=1: 42
c Typ=1 Len=1: 63
C Typ=1 Len=1: 43
ぁ Typ=1 Len=2: 82,9f
あ Typ=1 Len=2: 82,a0
ぃ Typ=1 Len=2: 82,a1
い Typ=1 Len=2: 82,a2
ぅ Typ=1 Len=2: 82,a3
う Typ=1 Len=2: 82,a4
ぇ Typ=1 Len=2: 82,a5
え Typ=1 Len=2: 82,a6
ぉ Typ=1 Len=2: 82,a7
お Typ=1 Len=2: 82,a8


ということで、簡単だったが、MySQL4.0.25及び、4.1.13aでの文字型の検証は終わり。(なんとなくPostgreSQLがステキに見えてくる。というのもMySQLが独特な世界を持っているからか?)

次回、PostgreSQLとMySQLの文字型をGeneric Connectivity経由でアクセスへつづく。

| | コメント (0) | トラックバック (0)

2006年3月 3日 (金)

Mac De Oracle Heterogeneous! #54

前回の続き。
MySQLの文字型の四回目。

1.varchar型の検証

1−1 MySQL4.0.25での検証

1)' あ '、 null、 空文字、シングルバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した

mysql> insert into varchar_test(id, r_varchar_20) values(33,' ¥202¥240 ');
Query OK, 1 row affected (0.01 sec)
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into varchar_test(id, r_varchar_20) values(33, ' あ ');
mysql> 
insert into varchar_test(id, r_varchar_20) values(34,null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into varchar_test(id, r_varchar_20) values(35,'');
Query OK, 1 row affected (0.00 sec)

mysql> insert into varchar_test(id, r_varchar_20) values(36,'12345678901234567890');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

2)シングルバイト文字で21文字を登録

PostgreSQLとは異なりワーニングもエラーも発生しない。Generic Connectivity経由での登録は要注意だ。

mysql> insert into varchar_test(id, r_varchar_20) values(37,'123456789012345678901');
Query OK, 1 row affected (0.00 sec)

3)マルチバイト文字で20文字を登録。

データベースキャラクタセットはSJISなので実際には40バイトになる文字列なのだが、これも正常?に実行された。

mysql> 
mysql> insert into varchar_test(id, r_varchar_20)
-> values(38,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W02X¥202O');
Query OK, 1 row affected (0.00 sec)
Terminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into varchar_test(id, r_varchar_20) values(38,'12345678901234567890');

4)マルチバイト文字で21文字を登録。

実際には42バイトになる文字列なのでだが正常の実行されてしまった。列は20バイトまでと定義しているのだが

mysql> 
mysql> insert into varchar_test(id, r_varchar_20)
-> values(39,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W02X¥202O¥202P');
Query OK, 1 row affected (0.00 sec)
Terminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into varchar_test(id, r_varchar_20) values(39,'123456789012345678901');

5)文字数、バイトサイズの確認

PostgreSQLの場合と比べて文字数とバイト数が異なることに気付いただろうか?
MySQL4.0.25のchar型と同じなのだ。このリリースのMySQLでは、varchar型とchar型の差が無いことに改めて気付く。

mysql> 
mysql> select
-> id,
-> r_varchar_20,
-> char_length(r_varchar_20) as char_length,
-> length(r_varchar_20) as length
-> from
-> varchar_test
-> where
-> id between 33 and 39;
+----+----------------------+-------------+--------+
| id | r_varchar_20 | char_length | length |
+----+----------------------+-------------+--------+
| 33 | あ | 2 | 3 |
| 34 | NULL | NULL | NULL |
| 35 | | 0 | 0 |
| 36 | 12345678901234567890 | 20 | 20 |
| 37 | 12345678901234567890 | 20 | 20 |
| 38 | 1234567890 | 10 | 20 |
| 39 | 1234567890 | 10 | 20 |
+----+----------------------+-------------+--------+
7 rows in set (0.00 sec)

mysql>
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql>


1−2 MySQL4.1.13aでの検証

1)' あ '、 null、 空文字、シングルバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した。

mysql> insert into varchar_test(id, r_varchar_20) values(33,' ¥202¥240 ');
Query OK, 1 row affected (0.00 sec)
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into varchar_test(id, r_varchar_20) values(33, ' あ ');
mysql> insert into varchar_test(id, r_varchar_20) values(34,null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into varchar_test(id, r_varchar_20) values(35,'');
Query OK, 1 row affected (0.00 sec)

mysql> insert into varchar_test(id, r_varchar_20) values(36,'12345678901234567890');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.07 sec)

2)シングルバイト文字で21文字を登録

MySQL4.0.25とは異なりワーニングが発生するが、Generic Connectivity経由ではワーニングが拾えないので要注意だ。

mysql> insert into varchar_test(id, r_varchar_20) values(37,'123456789012345678901');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1265 | Data truncated for column 'r_char_20' at row 1 |
+---------+------+------------------------------------------------+
1 row in set (0.00 sec)


3)マルチバイト文字を20文字登録(登録内容はMySQL4.0.25と同じ)

正常に実行される。

mysql> 
mysql> insert into varchar_test(id, r_varchar_20)
-> values(38,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O');
Query OK, 1 row affected (0.00 sec)

4)マルチバイト文字を21文字登録(登録内容はMySQL4.0.25と同じ)

文字列が制限を超えるとワーニングがでるようにはなっているが、4.1.xではここまで。ワーニングを拾ってロールバックしなければ、commitされてしまうため文字列が切り捨てられたことすら、気がつかないという状況もありえるので要注意。MySQL5.0.2以降ならばsql_mode='TRADITIONAL'にすればエラー扱いにすることも可能なようだが、4.x台では無理だ。今までの経験から warningは、Generic Connectivity経由では拾えないので、Generic Connectivity経由での登録や更新は要注意だ。

mysql> 
mysql> insert into varchar_test(id, r_varchar_20)
-> values(39,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1265 | Data truncated for column 'r_char_20' at row 1 |
+---------+------+------------------------------------------------+
1 row in set (0.00 sec)

5)文字数、バイトサイズの確認

MySQL4.1.x以降、varchar(n)の n は、文字数を意味するので MySQL4.0.xの文字列とは物理サイズが異なる点に注意。

mysql> 
mysql> select
-> id,
-> r_varchar_20,
-> char_length(r_varchar_20) as char_length,
-> length(r_varchar_20) as length
-> from
-> varchar_test
-> where
-> id between 33 and 39;
+----+------------------------------------------+-------------+--------+
| id | r_varchar_20 | char_length | length |
+----+------------------------------------------+-------------+--------+
| 33 | あ | 2 | 3 |
| 34 | NULL | NULL | NULL |
| 35 | | 0 | 0 |
| 36 | 12345678901234567890 | 20 | 20 |
| 37 | 12345678901234567890 | 20 | 20 |
| 38 | 12345678901234567890 | 20 | 40 |
| 39 | 12345678901234567890 | 20 | 40 |
+----+------------------------------------------+-------------+--------+
6 rows in set (0.00 sec)

mysql>
mysql> rollback;
Query OK, 0 rows affected (0.05 sec)

mysql>

MySQLのvarchar型でもchar型同様、後半の空白をトリムする仕様となっているので注意が必要だ。
マニュアルによると、後半の空白が必要な場合には、text型を利用する必要があるとの記述がある。なんだ?!


text型やblob型が、Generic Connectivity経由で利用できるか不明なのだが、簡単な検証を行っておく。

2.text型とblob型の検証

text型やblob型はOracleなどで言うラージオブジェクトとは別ものらしく、文字列型に分類されている。(ん〜〜〜〜〜。と、うなってみたりして・・)

mysql> insert into varchar_test(id,r_text) values(37,'¥202¥240¥202¥242¥202¥244');
Query OK, 1 row affected (0.00 sec)

mysql> insert into varchar_test(id,r_blob) values(38,'¥202¥240¥202¥242¥202¥244');
Query OK, 1 row affected (0.00 sec)


text型は文字数はマルチバイトで3文字と認識されているが、blob型では6文字と認識される。

mysql> select
-> id,
-> r_text,
-> hex(r_text),
-> char_length(r_text) as ¥203o¥203C¥203g¥220¥224,
-> length(r_text) as ¥225¥266¥216¥232¥220¥224
-> from
-> varchar_test
-> where
-> id = 37;
+----+--------+--------------+----------+----------+
| id | r_text | hex(r_text) | 文字数 | バイト数 |
+----+--------+--------------+----------+----------+
| 37 | あいう | 82A082A282A4 | 3 | 6 |
+----+--------+--------------+----------+----------+
1 row in set (0.00 sec)

mysql> select
-> id,
-> r_blob,
-> hex(r_blob),
-> char_length(r_blob) as ¥203o¥203C¥203g¥220¥224,
-> length(r_blob) as ¥225¥266¥216¥232¥220¥224
-> from
-> varchar_test
-> where
-> id = 38;
+----+--------+--------------+----------+----------+
| id | r_blob | hex(r_blob) | 文字数 | バイト数 |
+----+--------+--------------+----------+----------+
| 38 | あいう | 82A082A282A4 | 6 | 6 |
+----+--------+--------------+----------+----------+
1 row in set (0.00 sec)

mysql>


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

| | コメント (0) | トラックバック (0)

2006年3月 2日 (木)

Mac De Oracle Heterogeneous! #53

前回の続き。
MySQLの文字型の三回目。

1.char型の検証

1−1 MySQL4.0.25での検証

1)' あ '、 null、 空文字、シングルバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した。

mysql> insert into char_test(id, r_char_20) values(1,' ¥202¥240 ');
Query OK, 1 row affected (0.00 sec)
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_char_20) values(1, ' あ ');
mysql> insert into char_test(id, r_char_20) values(2,null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into char_test(id, r_char_20) values(3,'');
Query OK, 1 row affected (0.00 sec)

mysql> insert into char_test(id, r_char_20) values(4,'12345678901234567890');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

2)シングルバイト文字で21文字を登録

PostgreSQLとは異なりワーニングもエラーも発生しない。Generic Connectivity経由での登録は要注意だ。

mysql> insert into char_test(id, r_char_20) values(5,'123456789012345678901');
Query OK, 1 row affected (0.00 sec)

3)マルチバイト文字で20文字を登録。

データベースキャラクタセットはSJISなので実際には40バイトになる文字列なのだが、これも正常?に実行された。

mysql> insert into char_test(id, r_char_20) 
-> values(6,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W2X¥202O');
Query OK, 1 row affected (0.00 sec)
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_char_20) values(6,'12345678901234567890');

4)マルチバイト文字で21文字を登録。

実際には42バイトになる文字列なのでだが正常の実行されてしまった。列は20バイトまでと定義しているのだが。

mysql> 
mysql> insert into char_test(id, r_char_20)
-> values(7,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W2X¥202O¥202P');
Query OK, 1 row affected (0.01 sec)
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_char_20) values(7,'123456789012345678901');

5)文字数、バイトサイズの確認

PostgreSQLの場合と比べて文字数とバイト数が異なることに気付いただろうか?
MySQL4.0.25のchar型では、文字につづく空白が切り捨てられる。空文字を設定した場合も空文字が設定されている。

mysql> 
mysql> select
-> id,
-> r_char_20,
-> char_length(r_char_20) as char_length,
-> length(r_char_20) as length
-> from
-> char_test
-> where
-> id <= 7;
+----+----------------------+-------------+--------+
| id | r_char_20 | char_length | length |
+----+----------------------+-------------+--------+
| 1 | あ | 2 | 3 |
| 2 | NULL | NULL | NULL |
| 3 | | 0 | 0 |
| 4 | 12345678901234567890 | 20 | 20 |
| 5 | 12345678901234567890 | 20 | 20 |
| 6 | 1234567890 | 10 | 20 |
| 7 | 1234567890 | 10 | 20 |
+----+----------------------+-------------+--------+
7 rows in set (0.00 sec)

mysql>
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql>


1−2 MySQL4.1.13aでの検証

1)' あ '、 null、 空文字、シングルバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した。

mysql> insert into char_test(id, r_char_20) values(1,' ¥202¥240 ');
Query OK, 1 row affected (0.00 sec)
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_char_20) values(1, ' あ ');
mysql> insert into char_test(id, r_char_20) values(2,null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into char_test(id, r_char_20) values(3,'');
Query OK, 1 row affected (0.00 sec)

mysql> insert into char_test(id, r_char_20) values(4,'12345678901234567890');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.06 sec)

2)シングルバイト文字を21文字登録

MySQL4.0.xとは異なり、ワーニングが返されるが、それ以外の違いはない。

mysql> insert into char_test(id, r_char_20) values(5,'123456789012345678901');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1265 | Data truncated for column 'r_char_20' at row 1 |
+---------+------+------------------------------------------------+
1 row in set (0.00 sec)


3)マルチバイト文字を20文字登録(登録内容はMySQL4.0.25と同じ)

正常に実行される。

mysql> insert into char_test(id, r_char_20) 
-> values(6,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O');
Query OK, 1 row affected (0.00 sec)


4)マルチバイト文字を21文字登録(登録内容はMySQL4.0.25と同じ)

文字列が制限を超えるとワーニングがでるようにはなっているが、4.1.xではここまで。ワーニングを拾ってロールバックしなければ、commitされてしまうため文字列が切り捨てられたことすら、気がつかないという状況もありえるので要注意。MySQL5.0.2以降ならばsql_mode='TRADITIONAL'にすればエラー扱いにすることも可能なようだが、4.x台では無理だ。今までの経験から warningは、Generic Connectivity経由では拾えないので、Generic Connectivity経由での登録や更新は要注意だ。

mysql> 
mysql> insert into char_test(id, r_char_20)
-> values(7,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1265 | Data truncated for column 'r_char_20' at row 1 |
+---------+------+------------------------------------------------+
1 row in set (0.00 sec)


5)文字数、バイトサイズの確認

MySQL4.1.x以降、char(n)の n は、文字数を意味するので MySQL4.0.xとの違いは文字列が取りうる物理サイズということになる。

mysql> 
mysql>
mysql> select
-> id,
-> r_char_20,
-> char_length(r_char_20) as char_length,
-> length(r_char_20) as length
-> from
-> char_test
-> where
-> id <= 7;
+----+------------------------------------------+-------------+--------+
| id | r_char_20 | char_length | length |
+----+------------------------------------------+-------------+--------+
| 1 | あ | 2 | 3 |
| 2 | NULL | NULL | NULL |
| 3 | | 0 | 0 |
| 4 | 12345678901234567890 | 20 | 20 |
| 5 | 12345678901234567890           | 20 | 20 |
| 6 | 12345678901234567890 | 20 | 40 |
| 7 | 12345678901234567890 | 20 | 40 |
+----+------------------------------------------+-------------+--------+
7 rows in set (0.03 sec)

mysql>
mysql> rollback;
Query OK, 0 rows affected (0.05 sec)

mysql>


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

| | コメント (0) | トラックバック (0)

2006年3月 1日 (水)

Mac De Oracle Heterogeneous! #52

前回の続き。
MySQLの文字型の二回目。

MySQL4.0.25、MySQL4.1.13aともに以下の表を作成した。

mysql> desc char_test;
+-------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_char_20 | char(20) | YES | | NULL | |
| r_char_20_binary | char(20) binary | YES | | NULL | |
| r_char_255 | char(255) | YES | | NULL | |
| r_char_255_binary | char(255) binary | YES | | NULL | |
+-------------------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

mysql> desc varchar_test;
+----------------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+---------------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_varchar_20 | varchar(20) | YES | | NULL | |
| r_varchar_20_binary | varchar(20) binary | YES | | NULL | |
| r_varchar_255 | varchar(255) | YES | | NULL | |
| r_varchar_255_binary | varchar(255) binary | YES | | NULL | |
| r_tinytext | tinytext | YES | | NULL | |
| r_tinyblob | tinyblob | YES | | NULL | |
| r_text | text | YES | | NULL | |
| r_blob | blob | YES | | NULL | |
+----------------------+---------------------+------+-----+---------+-------+
9 rows in set (0.00 sec)

mysql>

MySQL4.0.xまでは、char型及び、varchar型は最大255バイト。4.1.x以降では65535文字
また、独特な仕様だが、char型とvarchar型は、大文字小文字を区別しない。大文字小文字を区別させるためには binary属性を付けなければならない。binary属性の無い文字型ではソート処理がどうなるのか気になるところだ。

ところで、255バイト以上の文字列はどのようにして格納するのか? とマニュアルを読んでいると、tinytext型、text型、mediumtext型、longtext型、そして、大文字小文字を区別できるtinyblob型、blob型、mediumblob型、longblob型があるとのこと。(blobだとbinary large objectなのかと思っていたのだが、マニュアルによると文字列という表現になっている。ところ変わればなんとやら。。なのだが、generic connectivity経由でOracleのvarchar2型にマッピングできるのかという点は不安材料だ。。)

また、MySQL4.1から文字列型の仕様がかなり変更されたらしく、MySQL4.0.xでは、char(n)又は、varchar(n)の n はバイトを意味していたものが、文字数に変わったようだ。
さらに、キャラクタセットがカラム毎に変えられるらしい、MySQL4.1以降ならば事前に表定義は、”しっかり”確認しておく事をお勧めする。もしそのような表定義であったなら generic connectivity で扱うのは諦めたほうがよいかもしれない。 

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

| | コメント (0) | トラックバック (0)

2006年2月28日 (火)

Mac De Oracle Heterogeneous! #51

文字型のつづき。今回から、MySQLの文字型の特徴を簡単検証していく。

PowerBook G4 MacOSX Tiger 10.4.5のMySQL4.0.25及び、PowerMac G5 Dual2.7GhzのMySQL4.1.13aを利用した。


gencon_blog_img33

尚、データベース及び、クライアントキャラクタセットともにSJISである。

MySQL4.0.25及び、MySQL4.1.13aには、以下のような表を作成した。。。のだが・・・・・。

mysql> create table char_testA
-> (
-> id int primary key,
-> r_char_20 char(20),
-> r_char_20_binary char(20) binary,
-> r_char_255 char(255),
-> r_char_255_binary char(255) binary,
-> r_varchar_20 varchar(20),
-> r_varchar_20_binary varchar(20) binary,
-> r_varchar_255 varchar(255),
-> r_varchar_255_binary varchar(255) binary,
-> r_tinytext tinytext,
-> r_tinyblob tinyblob,
-> r_text text,
-> r_blob blob
-> ) engine=innodb;

Query OK, 0 rows affected (0.10 sec)

char型で定義した列が全て varchar型になっていたのである。あれれ、何故????

mysql> desc char_test;
+----------------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+---------------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_char_20 | varchar(20) | YES | | NULL | |
| r_char_20_binary | varchar(20) binary | YES | | NULL | |
| r_char_255 | varchar(255) | YES | | NULL | |
| r_char_255_binary | varchar(255) binary | YES | | NULL | |
| r_varchar_20 | varchar(20) | YES | | NULL | |
| r_varchar_20_binary | varchar(20) binary | YES | | NULL | |
| r_varchar_255 | varchar(255) | YES | | NULL | |
| r_varchar_255_binary | varchar(255) binary | YES | | NULL | |
| r_tinytext | tinytext | YES | | NULL | |
| r_tinyblob | tinyblob | YES | | NULL | |
| r_text | text | YES | | NULL | |
| r_blob | blob | YES | | NULL | |
----------------------+---------------------+------+-----+---------+-------+
13 rows in set (0.00 sec)

DDLもvarcharに変更されている。
mysql> show create table char_test¥G
*************************** 1. row ***************************
Table: char_test
Create Table: CREATE TABLE `char_test` (
`id` int(11) NOT NULL default '0',
`r_char_20` varchar(20) default NULL,
`r_char_20_binary` varchar(20) binary default NULL,
`r_char_255` varchar(255) default NULL,
`r_char_255_binary` varchar(255) binary default NULL,
`r_varchar_20` varchar(20) default NULL,
`r_varchar_20_binary` varchar(20) binary default NULL,
`r_varchar_255` varchar(255) default NULL,
`r_varchar_255_binary` varchar(255) binary default NULL,
`r_tinytext` tinytext,
`r_tinyblob` tinyblob,
`r_text` text,
`r_blob` blob,
PRIMARY KEY (`id`)
) TYPE=InnoDB
1 row in set (0.00 sec)

mysql>

慌てて、マニュアルを確認してみると、

マニュアルから引用ここから


6.5.3.1. カラムの暗黙的な変更

場合によっては、CREATE TABLE ステートメントで指定されているカラムの型、属性が、MySQL によって暗黙的に変更されることがあります(このような変更は ALTER TABLE でも発生する場合があります)。

長さが 4 文字に満たない VARCHAR 型のカラムは CHAR 型に変更される。

テーブルのいずれかのカラムが可変長である場合は、結果的にそのレコード全体が可変長になる。したがって、テーブルに可変長のカラム(VARCHAR、TEXT、BLOB)が含まれている場合、長さが 3 文字を超す CHAR 型のカラムはいずれも VARCHAR 型カラムに変更される。これはカラムの使用方法には影響しない。MySQL では、VARCHAR 型は単に文字を格納するもう 1 つの手段として使用されている。MySQL でこの変換が実行される理由は、スペースを節約し、テーブル処理を迅速化するためである。 See 章 7. MySQL のテーブル型。

バージョン 4.1.0 以降では、255 文字を超える長さを持つ CHAR 型または VARCHAR 型のフィールドはいずれも TEXT 型に変換される。 これは互換性を考慮した機能。


マニュアルから引用ここまで


仕様なら仕方ない。(バグかと思ったよ。。。。)
ということで、char型本来の癖を見る為、char型だけの表とvarchar型、text型、blob型の表に分ける事にした。(尚、mediumtext型、mediumblob型、longtext型及び、longblob型は検証対象外とした。)

char(n) と char(n) binaryの違いは、'A'と'a'を区別するかしないかということ。binary属性を付けると大文字と小文字を区別するようになる。この特徴は要注意だ。PostgreSQLもOracleもDB2でも大文字小文字は区別される、区別したくない場合には、スカラ関数を使い大文字又は、小文字に統一してから比較するからだ。もし、Generic Connectivityを経由してアクセスするMySQLの表がbinary属性のないchar型やvarchar型だと、ソートは注意が必要かもしれない。(ソートについては、Generic Connectivity経由でも検証する)
また、blob型なのに何故、文字型の検証で登場するのかと感じる方もいると思うのだが、blob型は Oracleのlob型に対応するのでは? と思っているのだが、MySQLでは文字列型に分類されており、大文字小文字を区別したい文字列を格納するための型となっている、ちなみに、text型は大文字小文字を区別しない。これらの型の詳細は、MySQLのマニュアル又は、MySQLによる最速RDBMS構築ガイドを参照するとよいだろう。

mysql> create table char_test
-> (
-> id int primary key,
-> r_char_20 char(20),
-> r_char_20_binary char(20) binary,
-> r_char_255 char(255),
-> r_char_255_binary char(255) binary
-> ) engine=innodb;
Query OK, 0 rows affected (0.09 sec)

mysql>
mysql> create table varchar_test
-> (
-> id int primary key,
-> r_varchar_20 varchar(20),
-> r_varchar_20_binary varchar(20) binary,
-> r_varchar_255 varchar(255),
-> r_varchar_255_binary varchar(255) binary,
-> r_tinytext tinytext,
-> r_tinyblob tinyblob,
-> r_text text,
-> r_blob blob
-> ) engine=innodb;
Query OK, 0 rows affected (0.02 sec)


ちなみに、一旦, char型からvarchar型に変更されてしまうと、全列を固定長に戻したとしても、varchar型がchar型に戻されることは無いようだ。以下のログ参照。(ん〜〜〜〜・・・・。いろいろ書きたい気分だがノーコメント。) 
まず、char型だけの表を作成。この定義だとすべてchar型として定義されている。

Welcome to Darwin!
G5Server:˜ discus$ mysql -u discus -p mysqldb41
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or ¥g.
Your MySQL connection id is 1 to server version: 4.1.13a

Type 'help;' or '¥h' for help. Type '¥c' to clear the buffer.

mysql> create table char_test
-> (
-> id int primary key,
-> r_char_20 char(20),
-> r_char_20_binary char(20) binary,
-> r_char_255 char(255),
-> r_char_255_binary char(255) binary
-> ) engine=innodb;
Query OK, 0 rows affected (0.22 sec)

mysql> desc char_test;
+-------------------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_char_20 | char(20) | YES | | NULL | |
| r_char_20_binary | char(20) | YES | | NULL | |
| r_char_255 | char(255) | YES | | NULL | |
| r_char_255_binary | char(255) | YES | | NULL | |
+-------------------+-----------+------+-----+---------+-------+
5 rows in set (0.01 sec)

固定長の文字列しかない表であれば、char型のままなのだが、char型とvarchar型(text型、blob型も含む)が混在すると、既存char型は全て、自動的にvarchar型に変更されてしまう。MySQLのchar型、varchar型の仕様からすると、どちらの型でもいいのかもしれないが、他の(PostgreSQLやOracleなど)RDBMSと互換を持たせた挙動にしたい場合には困るかもしれない。(Generic Connectivity経由の挙動確認ではこの辺りも忘れずに!)
mysql> alter table char_test add column r_varchar_20 varchar(20);
Query OK, 0 rows affected (0.52 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc char_test;
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_char_20 | varchar(20) | YES | | NULL | |
| r_char_20_binary | varchar(20) | YES | | NULL | |
| r_char_255 | varchar(255) | YES | | NULL | |
| r_char_255_binary | varchar(255) | YES | | NULL | |
| r_varchar_20 | varchar(20) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+-------+
6 rows in set (0.03 sec)


一旦、char型からvarchar型に自動変更されてしまった表は、そのきっかけになった列を削除しても元には戻らない。
どうしても、char型に戻したいのなら表を再作成するしかない。

mysql> alter table char_test drop column r_varchar_20;
Query OK, 0 rows affected (0.71 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc char_test;
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| id | int(11) | | PRI | 0 | |
| r_char_20 | varchar(20) | YES | | NULL | |
| r_char_20_binary | varchar(20) | YES | | NULL | |
| r_char_255 | varchar(255) | YES | | NULL | |
| r_char_255_binary | varchar(255) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+-------+
5 rows in set (0.02 sec)

mysql> drop table char_test;
Query OK, 0 rows affected (0.05 sec)

mysql>

と、戸惑う仕様がいろいろあるのだが、なんとかやっている。ということで次回へつづく。

| | コメント (0) | トラックバック (0)

2006年2月27日 (月)

Mac De Oracle Heterogeneous! #50

前回からのつづき。
PostgreSQLの文字型 最終回。

ソートの確認。ロケール関連パラメータをCに設定しているので特に問題ないと思うが、念のために確認。以下のデータを登録しておく。

dpostgresql749=> select id,r_varchar_20 from char_test;
id | r_varchar_20
----+--------------
1 | C
2 | c
3 | B
4 | b
5 | A
6 | a
7 | お
8 | え
9 | う
10 | い
11 | あ
12 | ぉ
13 | ぇ
14 | ぅ
15 | ぃ
16 | ぁ
(16 rows)

postgresql749=>

尚、文字列を16進数表示するユーザ定義関数 strtohex()を利用して文字コードも確認した。
strtohex()関数を作成したログ(抜粋)。詳細はstrtohexのソースに同胞されているドキュメントを参照のこと。
http://ring.atr.jp/archives/misc/db/postgresql-jp/strtohex/?C=M;O=Aからダウンロードできる。

pb17:/usr/local/pgsql/share/contrib postgres$ postmaster -S
pb17:/usr/local/pgsql/share/contrib postgres$ psql -e -f strtohex.sql postgresql749
SET search_path = scott;
SET
CREATE OR REPLACE FUNCTION strtohex(TEXT)
RETURNS TEXT
AS '$libdir/strtohex', 'strtohex'
LANGUAGE C STRICT;
CREATE FUNCTION
commit;
COMMIT
pb17:/usr/local/pgsql/share/contrib postgres$ psql -U scott postgresql749
Password:
Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=> select strtohex('a');
strtohex
----------
61
(1 row)

文字列を昇順にソートした結果。(変わったところはないようだ)

postgresql749=> ¥p
select
id,
r_varchar_20,
strtohex(r_varchar_20) as hex_euc,
strtohex(convert(r_varchar_20,'SJIS')) as hex_sjis,
strtohex(convert(r_varchar_20,'UTF-8')) as hex_utf8
from
char_test
order by
r_varchar_20;

postgresql749=> ¥g
id | r_varchar_20 | hex_euc | hex_sjis | hex_utf8
----+--------------+---------+----------+----------
5 | A | 41 | 41 | 41
3 | B | 42 | 42 | 42
1 | C | 43 | 43 | 43
6 | a | 61 | 61 | 61
4 | b | 62 | 62 | 62
2 | c | 63 | 63 | 63
16 | ぁ | a4a1 | 829f | e38181
11 | あ | a4a2 | 82a0 | e38182
15 | ぃ | a4a3 | 82a1 | e38183
10 | い | a4a4 | 82a2 | e38184
14 | ぅ | a4a5 | 82a3 | e38185
9 | う | a4a6 | 82a4 | e38186
13 | ぇ | a4a7 | 82a5 | e38187
8 | え | a4a8 | 82a6 | e38188
12 | ぉ | a4a9 | 82a7 | e38189
7 | お | a4aa | 82a8 | e3818a
(16 rows)


ちなみに、Oracleでソートを行った場合と同じ結果だ。
(言語ソートすると言語固有の文字順にソートされるが、PostgreSQLのロケール関連パラメータを設定した場合にはOracleの言語ソートと同じ結果になるのかは未確認。PostgreSQLのマニュアルを熟読しないと・・・・。

購入したPostgreSQL徹底入門「P.178」では詳細な解説はなく、簡単な解説だけだったのが残念。とはいっても言語ソースが必要になる状況は想定していないので特に問題なし。)

SCOTT> list
1 select
2 id#,
3 r_varchar2,
4 dump(r_varchar2,16) as hex_sjis,
5 dump(convert(r_varchar2,'ja16euc'),16) as hex_euc,
6 dump(convert(r_varchar2,'utf8'),16) as hex_utf8
7 from
8 char_test
9 order by
10* r_varchar2
SCOTT> /

ID# R_VARCHAR2 HEX_SJIS HEX_EUC HEX_UTF8
---------- -------------------- -------------------- -------------------- ----------------------
5 A Typ=1 Len=1: 41 Typ=1 Len=1: 41 Typ=1 Len=1: 41
3 B Typ=1 Len=1: 42 Typ=1 Len=1: 42 Typ=1 Len=1: 42
1 C Typ=1 Len=1: 43 Typ=1 Len=1: 43 Typ=1 Len=1: 43
6 a Typ=1 Len=1: 61 Typ=1 Len=1: 61 Typ=1 Len=1: 61
4 b Typ=1 Len=1: 62 Typ=1 Len=1: 62 Typ=1 Len=1: 62
2 c Typ=1 Len=1: 63 Typ=1 Len=1: 63 Typ=1 Len=1: 63
16 ぁ Typ=1 Len=2: 82,9f Typ=1 Len=2: a4,a1 Typ=1 Len=3: e3,81,81
11 あ Typ=1 Len=2: 82,a0 Typ=1 Len=2: a4,a2 Typ=1 Len=3: e3,81,82
15 ぃ Typ=1 Len=2: 82,a1 Typ=1 Len=2: a4,a3 Typ=1 Len=3: e3,81,83
10 い Typ=1 Len=2: 82,a2 Typ=1 Len=2: a4,a4 Typ=1 Len=3: e3,81,84
14 ぅ Typ=1 Len=2: 82,a3 Typ=1 Len=2: a4,a5 Typ=1 Len=3: e3,81,85
9 う Typ=1 Len=2: 82,a4 Typ=1 Len=2: a4,a6 Typ=1 Len=3: e3,81,86
13 ぇ Typ=1 Len=2: 82,a5 Typ=1 Len=2: a4,a7 Typ=1 Len=3: e3,81,87
8 え Typ=1 Len=2: 82,a6 Typ=1 Len=2: a4,a8 Typ=1 Len=3: e3,81,88
12 ぉ Typ=1 Len=2: 82,a7 Typ=1 Len=2: a4,a9 Typ=1 Len=3: e3,81,89
7 お Typ=1 Len=2: 82,a8 Typ=1 Len=2: a4,aa Typ=1 Len=3: e3,81,8a

16行が選択されました。
ちなみに(テストデータがよくないので申し訳ないのだが)、nlssort関数を利用した言語ソートでは小文字英字の順序の違いに気付くと思う。
SCOTT> 
SCOTT> list
1 select
2 r_varchar2
3 from
4 char_test
5 order by
6* nlssort(r_varchar2, 'nls_sort=japanese')
SCOTT> /

R_VARCHAR2
--------------------
a
A
b
B
c
C











16行が選択されました。

SCOTT>


次回は、MySQLの文字型について同様の検証を行う。

| | コメント (0) | トラックバック (0)

2006年2月26日 (日)

Mac De Oracle Heterogeneous! #49

前回からのつづき。
PostgreSQLの文字型の四回目。

1.text型の検証

1)' あ '、 null、 空文字、シングルバイト文字及び、マルチバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した。

postgresql749=> 
postgresql749=> insert into char_test(id, r_text)
postgresql749-> values(1, ' ¥202¥240 ');
INSERT 33747 1
postgresql749=> insert into char_test(id, r_text)
postgresql749-> values(2, null);
INSERT 33748 1
postgresql749=> insert into char_test(id, r_text)
postgresql749-> values(3, '');
INSERT 33749 1
postgresql749=> insert into char_test(id, r_text)
postgresql749-> values(4, '12345678901234567890');
INSERT 33750 1
postgresql749=> insert into char_test(id, r_text)
postgresql749-> values(5, '¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X;
INSERT 33751 1
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_text) values(5, '12345678901234567890');
postgresql749=> commit;
COMMIT

2)text型の最大サイズ

text型の最大サイズは、約1GB(要するに1GB未満)ということで、許容サイズを超えればエラー。

postgresql749=> insert into char_test(id,r_text) values(99,lpad('*',2048000000,'*'));
ERROR: requested length too large
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into char_test(id,r_text) values(99,lpad('*',1024000000,'*'));
ERROR: requested length too large
postgresql749=> rollback;
ROLLBACK

3)文字数、バイトサイズの確認

空白の扱いは、varchar型と同じだが、Generic Connectivity経由では、Oracleのどの型にマップされるのかがポイント。Generic Connectivity経由では利用できない可能性もあるし、利用できたとしてもVARCHAR2型の最大サイズである4000バイトを超えた場合にはどのような挙動になるのかという点も気になるところだ。
Generic Connectivityを利用せず、PostgreSQLのtext型からOracleへデータ移行するとした場合、PostgreSQLのtext型に登録されている文字列の最大サイズが4000バイトを超えるのならば、CLOB型に、4000バイト以下なら、VARCHAR2型にするのがベストだと思われる。
また、PostgreSQLの文字型は、NULL及び、空文字を設定できるが、Oracleでは、NULLと空文字が、NULLとして扱われているため、PostgreSQLの文字型に空文字を設定した場合は、Oracle側ではNULLとして扱われると予想している。

postgresql749-> ¥p
select
id,
r_text,
length(r_text) as 文字数,
octet_length(r_text) as バイト数
from
char_test

postgresql749-> ¥g
id | r_text | 文字数 | バイト数
----+------------------------------------------+-------+--------
1 | あ | 3 | 4
2 | | |
3 | | 0 | 0
4 | 12345678901234567890 | 20 | 20
5 | 12345678901234567890 | 20 | 40
(5 rows)

postgresql749=>

次回へつづく。

| | コメント (0) | トラックバック (0)

2006年2月25日 (土)

Mac De Oracle Heterogeneous! #48

前回からのつづき。
PostgreSQLの文字型 三回目。

1.varchar型の検証

1)' あ '、 null、 空文字、シングルバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した。

postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(1, ' ¥202¥240 ');
INSERT 33742 1
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_varchar_20) values(1, ' あ ');
postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(2, null);
INSERT 33743 1
postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(3, '');
INSERT 33744 1
postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(4,'12345678901234567890');
INSERT 33745 1
postgresql749=> commit;
COMMIT


2)シングルバイト文字を21文字登録

20文字を超えるためエラー。(Oracleと連携しても問題になる事はないだろう)

postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(5,'123456789012345678901');
ERROR: value too long for type character varying(20)
postgresql749=> rollback;
ROLLBACK


3)マルチバイト文字を20文字登録

20文字以内なので問題なく登録できる。

postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(5,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O');
INSERT 33746 1
postgresql749=> commit;
COMMIT
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_varchar_20) values(5,'12345678901234567890');


4)マルチバイト文字を21文字登録

20文字を超えるためエラー。

postgresql749=> insert into char_test(id, r_varchar_20)
postgresql749-> values(6,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O2P');
ERROR: value too long for type character varying(20)
postgresql749=> rollback;
ROLLBACK
現在リリースされているMacOSXのTerminalは、マルチバイトを入力するとエスケープシーケンスになってしまう。実際に入力しているのは以下のDML。
insert into char_test(id, r_varchar_20) values(6,'123456789012345678901');


5)文字数、バイトサイズの確認

空白の扱いは、Oracleと同じようなので問題になることはないだろう。Oracleではvarchar2(20 char)か、varchar2(40)にマッピングすればよいと思うのだが、Generic Connectivity経由の場合はどの型にマッピングされるのか?、また、PostgreSQLの varchar型は、Oracleのvarchar2型より大きいサイズを定義できる(Oracleのvarchar2型は4000バイトが最大だが、PostgreSQLでは約1GBまで可能)ため、Generic Connectivity経由である場合はどのように扱われるのかがポイントになるだろう。

postgresql749=> ¥p
select
id,
r_varchar_20,
length(r_varchar_20) as 文字数,
octet_length(r_varchar_20) as バイト数
from
char_test;
postgresql749=> ¥g
id | r_varchar_20 | 文字数 | バイト数
----+------------------------------------------+-------+--------
1 | あ | 3 | 4
2 | | |
3 | | 0 | 0
4 | 12345678901234567890 | 20 | 20
5 | 12345678901234567890 | 20 | 40
(5 rows)

postgresql749=> delete from char_test;
DELETE 5
postgresql749=> commit;
COMMIT


今日はここまで、続きは次回。

| | コメント (0) | トラックバック (0)

2006年2月24日 (金)

Mac De Oracle Heterogeneous! #47

前回からのつづき。
PostgreSQLの文字型の二回目。

1.char型の検証

1)' あ '、 null、 空文字、シングルバイト文字を20文字登録。

空白の扱いを確認するため、”あ”の前後に空白を付加し、' あ ' として登録した。

postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(1, ' ¥202¥240 ');
INSERT 33737 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(2, null);
INSERT 33738 1
postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(3, '');
INSERT 33739 1
postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(4,'12345678901234567890');
INSERT 33740 1
postgresql749=> commit;
COMMIT

2)シングルバイト文字を21文字登録

20文字を超えるためエラー。(Oracleと連携しても問題になる事はないだろう)

postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(5,'123456789012345678901');
ERROR: value too long for type character(20)
postgresql749=> rollback;
ROLLBACK

3)マルチバイト文字を20文字登録

20文字以内なので問題なく登録できる。
(MacOSX TigerのTerminalからマルチバイト文字を入力するとエスケープシーケンスに変換されてしまうが表示上は問題ない。いつ改善されるやら。。)
ちなみに、実行したインサート文は以下。

insert into char_test(id, r_char_20) values(5,'12345678901234567890');

postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(5,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O');
INSERT 33741 1
postgresql749=> commit;
COMMIT

4)マルチバイト文字を21文字登録

20文字を超えるためエラー。
実行したインサート文は以下。

insert into char_test(id, r_char_20) values(27,'123456789012345678901');

postgresql749=> insert into char_test(id, r_char_20)
postgresql749-> values(6,'¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O¥202P¥202Q¥202R¥202S¥202T¥202U¥202V¥202W¥202X¥202O2P');
ERROR: value too long for type character(20)
postgresql749=> rollback;
ROLLBACK

5)文字数、バイトサイズの確認

空白の扱いは、Oracleと同じようなので問題になることはないだろう。Oracleではchar(20 char)か、varchar2(40)にマッピングすればよいと思うのだが、Generic Connectivity経由の場合はどの型にマッピングされるのか?、また、PostgreSQLの char型は、Oracleのchar型より大きいサイズを定義できる(Oracleのchar型は2000バイトが最大だが、PostgreSQLでは約1GBまで可能)ため、Generic Connectivity経由である場合はどのように扱われるのかがポイントになるだろう。

postgresql749=> ¥p
select
id,
r_char_20,
length(r_char_20) as 文字数,
octet_length(r_char_20) as バイト数
from
char_test;
postgresql749=> ¥g
id | r_char_20 | 文字数 | バイト数
----+------------------------------------------+-------+--------
1 | あ | 20 | 21
2 | | |
3 | | 20 | 20
4 | 12345678901234567890 | 20 | 20
5 | 12345678901234567890 | 20 | 40
(5 rows)

postgresql749=>
postgresql749=> delete from char_test;
DELETE 5
postgresql749=> commit;
COMMIT


次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月23日 (木)

Mac De Oracle Heterogeneous! #46

Generic Connectivityの検証も残すところ文字型のみ。ラージオブジェクトについてはおまけ程度に書く予定だが、その他、各データベースに特有の型は今のところ試す予定はない。(必要になりそうならやるかもしれないが・・)

まず、PostgreSQLとMySQLそれぞれの文字型について癖を把握しておく。
PostgreSQLの文字型 一回目。

PowerBook G4 MacOSX Tiger 10.4.5のPostgreSQL7.4.9を利用した。


gencon_blog_img_postgre

また、クライアントエンコーディングは、SJIS。
データベースキャラクタセットは、EUC。
ソートに影響するローケル関連パラメータLC_COLLATEパラメータ及び、LC_CTYPEパラメータは C とした。 
(ちなみに、LC_COLLATE及び、LC_CTYPEパラメータを設定すると Oracleの言語ソートのようなことができるような記述がマニュアルにはあるのだが、前述した書籍で「日本語を使う場合、initdbで--no-locale。。。」とあったため、この検証では C と設定することとした)

pb17:˜ postgres$ pg_controldata
pg_control version number: 72
Catalog version number: 200310211
Database cluster state: shut down

中略

LC_COLLATE: C
LC_CTYPE: C
pb17:˜ postgres$
pb17:˜ postgres$
pb17:˜ postgres$ echo $PGCLIENTENCODING
SJIS
pb17:˜ postgres$

以下の表を作成した。

postgresql749=> create table char_test
postgresql749-> (
postgresql749(> id int primary key,
postgresql749(> r_char_20 char(20),
postgresql749(> r_char_2000 char(2000),
postgresql749(> r_char_2001 char(2001),
postgresql749(> r_varchar_20 varchar(20),
postgresql749(> r_varchar_4000 varchar(4000),
postgresql749(> r_varchar_4001 varchar(4001),
postgresql749(> r_text text
postgresql749(> );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "char_test_pkey" for table "char_test"
CREATE TABLE
postgresql749=> ¥d char_test
Table "scott.char_test"
Column | Type | Modifiers
----------------+-------------------------+-----------
id | integer | not null
r_char_20 | character(20) |
r_char_2000 | character(2000) |
r_char_2001 | character(2001) |
r_varchar_20 | character varying(20) |
r_varchar_4000 | character varying(4000) |
r_varchar_4001 | character varying(4001) |
r_text | text |
Indexes:
"char_test_pkey" primary key, btree (id)

postgresql749=>
postgresql749=> commit;
COMMIT
postgresql749=>

Oracleと違い点は、char(n)型及び、varchar(n)型の n は常に文字数ということ。
また、n の上限はなく、最大長が約1GBまで制限がある。
従って、データベースキャラクタセットにより n の上限が変わってくるということになる。
Generic Connectivity経由でアクセスする際にはこの辺りがポイントになるだろう。また、text型がどのような扱いになるのかも気になるところだ。

ちなみに、Oracleでは初期化パラメータ nls_length_semantics を char にしデフォルトを文字単位の長さにするか、列を定義する際に、CHAR修飾子を指定することと同じ。
nls_length_semanticsのデフォルトはBYTEなので、hoge_code1は10文字、hoge_code2は10バイトという意味になる、

create table hoge
(
hoge_code1 CHAR(10 CHAR),
hoge_code2 CHAR(10)
);

今日はここまで。次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月22日 (水)

Mac De Oracle Heterogeneous! #45

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 最終回。

Generic Connectivity経由でdecimal型と同型の符号なしにアクセスした結果。

ここでは、以下のように定義した。

decimal(38,0)と同型の符号なし。
decimal(38,16)と同型の符号なし。

MySQL4.1.13a、MySQL4.0.25では、Oracleのnumber型の精度より低い。これらの型もGeneric Connectivity経由で参照、更新するのは避けたほうがよさそうである。
(実際にはインサート文も検証しているが結果は同じであるため省略)

1)MySQL4.0.25の decimal(38,0)とdecimal(38,0) unsignedを
  Generic Connectivity経由で問い合わせた結果

CORYDORAS> set numwidth 40
CORYDORAS> select
2 "r_decimal_38",
3 "r_decimal_38_unsigned"
4 from
5 num_test_mysql4025_mac@oracle10g_win;

r_decimal_38 r_decimal_38_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
99999999999999997748809823456034029568 0
-99999999999999997748809823456034029568 99999999999999997748809823456034029568
NULL NULL

中略

NULL NULL

25行が選択されました。

2)MySQL4.1.13aの decimal(38,0)とdecimal(38,0) unsignedを
  Generic Connectivity経由で問い合わせた結果

MySQL4.1.13aでは、不具合では?と思える部分(99999999999999999999999999999999999999が100000000000000035527741686413195739136となり精度が39桁になってしまっている)もある。

CORYDORAS> list
1 select
2 "r_decimal_38",
3 "r_decimal_38_unsigned"
4 from
5* num_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /

r_decimal_38 r_decimal_38_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
100000000000000035527741686413195739136 0
-99999999999999999999999999999999999999 99999999999999999999999999999999999999
NULL NULL
NULL NULL

27行が選択されました。

CORYDORAS>

3)MySQL4.0.25のdecimal(38,16)とdecimal(38,16) unsignedを
  Generic Connectivity経由で問い合わせた結果

decimalの精度は、doubleと同じというMySQL側の仕様の影響だと思われるが、MySQL独特な動作の一つである数値の丸めが発生し、decimal(38,0)では最大値の精度が23桁になってしまっている。これもgeneric connectivity経由での参照、更新対象にはしないほうがよいだろう。

CORYDORAS> select
2 "r_decimal_38_16",
3 "r_decimal_38_16_unsigned"
4 from
5 num_test_mysql4025_mac@oracle10g_win;

r_decimal_38_16 r_decimal_38_16_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-9999999999999999999999.9999999999999999 0
10000000000000000000000 9999999999999999999999.9999999999999999
NULL NULL
NULL NULL

25行が選択されました。

4)MySQL4.1.13aのdecimal(38,16)とdecimal(38,16) unsignedを
  Generic Connectivity経由で問い合わせた結果。

3)とほぼ同じ結果であった。

CORYDORAS> list
1 select
2 "r_decimal_38_16",
3 "r_decimal_38_16_unsigned"
4 from
5* num_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /

r_decimal_38_16 r_decimal_38_16_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-9999999999999999999999.9999999999999999 0
10000000000000004194304 9999999999999999999999.9999999999999999

27行が選択されました。

CORYDORAS>


==================================
Generic Connectivity経由での数値型の参照、更新のまとめ(MySQL4.0.x、4.1.x編)


利用している MyODBCドライバなどはこちら

数値型マッピング
MySQL4.0.25
MySQL4.1.13a
Oracle10g R1Generic Connectivityでの利用備 考
tinyint型 number型注1)
tinyint unsigned型 × 直接利用するのは避けたほうがよいだろう。参照するだけならば、MySQLの表データをCSVファイル化し外部表で取り込む等、直接参照しないアプローチを考えたほうがよいだろう。注1)
smallint型 注1)
smallint unsigned型 × 直接利用するのは避けたほうがよいだろう。参照するだけならば、MySQLの表データをCSVファイル化し外部表で取り込む等、直接参照しないアプローチを考えたほうがよいだろう。注1)
mediumint型 注1)
mediumint unsigned型 注1)
int型 注1)
int unsigned型 × 直接利用するのは避けたほうがよいだろう。参照するだけならば、MySQLの表データをCSVファイル化し外部表で取り込む等、直接参照しないアプローチを考えたほうがよいだろう。注1)
bigint型 × 直接利用するのは避けたほうがよいだろう。参照するだけならば、MySQLの表データをCSVファイル化し外部表で取り込む等、直接参照しないアプローチを考えたほうがよいだろう。注1)
bigint unsigned型 × 同上
float型 注1)
float unsigned型 注1)
double型 × 直接利用するのは避けたほうがよいだろう。参照するだけならば、MySQLの表データをCSVファイル化し外部表で取り込む等、直接参照しないアプローチを考えたほうがよいだろう。注1)
double unsigned型 × 同上
decimal(38,0)

double型と同じ精度ということなので、結果を見る限りdecimal(16,0)ぐらいまでなら利用できそうであるが、利用するのは避けたほうが無難かもしれない。どうしても利用したい場合には、Generic Connectivity以外のアプローチを考えたほうがよいかもしれない。例えば、参照だけならば、MySQLのデータをCSVファイル化し外部表で取り込む等。注1)

decimal(38,0) unsigned 同上
decimal(38,16) ×

直接利用するのは避けたほうがよいだろう。参照するだけならば、MySQLの表データをCSVファイル化し外部表で取り込む等、直接参照しないアプローチを考えたほうがよいだろう。注1)

decimal(38,16) unsigned × 同上

注1)数値型を扱う際にinsertやupdate文では、値が有効範囲を超えると数値が最大値、最小値に丸められるというMySQLの仕様に要注意。但し、MySQL5.0.2以降であればSQL_MODEの設定でエラーとして扱うこともできるようなので、それがうまく機能すれば回避することは可能かもしれない。(現時点では未確認)

次回、文字型の検証へつづく。

| | コメント (0) | トラックバック (0)

2006年2月21日 (火)

Mac De Oracle Heterogeneous! #44

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 8回目。

Generic Connectivity経由でdouble型と同型の符号なしにアクセスした結果。

PostgreSQL7.4.9の場合と同様にGeneric Connectivity経由での参照、更新は避けたほうがよい。

問合せの結果だけを載せる。(データの登録も行ったが結果は同じであったため省略)

1)MySQL4.0.25をGeneic Connectivity経由で問い合わせた結果。

CORYDORAS> select
2 "r_double",
3 "r_double_unsigned"
4 from
5 num_test_mysql4025_mac@oracle10g_win;

r_double r_double_unsigned
---------- -----------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-˜ 0
˜ 0
0 0
0 ˜
NULL NULL

中略

NULL NULL

25行が選択されました。

CORYDORAS>

2)MySQl4.1.13aをGeneric Connectivity経由で問い合わせた結果。
CORYDORAS> select
2 "r_double",
3 "r_double_unsigned"
4 from
5 num_test_mysql4113a_mac_sv@oracle10g_win;

r_double r_double_unsigned
---------- -----------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-˜ 0
˜ 0
0 0
0 ˜
NULL NULL

中略

NULL NULL

27行が選択されました。

CORYDORAS>


次につづく。

| | コメント (0) | トラックバック (0)

2006年2月20日 (月)

Mac De Oracle Heterogeneous! #43

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 7回目。

Generic Connectivity経由でfloat型と同型の符号なしにアクセスした結果。

MySQL4.0.2.25、 MySQL4.1.13aともにfloat型の利用は問題ないと思われる。


1)MySQL4.0.25をGeneric Connectivity経由で問い合わせた結果。

CORYDORAS> set numwidth 10
CORYDORAS> list
1 select
2 "r_float",
3 "r_float_unsigned"
4 from
5* num_test_mysql4025_mac@oracle10g_win
CORYDORAS> /

r_float r_float_unsigned
---------- ----------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-3.400E+38 0
3.4000E+38 NULL
-1.200E-38 1.2000E-38
1.2000E-38 3.4000E+38
NULL NULL

中略

NULL NULL

25行が選択されました。

2)MySQL4.1.13aをGeneric Connectivity経由で問い合わせた結果。
CORYDORAS> list
1 select
2 "r_float",
3 "r_float_unsigned"
4 from
5* num_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /

r_float r_float_unsigned
---------- ----------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-3.400E+38 0
3.4000E+38 NULL
-1.200E-38 1.2000E-38
1.2000E-38 3.4000E+38
NULL NULL

中略

NULL NULL

27行が選択されました。

CORYDORAS>

3)MySQL4.0.25へ最大値、最小値、アンダーフローする値、オーバーフローする値を登録した結果。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_float","r_float_unsigned")
2 values(-3.4e38,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_float","r_float_unsigned")
2 values(3.4e38,null);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_float","r_float_unsigned")
2 values(-1.2e-38,1.2e-38)
3 ;

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_float","r_float_unsigned")
2 values(1.2e-38,3.4e38);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_float","r_float_unsigned")

2 values(-3.5e38,-1.0e38);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_float","r_float_unsigned")
2 values(3.5e38,3.5e38);

1行が作成されました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_float",
7 a."r_float_unsigned"
8 from
9 num_test_mysql4025_mac@oracle10g_win a
10 )
11 where
12 "rownum" > 25;

rownum r_float r_float_unsigned
---------- ---------- ----------------
26 -3.400E+38 0
27 3.4000E+38 NULL
28 -1.200E-38 1.2000E-38
29 1.2000E-38 3.4000E+38
30 -3.403E+38 0
31 3.4028E+38 3.4028E+38

6行が選択されました。

CORYDORAS> rollback;

ロールバックが完了しました。


4)MySQL4.1.13aへ最大値、最小値、アンダーフローする値、オーバーフローする値を登録した結果。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_float","r_float_unsigned")
2 values(-3.4e38,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_float","r_float_unsigned")
2 values(3.4e38,null);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g 2 _win("r_float","r_float_unsigned")
2 values(-1.2e-38,1.2e-38);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_float","r_float_unsigned")
2 values(1.2e-38,3.4e38);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_float","r_float_unsigned")
2 values(-3.5e38,-1.0e38);

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_float","r_float_unsigned")
2 values(3.5e38,3.5e38);

1行が作成されました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_float",
7 a."r_float_unsigned"
8 from
9 num_test_mysql4113a_mac_sv@oracle10g_win a
10 )
11 where
12 "rownum" > 27;

rownum r_float r_float_unsigned
---------- ---------- ----------------
28 -3.400E+38 0
29 3.4000E+38 NULL
30 -1.200E-38 1.2000E-38
31 1.2000E-38 3.4000E+38
32 -3.403E+38 0
33 3.4028E+38 3.4028E+38

6行が選択されました。

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>


次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月19日 (日)

Mac De Oracle Heterogeneous! #42

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 6回目。

Generic Connectivity経由でbigint型と同型の符号なしにアクセスした結果。

MySQL4.0.2.25、 MySQL4.1.13aともにbigint型は Generic Connectivity経由で利用しないほうがよいだろう。

1)MySQL4.0.25をGeneric Connectivity経由で問い合わせた結果。

0のはずが、48と表示される。最大値、最長値とも設定した値とは異なる値が表示されている。

CORYDORAS> select
2 "r_bigint",
3 "r_bigint_unsigned"
4 from
5 num_test_mysql4025_mac@oracle10g_win;

r_bigint r_bigint_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
48 48
48 48
NULL NULL

中略

NULL NULL
15537418697586989 48
14134441877320249 14697404732553265
NULL NULL

中略

NULL NULL

25行が選択されました。

2)MySQL4.1.13aをGeneric Connectivity経由で問い合わせた結果。

1)の場合と同じくNG。

CORYDORAS> 
CORYDORAS> list
1 select
2 "r_bigint",
3 "r_bigint_unsigned"
4 from
5* num_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /

r_bigint r_bigint_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
48 48
48 48
NULL NULL

中略

NULL NULL
15537418697586989 48
14134441877320249 14697404732553265
15537418697586989 14697404732553265
15537418697586989 14697404732553265
NULL NULL

中略

NULL NULL

27行が選択されました。

3)MySQL4.0.25へ最大値、最小値、許容範囲を超える値を登録した結果。

登録した値とは全く異なる値になってしまう。

CORYDORAS> 
CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(-9223372036854775808,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(9223372036854775807,18446744073709551615);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(-9223372036854775809, -1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(9223372036854775808, 18446744073709551616);

1行が作成されました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_bigint",
7 a."r_bigint_unsigned"
8 from
9 num_test_mysql4025_mac@oracle10g_win a
10 )
11 where
12 "rownum" > 25;

rownum r_bigint r_bigint_unsigned
---------------------------------------- ---------------------------------------- ----------------------------------------
26 15537418697586989 48
27 14134441877320249 14697404732553265
28 15537418697586989 14697404732553265
29 15537418697586989 14697404732553265

CORYDORAS>
CORYDORAS> rollback;

ロールバックが完了しました。

4)MySQL4.1.13aへ最大値、最小値、許容範囲を超える値を登録。

3)と同じ結果。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(-9223372036854775808,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(9223372036854775807,18446744073709551615);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(-9223372036854775809, -1);

1行が作成されました。

CORYDORAS> insert int 2 o num_test_mysql4113a_mac_sv@oracle10g_win("r_bigint","r_bigint_unsigned")
2 values(9223372036854775808, 18446744073709551616);

1行が作成されました。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_bigint",
7 a."r_bigint_unsigned"
8 from
9 num_test_mysql4113a_mac_sv@oracle10g_win a
10 )
11 where
12* "rownum" > 27
CORYDORAS> /

rownum r_bigint r_bigint_unsigned
---------------------------------------- ---------------------------------------- ----------------------------------------
28 15537418697586989 48
29 14134441877320249 14697404732553265
30 15537418697586989 14697404732553265
31 15537418697586989 14697404732553265

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>

次へつづく。

| | コメント (0) | トラックバック (0)

2006年2月18日 (土)

Mac De Oracle Heterogeneous! #41

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 5回目。

Generic Connectivity経由でint型と同型の符号なしにアクセスした結果。

MySQL4.0.2.25、 MySQL4.1.13aともにint型の符号なしは NG。 Generic Connectivity経由で、符号なしint型は利用しないほうがよいだろう。

1)MySQL4.0.25をGeneric Connectivity経由で問い合わせた結果。

CORYDORAS> list
1 select
2 "r_int",
3 "r_int_unsigned"
4 from
5* num_test_mysql4025_mac@oracle10g_win
CORYDORAS> /

r_int r_int_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-2147483648 0
2147483647 -1
NULL NULL

中略

NULL NULL

25行が選択されました。

2)MySQL4.1.13aをGeneric Connectivity経由で問い合わせた結果。

CORYDORAS> list
1 select
2 "r_int",
3 "r_int_unsigned"
4 from
5* num_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /

r_int r_int_unsigned
---------------------------------------- ----------------------------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-2147483648 0
2147483647 -1
NULL NULL

中略

NULL NULL

27行が選択されました。

CORYDORAS>

3)MySQL4.0.25へ最大値、最小値、許容範囲を超える値を登録した結果。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_int", "r_int_unsigned")
2 values(-2147483648,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_int", "r_int_unsigned")
2 values(2147483647,4294967295);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_int", "r_int_unsigned")
2 values(-2147483649,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_int", "r_int_unsigned")
2 values(2147483648,4294967296);

1行が作成されました。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_int",
7 a."r_int_unsigned"
8 from
9 num_test_mysql4025_mac@oracle10g_win a
10 )
11 where
12* "rownum" > 25
CORYDORAS> /

rownum r_int r_int_unsigned
---------------------------------------- ---------------------------------------- ----------------------------------------
26 -2147483648 0
27 2147483647 -1
28 -2147483648 0
29 2147483647 -1

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS>

4)MySQL4.1.13aへ最大値、最小値、許容範囲を超える値を登録した結果。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_int", "r_int_unsigned")
2 values(-2147483648,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_int", "r_int_unsigned")
2 values(2147483647,4294967295);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@o 2 racle10g_win("r_int", "r_int_unsigned")
2 values(-2147483649,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_int", "r_int_unsigned")
2 values(2147483648,4294967296);

1行が作成されました。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_int",
7 a."r_int_unsigned"
8 from
9 num_test_mysql4113a_mac_sv@oracle10g_win a
10 )
11 where
12* "rownum" > 27
CORYDORAS> /

rownum r_int r_int_unsigned
---------------------------------------- ---------------------------------------- ----------------------------------------
28 -2147483648 0
29 2147483647 -1
30 -2147483648 0
31 2147483647 -1

CORYDORAS>
CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>

次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月17日 (金)

Mac De Oracle Heterogeneous! #40

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 4回目。

Generic Connectivity経由でmediumint型と同型の符号なしにアクセスした結果。

tinyint,smallint型とは異なり、符号なしでも問題はない。

1)MySQL4.0.25への問合せ。

CORYDORAS> select
2 "r_mediumint",
3 "r_mediumint_unsigned"
4 from
5 num_test_mysql4025_mac@oracle10g_win;

r_mediumint r_mediumint_unsigned
----------- --------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-8388608 0
8388607 16777215
NULL NULL

中略

NULL NULL

25行が選択されました。

CORYDORAS>

2)MySQL4.0.25への最大値、最小値、及び、許容範囲を超える値の登録。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(-8388608,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(8388607,16777215);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(-8388609,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(8388608,16777216);

1行が作成されました。


CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_mediumint",
7 a."r_mediumint_unsigned"
8 from
9 num_test_mysql4025_mac@oracle10g_win a
10 )
11 where
12* "rownum" > 25
CORYDORAS> /

rownum r_mediumint r_mediumint_unsigned
---------- ----------- --------------------
26 -8388608 0
27 8388607 16777215
28 -8388608 0
29 8388607 16777215

CORYDORAS> rollback;

ロールバックが完了しました。

3)MySQL4.1.13aへの問合せ。

CORYDORAS> select
2 "r_mediumint",
3 "r_mediumint_unsigned"
4 from
5 num_test_mysql4113a_mac_sv@oracle10g_win;

r_mediumint r_mediumint_unsigned
----------- --------------------
NULL NULL
0 0
0 0
NULL NULL

中略

NULL NULL
-8388608 0
8388607 16777215
NULL NULL

中略

NULL NULL

27行が選択されました。

4)MySQL4.1.13aへの最大値、最小値、及び、許容範囲を超える値の登録。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(-8388608,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(8388607,16777215);

1行が作成されました。

CORYDORAS> insert into num_test_mys 2 ql4113a_mac_sv@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(-8388609,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_mediumint", "r_mediumint_unsigned")
2 values(8388608,16777216);

1行が作成されました。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_mediumint",
7 a."r_mediumint_unsigned"
8 from
9 num_test_mysql4113a_mac_sv@oracle10g_win a
10 )
11 where
12* "rownum" > 27
CORYDORAS> /

rownum r_mediumint r_mediumint_unsigned
---------- ----------- --------------------
28 -8388608 0
29 8388607 16777215
30 -8388608 0
31 8388607 16777215

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>

次回へつづく。

| | コメント (0) | トラックバック (0)

2006年2月16日 (木)

Mac De Oracle Heterogeneous! #39

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 3回目。

1) smallint型及び、同型の符号なし。

tinyint型の場合と同様に符号なしは、NG。

CORYDORAS> select
2 "r_smallint",
3 "r_smallint_unsigned"
4 from
5 num_test_mysql4025_mac@oracle10g_win;

r_smallint r_smallint_unsigned
---------- -------------------
NULL NULL
0 0
0 0
NULL NULL
NULL NULL
-32768 0
32767 -1
NULL NULL

中略

NULL NULL

25行が選択されました。

CORYDORAS>

1−1)MySQL4.0.25への最大値と最小値、許容範囲を超える値の登録。

これもMySQL側の挙動の通りだが、符号なしは NG。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(-32768,0);

1行が作成されました。

insert into num_test_mysql4025_mac@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(32767,65535);

1行が作成されました。

insert into num_test_mysql4025_mac@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(-32769,-1);

1行が作成されました。

insert into num_test_mysql4025_mac@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(32768,65536);

1行が作成されました。


CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_smallint",
7 a."r_smallint_unsigned"
8 from
9 num_test_mysql4025_mac@oracle10g_win a
10 )
11 where
12* "rownum" > 25
CORYDORAS> /

rownum r_smallint r_smallint_unsigned
---------- ---------- -------------------
26 -32768 0
27 32767 -1
28 -32768 0
29 32767 -1

CORYDORAS>

CORYDORAS> rollback;

ロールバックが完了しました。

1−2)MySQL4.1.13aへの最大値と最小値、許容範囲を超える値の登録。

これもMySQL側の挙動の通りだが、符号なしは NG。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(-32768,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(32767,65535);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac 2 _sv@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(-32769,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_smallint", "r_smallint_unsigned")
2 values(32768,65536);

1行が作成されました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_smallint",
7 a."r_smallint_unsigned"
8 from
9 num_test_mysql4113a_mac_sv@oracle10g_win a
10 )
11 where
12 "rownum" > 27;

rownum r_smallint r_smallint_unsigned
---------- ---------- -------------------
28 -32768 0
29 32767 -1
30 -32768 0
31 32767 -1

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS>

次回へつづく。

| | コメント (0) | トラックバック (0)

2006年2月15日 (水)

Mac De Oracle Heterogeneous! #38

数値型のつづき。
Generic Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセス 2回目。 tinyint型と同型の符号なし。

1)MySQLのtinyint型及び、同型の符号なしの検証。

  tinyint型は問題ないのだが、符号なしは NG。

1−1)MySQL4.1.13aにGeneric Connectivity経由で問合せをした結果

CORYDORAS> list
1 select
2 "r_tinyint",
3 "r_tinyint_unsigned"
4 from
5* num_test_mysql4113a_mac_sv@oracle10g_win
CORYDORAS> /

r_tinyint r_tinyint_unsigned
---------- ------------------
NULL NULL
0 0
0 0
-128 0
127 -1
NULL NULL
NULL NULL

中略

NULL NULL

27行が選択されました。

CORYDORAS>

1−2)MySQL4.0.25にGeneric Connectivity経由で問合せをした結果

CORYDORAS> list
1 select
2 "r_tinyint",
3 "r_tinyint_unsigned"
4 from
5* num_test_mysql4025_mac@oracle10g_win
CORYDORAS> /

r_tinyint r_tinyint_unsigned
---------- ------------------
NULL NULL
0 0
0 0
-128 0
127 -1
NULL NULL

中略

NULL NULL

25行が選択されました。

CORYDORAS>

1−3)MySQL4.1.13aへGeneric Connectivity経由でインサート文を発行。
   各型の最小値、最大値、許容範囲を超える値を登録。

MySQL上ではワーニングが返るが、Generic Connectivity経由では正常に処理される。MySQL側では許容範囲を超える数値は丸められ、最小値、最大値に置換される。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_tinyint", "r_tinyint_unsigned")
2 values(-128,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_tinyint","r_tinyint_unsigned")
2 values(127,255);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_tinyint","r_tinyint_unsigned")
2 values(-129,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4113a_mac_sv@oracle10g_win("r_tinyint","r_tinyint_unsigned")
2 values(128,256);

1行が作成されました。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_tinyint",
7 a."r_tinyint_unsigned"
8 from
9 num_test_mysql4113a_mac_sv@oracle10g_win a
10 )
11 where
12* "rownum" > 27
CORYDORAS> /

rownum r_tinyint r_tinyint_unsigned
---------- ---------- ------------------
28 -128 0
29 127 -1
30 -128 0
31 127 -1

CORYDORAS>

CORYDORAS> rollback;

ロールバックが完了しました。

1−4)MySQL4.0.25へGeneric Connectivity経由でインサート文を発行。
    各型の最小値、最大値、許容範囲を超える値を登録。

結果は、MySQL4.1.13aと同じ。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_tinyint", "r_tinyint_unsigned")
2 values(-128,0);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_tinyint","r_tinyint_unsigned")
2 values(127,255);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_tinyint","r_tinyint_unsigned")
2 values(-129,-1);

1行が作成されました。

CORYDORAS> insert into num_test_mysql4025_mac@oracle10g_win("r_tinyint","r_tinyint_unsigned")
2 values(128,256);

1行が作成されました。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a."r_tinyint",
7 a."r_tinyint_unsigned"
8 from
9 num_test_mysql4025_mac@oracle10g_win a
10 )
11 where
12* "rownum" > 25
CORYDORAS> /

rownum r_tinyint r_tinyint_unsigned
---------- ---------- ------------------
26 -128 0
27 127 -1
28 -128 0
29 127 -1

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS> select count(*) from num_test_mysql4025_mac@oracle10g_win;

COUNT(*)
----------
25

CORYDORAS>

次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月14日 (火)

Mac De Oracle Heterogeneous! #37

数値型のつづき。MySQLでの数値型の癖はある程度見えたので、ここからはGeneric Connectivity経由でMySQL4.0.25及び、MySQL4.1.13aの数値型にアクセスし、その挙動を検証する。

以下のような経路でアクセスしている

gencon_blog_img1

Oracle10g R1(Windows XP Professional)には、num_test_mysql4025_mac(MySQL4.0.25のnum_test表へのシノニム)とnum_test_mysql4113a_mac_sv(MySQL4.1.13aのnum_test表へのシノニム)という2つのシノニムを作成しておく。

CORYDORAS> select synonym_name from user_synonyms@oracle10g_win;

SYNONYM_NAME
------------------------------
NUM_TEST_POSTGRESQL749_MAC
NUM_TEST_MYSQL4113A_MAC_SV
NUM_TEST_MYSQL4025_MAC
DATE_TEST_MYSQL4026_WIN
DATE_TEST_MYSQL4113A_MAC_SV
DATE_TEST_POSTGRESQL749_MAC
EMP_MYSQL4025_MAC
INNO_EMP_MYSQL4025_MAC
EMP_MYSQL4026_WIN
EMP_MYSQL4113A_MAC_SV
EMP_POSTGRESQL749_MAC
ORACLE_EMP_MYSQL4026_WIN

12行が選択されました。

CORYDORAS>

おっと! いきなり問題発生。27行しかないのに count(*)の結果が14130行とは? 問題はMySQL側にあるように思える。MySQL4.0.25では正しい結果が取得できるが、MySQl4.1.13aでは見ての通り。試しに、execute immediate文で試してみたが同じ結果だった。

さて、どうすればいいか? 

ということで、回避策としてrownumの最大値を取得するという方法(なかなかキツいね。)

CORYDORAS> select count(*) from num_test_mysql4113a_mac_sv@oracle10g_win;

COUNT(*)
----------
14130

CORYDORAS> select count(*) from num_test_mysql4025_mac@oracle10g_win;

COUNT(*)
----------
25

CORYDORAS>

CORYDORAS> set serveroutput on;
CORYDORAS> list
1 declare
2 rows pls_integer;
3 begin
4 execute immediate 'select count(*) as ctr from num_test_mysql4113a_mac_sv@oracle10g_win' into rows;
5 dbms_output.put_line(rows);
6* end;
CORYDORAS> /
14130

PL/SQLプロシージャが正常に完了しました。

CORYDORAS> select max(rownum) from num_test_mysql4113a_mac_sv@oracle10g_win;

MAX(ROWNUM)
----------------------------------------
27

CORYDORAS>

さて、最初から凹み気味だが、MySQLの数値型は、Oracleではすべて number型 にマッピングされる。

CORYDORAS> list
1 select
2 dump("r_tinyint") as "tinyint",
3 dump("r_tinyint_unsigned") as "tinyint_unsigned",
4 dump("r_smallint") as "smallint",
5 dump("r_smallint_unsigned") as "smallint_unsigned",
6 dump("r_mediumint") as "mediumint",
7 dump("r_mediumint_unsigned") as "mediumint_unsigned",
8 dump("r_int") as "int",
9 dump("r_int_unsigned") as "int_unsigned"
10 from
11 num_test_mysql4025_mac@oracle10g_win
12 where
13* rownum <= 2
CORYDORAS> /

tinyint tinyint_unsigned smallint smallint_unsigne mediumint mediumint_unsign int int_unsigned
---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ----------------
NULL NULL NULL NULL NULL NULL NULL NULL
Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128
CORYDORAS>

次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月13日 (月)

Mac De Oracle Heterogeneous! #36

数値型の検証のつづき(MySQL編の第4回目)。。decimal型のdecimal(38,0)とdecimal(38,16)、それらの型で符号なし。

1)decimal型

1−1)decimal(38,0)と符号なしdecimal(38,0)

精度はdouble型と同じであるとマニュアルに記載されているので、decimal(38,0)の場合だとOracleのnumber(38,0)より精度が劣るようだ。
decimal型をOracleに取り込むだけなら、精度の範囲内なので利用できそうであるが、OracleからMySQLへ登録したり更新する場合は注意が必要だ。decimal(16,0)くらいなら利用できる可能性はあるが実際に確認してから利用するか否かを決めた方がよさそうである。

mysql> insert into
-> num_test(r_decimal_38, r_decimal_38_unsigned)
-> values(
-> 99999999999999999999999999999999999999,
-> 0
-> );
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_decimal_38, r_decimal_38_unsigned)
-> values(
-> -99999999999999999999999999999999999999,
-> 99999999999999999999999999999999999999
-> );
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.07 sec)

mysql> insert into
-> num_test(r_decimal_38, r_decimal_38_unsigned)
-> values(100000000000000000000000000000000000000,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_decimal_38,r_decimal_38_unsigned)
-> values(-100000000000000000000000000000000000000,100000000000000000000000000000000000000);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_decimal_38,
-> r_decimal_38_unsigned
-> from
-> num_test
-> limit
-> 21,-1;
+-----------------------------------------+----------------------------------------+
| r_decimal_38 | r_decimal_38_unsigned |
+-----------------------------------------+----------------------------------------+
| 99999999999999997748809823456034029568 | 0 |
| -99999999999999997748809823456034029568 | 99999999999999997748809823456034029568 |
| 99999999999999997748809823456034029568 | 0 |
| -99999999999999997748809823456034029568 | 99999999999999997748809823456034029568 |
+-----------------------------------------+----------------------------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.39 sec)

mysql>

MySQL4.0.25では正常に見えるが実は、丸め処理が行われている。MySQL4.1.13aで同じインサート文を発行すると2件のワーニングが返される。内容は以下の通り out of range。そして、r_decimal_38の精度は38桁なのだが39桁になってしまった。MySQLのバージョン毎に対応を変えるというか、変えられるような作り込みが必要になる可能性もでてきた。
mysql>
mysql> insert into
-> num_test(r_decimal_38, r_decimal_38_unsigned)
-> values(
-> 99999999999999999999999999999999999999,
-> 0
-> );
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> insert into
-> num_test(r_decimal_38, r_decimal_38_unsigned)
-> values(
-> -99999999999999999999999999999999999999,
-> 99999999999999999999999999999999999999
-> );
Query OK, 1 row affected, 2 warnings (0.01 sec)

mysql> show warnings;
+---------+------+--------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------------------------+
| Warning | 1264 | Data truncated; out of range for column 'r_decimal_38' at row 1 |
| Warning | 1264 | Data truncated; out of range for column 'r_decimal_38_unsigned' at row 1 |
+---------+------+--------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.06 sec)


mysql> edit
-> \¥g
+-----------------------------------------+----------------------------------------+
| r_decimal_38 | r_decimal_38_unsigned |
+-----------------------------------------+----------------------------------------+
| 100000000000000035527741686413195739136 | 0 |
| -99999999999999999999999999999999999999 | 99999999999999999999999999999999999999 |
+-----------------------------------------+----------------------------------------+
2 rows in set (0.00 sec)

mysql>

1−2)decimal(38,16)と符号なしdecimal(38,16)

これは問題無さそうだと思い見逃しそうになったのだが、よくよく結果をみてみると、decimal(38.16)で最小値はよいのだが、最大値がまずい。精度が22桁なのに、最大値が23桁になっている。(これも不具合だろうか?。Generic Connectivity経由ではdecimal型も利用しないほうがよいかもしれない。まだ、テストしていないので使えるか不明だが。。)
以下、MySQL4.0.25での実行結果。

mysql> insert into
-> num_test(r_decimal_38_16, r_decimal_38_16_unsigned)
-> values
-> (-9999999999999999999999.9999999999999999,0),
-> ( 9999999999999999999999.9999999999999999,9999999999999999999999.9999999999999999);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 2

mysql> commit;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into
-> num_test(r_decimal_38_16, r_decimal_38_16_unsigned)
-> values(-10000000000000000000000.99999999999999995,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_decimal_38_16, r_decimal_38_16_unsigned)
-> values(10000000000000000000000.99999999999999994,10000000000000000000000.99999999999999995);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_decimal_38_16,
-> r_decimal_38_16_unsigned
-> from
-> num_test
-> limit
-> 23,-1;
+------------------------------------------+-----------------------------------------+
| r_decimal_38_16 | r_decimal_38_16_unsigned |
+------------------------------------------+-----------------------------------------+
| -9999999999999999999999.9999999999999999 | 0.0000000000000000 |
| 10000000000000000000000.0000000000000000 | 9999999999999999999999.9999999999999999 |
| -9999999999999999999999.9999999999999999 | 0.0000000000000000 |
| 10000000000000000000000.0000000000000000 | 9999999999999999999999.9999999999999999 |
+------------------------------------------+-----------------------------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.38 sec)

mysql>

以下、MySQL4.1.13aでの実行結果。精度が1桁多くなる現象もあるが値も微妙に違う。
mysql> insert into
-> num_test(r_decimal_38_16, r_decimal_38_16_unsigned)
-> values
-> (-9999999999999999999999.9999999999999999,0),
-> ( 9999999999999999999999.9999999999999999,9999999999999999999999.9999999999999999);
Query OK, 2 rows affected, 2 warnings (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 2

mysql>
mysql> commit;
Query OK, 0 rows affected (0.05 sec)

mysql>
mysql> insert into
-> num_test(r_decimal_38_16, r_decimal_38_16_unsigned)
-> values(-10000000000000000000000.99999999999999995,-1);
Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql>
mysql> insert into
-> num_test(r_decimal_38_16, r_decimal_38_16_unsigned)
-> values(10000000000000000000000.99999999999999994,10000000000000000000000.99999999999999995);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select
-> r_decimal_38_16,
-> r_decimal_38_16_unsigned
-> from
-> num_test
-> limit
-> 25,99;
+------------------------------------------+-----------------------------------------+
| r_decimal_38_16 | r_decimal_38_16_unsigned |
+------------------------------------------+-----------------------------------------+
| -9999999999999999999999.9999999999999999 | 0.0000000000000000 |
| 10000000000000004194304.0000000000000000 | 9999999999999999999999.9999999999999999 |
| -9999999999999999999999.9999999999999999 | 0.0000000000000000 |
| 10000000000000002097152.0000000000000000 | 9999999999999999999999.9999999999999999 |
+------------------------------------------+-----------------------------------------+
4 rows in set (0.00 sec)

mysql>

長いので次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月12日 (日)

Mac De Oracle Heterogeneous! #35

数値型の検証のつづき(MySQL編の第3回目)・・・float型、double型及び、各型の符号なし

1)float型
MySQL4.0.25とMySQL4.1.13aは同じ挙動であった。オーバーフロー、アンダーフローを丸めてしまう点も同じ。

mysql> insert into 
-> num_test(r_float, r_float_unsigned)
-> values(-3.4e38,0),(3.4e38,null),(-1.2e-38,1.2e-38),(1.2e-38,3.4e38);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into
-> num_test(r_float, r_float_unsigned)
-> values(-3.5e38,-1.0e38);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_float, r_float_unsigned)
-> values(3.5e38,3.5e38);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_float,
-> r_float_unsigned
-> from
-> num_test
-> limit
-> 13,-1;
+--------------+------------------+
| r_float | r_float_unsigned |
+--------------+------------------+
| -3.4e+38 | 0 |
| 3.4e+38 | NULL |
| -1.2e-38 | 1.2e-38 |
| 1.2e-38 | 3.4e+38 |
| -3.40282e+38 | 0 |
| 3.40282e+38 | 3.40282e+38 |
+--------------+------------------+
6 rows in set (0.00 sec)

mysql> rollback;

ちなみに、MySQl4.1.13aで同じインサート文を実行すると、ワーニングが2件返され、オーバフローした値、及びアンダーフローした値は、それぞれ最大値、最小値に丸めらる。

mysql> insert into
-> num_test(r_float, r_float_unsigned)
-> values(-3.5e38,-1.0e38);
Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql> show warnings;
+---------+------+---------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------------------+
| Warning | 1264 | Data truncated; out of range for column 'r_float' at row 1 |
| Warning | 1264 | Data truncated; out of range for column 'r_float_unsigned' at row 1 |
+---------+------+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql>

2)double型
MySQL4.0.25は特に問題なさそうだが、MySQL4.1.13aではdouble型の値が0と−0となってしまった。(これも不具合だろう)。double unsigned型のアンダーフロー処理が改善された反面、double型のオーバフローとアンダーフローの丸め処理がデグっているように見える。

+------------+-------------------+
| r_double | r_double_unsigned |
+------------+-------------------+
| 2.3e-308 | 2.3e-308 |
| -2.3e-308 | 1.79e+308 |

となっているが、MySQL4.1.13aでは、double型の丸め処理に問題がありそうな結果だ。
+------------+-------------------+
| r_double | r_double_unsigned |
+------------+-------------------+
| 0 | 0 |
| -0 | 1.79e+308 |

以下、MySQL4.0.25でインサート文を実行した結果

mysql> insert into
-> num_test(r_double,r_double_unsigned)
-> values(-1.79e308,0),(1.79e308,0),(2.3e-308,2.3e-308),(-2.3e-308,1.79e308);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.08 sec)

mysql> select
-> r_double,
-> r_double_unsigned
-> from
-> num_test
-> limit
-> 17,-1;
+------------+-------------------+
| r_double | r_double_unsigned |
+------------+-------------------+
| -1.79e+308 | 0 |
| 1.79e+308 | 0 |
| 2.3e-308 | 2.3e-308 |
| -2.3e-308 | 1.79e+308 |
+------------+-------------------+
4 rows in set (0.00 sec)

mysql>

以下、MySQL4.1.13aでインサート文を実行した結果。MySQL4.0.25と比べ、double unsigned型のアンダーフローの丸め処理は改善されているようだが、double型のアンダーフロー及びオーバーフローの丸め処理は挙動がおかしくなってしまったようだ。
mysql> insert into
-> num_test(r_double,r_double_unsigned)
-> values(-1.79e308,0),(1.79e308,0),(2.3e-308,2.3e-308),(-2.3e-308,1.79e308);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql>
mysql> commit;
Query OK, 0 rows affected (0.08 sec)

mysql> select
-> r_double,
-> r_double_unsigned
-> from
-> num_test
-> limit
-> 19,99;
+------------+-------------------+
| r_double | r_double_unsigned |
+------------+-------------------+
| -1.79e+308 | 0 |
| 1.79e+308 | 0 |

| 0 | 0 |
| -0 | 1.79e+308 |
+------------+-------------------+
4 rows in set (0.00 sec)

以下のような結果からみても、おかしな挙動を示す。(取りあえず使う予定はないからよしとしておくか?!)

mysql> insert into num_test(r_double) values(0.5e-307);
Query OK, 1 row affected (0.00 sec)

mysql> select r_double from num_test limit 27,99;
+----------+
| r_double |
+----------+
| 5e-308 |
+----------+
1 row in set (0.00 sec)

mysql> insert into num_test(r_double) values(2.2e-307);
Query OK, 1 row affected (0.00 sec)

mysql> select r_double from num_test limit 27,99;
+----------+
| r_double |
+----------+
| 5e-308 |
| 0 |
+----------+
2 rows in set (0.00 sec)

mysql> insert into num_test(r_double) values(2.2e-306);
Query OK, 1 row affected (0.00 sec)

mysql> select r_double from num_test limit 27,99;
+----------+
| r_double |
+----------+
| 5e-308 |
| 0 |
| 2.2e-306 |
+----------+
3 rows in set (0.00 sec)

mysql>

長いので次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月11日 (土)

Mac De Oracle Heterogeneous! #34

数値型の検証のつづき(MySQL編の第2回目)。。。tinyint型、smallint型、mediumint型、int型、bigint型及び、各型の符号なし。

MySQL4.0.25での検証。(MySQL4.1.13aではワーニング返される点がことなるが大きな挙動の差はない。但し、不具合と思われる部分がいくつかある。)
MySQLの仕様なのだが数値型で定義した範囲を超える値を設定した場合はワーニング扱になっている、しかも、上限を超えれば最大値、下限を超えれば最小値に置き換えられる。ちなみに私の知っている商用RDBMSでこのような挙動をするものはないので私にとっては嫌な特徴の一つ。Oracleだけをやってきた方は、”ハマ”りそうな点なので注意しておいたほうがいいだろう。(複数行インサート文では精度超過でワーニングがでるが、MySQL4.0.xでは単一行をインサートする場合はワーニングもでないので要注意。)


1)tinyint型と符号なしtinyint型


Generic Connectivityで扱う場合にも問題は無さそうな気がするが、前述した通り、tinyint型及び、符号なしtinyint型で表現できる範囲を超えた値を設定すると最小値及び最大値に置き換えられてしまうので注意したほうがよい。

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(-128,0);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(127,255);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select
-> r_tinyint,
-> r_tinyint_unsigned
-> from
-> num_test
-> limit
-> 3,-1;
+-----------+--------------------+
| r_tinyint | r_tinyint_unsigned |
+-----------+--------------------+
| -128 | 0 |
| 127 | 255 |
+-----------+--------------------+
2 rows in set (0.01 sec)

mysql>


MySQL4.0.25でも表現可能な範囲を超えた値を設定した場合には複数行インサート文ではワーニングが返される。
mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(-129,-1), (128,256);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 4

mysql>
mysql> select
-> r_tinyint,
-> r_tinyint_unsigned
-> from
-> num_test
-> limit
-> 3,-1;
+-----------+--------------------+
| r_tinyint | r_tinyint_unsigned |
+-----------+--------------------+
| -128 | 0 |
| 127 | 255 |
| -128 | 0 |
| 127 | 255 |
+-----------+--------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(-129, -1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(128,256);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_tinyint,
-> r_tinyint_unsigned
-> from
-> num_test
-> limit
-> 3,-1;
+-----------+--------------------+
| r_tinyint | r_tinyint_unsigned |
+-----------+--------------------+
| -128 | 0 |
| 127 | 255 |
| -128 | 0 |
| 127 | 255 |
+-----------+--------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql>

2)smallint型と符号なしsmallint型

mysql> insert into
-> num_test(r_smallint, r_smallint_unsigned)
-> values(-32768,0), (32767,65535);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_smallint, r_smallint_unsigned)
-> values(-32769,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_smallint, r_smallint_unsigned)
-> values(32768,65536);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_smallint,
-> r_smallint_unsigned
-> from
-> num_test
-> limit
-> 5,-1;
+------------+---------------------+
| r_smallint | r_smallint_unsigned |
+------------+---------------------+
| -32768 | 0 |
| 32767 | 65535 |
| -32768 | 0 |
| 32767 | 65535 |
+------------+---------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql>

3)mediumint型と符号nasimediumint型

mysql> insert into
-> num_test(r_mediumint, r_mediumint_unsigned)
-> values(-8388608,0), (8388607,16777215);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

以下のインサート文で表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_mediumint, r_mediumint_unsigned)
-> values(-8388609,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_mediumint, r_mediumint_unsigned)
-> values(8388608,16777216);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_mediumint,
-> r_mediumint_unsigned
-> from
-> num_test
-> limit 7,-1;
+-------------+----------------------+
| r_mediumint | r_mediumint_unsigned |
+-------------+----------------------+
| -8388608 | 0 |
| 8388607 | 16777215 |
| -8388608 | 0 |
| 8388607 | 16777215 |
+-------------+----------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.38 sec)

mysql>

4)int型と符号なしint型

mysql> insert into
-> num_test(r_int, r_int_unsigned)
-> values(-2147483648,0), (2147483647,4294967295);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_int, r_int_unsigned)
-> values(-2147483649,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_int, r_int_unsigned)
-> values(2147483648,4294967296);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_int,
-> r_int_unsigned
-> from
-> num_test
-> limit
-> 9,-1;
+-------------+----------------+
| r_int | r_int_unsigned |
+-------------+----------------+
| -2147483648 | 0 |
| 2147483647 | 4294967295 |
| -2147483648 | 0 |
| 2147483647 | 4294967295 |
+-------------+----------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.39 sec)

mysql>

5)bigint型と符号なしbigint型 

3行目のインサート文では、符号なしbigint型に −1 を設定しているが丸められて 0 にはならなず、符号なしbigint型の最大値が設定される。4行目のインサート文では、正の最大値を超える値(9223372036854775808)を設定してるにもかかわらず、負の最大値が設定されている。 (不具合だと思われる。)

mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775808,0), (9223372036854775807,18446744073709551615);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775809, -1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(9223372036854775808, 18446744073709551616);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_bigint,
-> r_bigint_unsigned
-> from
-> num_test
-> limit
-> 11,-1;
+----------------------+----------------------+
| r_bigint | r_bigint_unsigned |
+----------------------+----------------------+
| -9223372036854775808 | 0 |
| 9223372036854775807 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
+----------------------+----------------------+
4 rows in set (0.00 sec)

mysql>


尚、MySQL4.1.13aでは3行目と4行目のインサート文でワーニングが1件返される。(ワーニングは2件じゃないのかな? これも不具合のようだが・・・。)
5.x以降ではどのようになるかは分からないが、少なくともMySQL4.x台を対象にしたGeneric Connectivityで、bigint型は利用しないほうがよいだろう。(厳密に範囲チェックし精度を超えないようにすればなんとかなるかもしれないが・・・・・所詮そのプログラムも人が作るもの。バグがないとも限らない。)

mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775808,0), (9223372036854775807,18446744073709551615);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql>
mysql> commit;
Query OK, 0 rows affected (0.07 sec)

mysql>
以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775809, -1);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql>
mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(9223372036854775808, 18446744073709551616);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select
-> r_bigint,
-> r_bigint_unsigned
-> from
-> num_test
-> limit
-> 11,99;
+----------------------+----------------------+
| r_bigint | r_bigint_unsigned |
+----------------------+----------------------+
| -9223372036854775808 | 0 |
| 9223372036854775807 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
+----------------------+----------------------+
4 rows in set (0.00 sec)

mysql>

次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月10日 (金)

Mac De Oracle Heterogeneous! #33

つづきです。数値型の検証(MySQL編の第一回目)。。。PostgreSQLとは一味違った癖がありそうな予感。

赤で囲まれたデータベースを利用した。
gencon_blog_img33

MySQL4.0.25で、null、0、そして空文字を設定した。PostgreSQLやOracleとは異なり、空文字を設定すると0が設定されてしまう。PostgreSQLやOracleではエラーなので注意してたポイントだ。コーディング規約で空文字で数値型を初期化したりしないように縛っていたほうがよいかもしれない。
MySQL4.1.13aで同じことを行うと、仕様変更されたようで、空文字についてはワーニングが返される、しかし、エラーではないのでGeneric Connectivity経由ではエラーになることはないと予想される。この手のワーニングをエラー扱いにできれば、PostgreSQLやOracleと同じハンドリングで済むのだが。
マニュアルと読んでいたら、5.0.2以降では、sql_mode=traditionalとするとワーニングではなくエラーが返されるらしい。。今回は4.0と4.1なので使えない。

以下は、MySQL4.0.25で行った結果である。

mysql> insert into num_test
-> values(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
Query OK, 1 row affected (0.07 sec)

mysql> insert into num_test
-> values(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
Query OK, 1 row affected (0.39 sec)

mysql> insert into num_test
-> values('','','','','','','','','','','','','','','','','','');
Query OK, 1 row affected (0.37 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from num_test¥G
*************************** 1. row ***************************
r_tinyint: NULL
r_tinyint_unsigned: NULL
r_smallint: NULL
r_smallint_unsigned: NULL
r_mediumint: NULL
r_mediumint_unsigned: NULL
r_int: NULL
r_int_unsigned: NULL
r_bigint: NULL
r_bigint_unsigned: NULL
r_float: NULL
r_float_unsigned: NULL
r_double: NULL
r_double_unsigned: NULL
r_decimal_38: NULL
r_decimal_38_unsigned: NULL
r_decimal_38_16: NULL
r_decimal_38_16_unsigned: NULL
*************************** 2. row ***************************
r_tinyint: 0
r_tinyint_unsigned: 0
r_smallint: 0
r_smallint_unsigned: 0
r_mediumint: 0
r_mediumint_unsigned: 0
r_int: 0
r_int_unsigned: 0
r_bigint: 0
r_bigint_unsigned: 0
r_float: 0
r_float_unsigned: 0
r_double: 0
r_double_unsigned: 0
r_decimal_38: 0
r_decimal_38_unsigned: 0
r_decimal_38_16: 0.0000000000000000
r_decimal_38_16_unsigned: 0.0000000000000000
*************************** 3. row ***************************
r_tinyint: 0
r_tinyint_unsigned: 0
r_smallint: 0
r_smallint_unsigned: 0
r_mediumint: 0
r_mediumint_unsigned: 0
r_int: 0
r_int_unsigned: 0
r_bigint: 0
r_bigint_unsigned: 0
r_float: 0
r_float_unsigned: 0
r_double: 0
r_double_unsigned: 0
r_decimal_38: 0
r_decimal_38_unsigned: 0
r_decimal_38_16: 0.0000000000000000
r_decimal_38_16_unsigned: 0.0000000000000000
3 rows in set (0.00 sec)

mysql>

以下は、MySQL4.1.13aで行ったもの。空文字をインサートするとワーニングが返されていることがわかるだろうか?

mysql> insert into num_test
-> values(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
Query OK, 1 row affected (0.10 sec)

mysql> insert into num_test
-> values(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
Query OK, 1 row affected (0.07 sec)

mysql> insert into num_test
-> values('','','','','','','','','','','','','','','','','','');
Query OK, 1 row affected, 13 warnings (0.09 sec)

mysql> commit;


次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月 9日 (木)

Mac De Oracle Heterogeneous! #32

PostgreSQLに引き続き、MySQLで数値型の検証を行った。(一連の検証では、それほど深く検証している訳ではない。Generic ConnectivityでOracleと他のRDBMSを連携させようと思うのなら、さらに詳細な検証を行うことをお勧めする。MySQL4.0、4.1、5.0とかなりの仕様が変更されているので、各バージョンで挙動が異なることが予想されるのもその理由だ。)

PowerBook G4 MacOSX Tiger 10.4.4のMySQL4.0.25 standardと、PowerMac G5 MacOSX Tiger Server 10.4.3のMySQL4.1.13aで検証を行った。
以下のような経路でアクセスするのだが、

gencon_blog_img1


まず最初はMySQL側で数値型の癖を把握しておく。

Powerbook G4 の MySQL4.0.25及び、PowerMac G5の MySQL4.1.13aには以下の表を作成した。

mysql> desc num_test;
+--------------------------+-------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+-------------------------+------+-----+---------+-------+
| r_tinyint | tinyint(4) | YES | | NULL | |
| r_tinyint_unsigned | tinyint(3) unsigned | YES | | NULL | |
| r_smallint | smallint(6) | YES | | NULL | |
| r_smallint_unsigned | smallint(5) unsigned | YES | | NULL | |
| r_mediumint | mediumint(9) | YES | | NULL | |
| r_mediumint_unsigned | mediumint(8) unsigned | YES | | NULL | |
| r_int | int(11) | YES | | NULL | |
| r_int_unsigned | int(10) unsigned | YES | | NULL | |
| r_bigint | bigint(20) | YES | | NULL | |
| r_bigint_unsigned | bigint(20) unsigned | YES | | NULL | |
| r_float | float | YES | | NULL | |
| r_float_unsigned | float unsigned | YES | | NULL | |
| r_double | double | YES | | NULL | |
| r_double_unsigned | double unsigned | YES | | NULL | |
| r_decimal_38 | decimal(38,0) | YES | | NULL | |
| r_decimal_38_unsigned | decimal(38,0) unsigned | YES | | NULL | |
| r_decimal_38_16 | decimal(38,16) | YES | | NULL | |
| r_decimal_38_16_unsigned | decimal(38,16) unsigned | YES | | NULL | |
+--------------------------+-------------------------+------+-----+---------+-------+
18 rows in set (0.00 sec)

mysql>

MySQL4.0.25では問題なかった?!のだが、MySQL4.1.13aで同じDDLを実行するとワーニングがでる。
以下は、MySQL4.1.13aで表を作成したログ。

mysql> create table num_test
-> (
-> r_tinyint tinyint,
-> r_tinyint_unsigned tinyint unsigned,
-> r_smallint smallint,
-> r_smallint_unsigned smallint unsigned,
-> r_mediumint mediumint,
-> r_mediumint_unsigned mediumint unsigned,
-> r_int int,
-> r_int_unsigned int unsigned,
-> r_bigint bigint,
-> r_bigint_unsigned bigint unsigned,
-> r_float float,
-> r_float_unsigned float unsigned,
-> r_double double,
-> r_double_unsigned double unsigned,
-> r_decimal_38 decimal(38,0),
-> r_decimal_38_unsigned decimal(38,0) unsigned,
-> r_decimal_38_16 decimal(38,16),
-> r_decimal_38_16_unsigned decimal(38,16) unsigned
-> ) type=InnoDB;
Query OK, 0 rows affected, 1 warning (0.14 sec)

なんだろう。ワーニングがでるが表は作成されている。

mysql> desc num_test;
+--------------------------+-------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+-------------------------+------+-----+---------+-------+
| r_tinyint | tinyint(4) | YES | | NULL | |
| r_tinyint_unsigned | tinyint(3) unsigned | YES | | NULL | |
| r_smallint | smallint(6) | YES | | NULL | |
| r_smallint_unsigned | smallint(5) unsigned | YES | | NULL | |
| r_mediumint | mediumint(9) | YES | | NULL | |
| r_mediumint_unsigned | mediumint(8) unsigned | YES | | NULL | |
| r_int | int(11) | YES | | NULL | |
| r_int_unsigned | int(10) unsigned | YES | | NULL | |
| r_bigint | bigint(20) | YES | | NULL | |
| r_bigint_unsigned | bigint(20) unsigned | YES | | NULL | |
| r_float | float | YES | | NULL | |
| r_float_unsigned | float unsigned | YES | | NULL | |
| r_double | double | YES | | NULL | |
| r_double_unsigned | double unsigned | YES | | NULL | |
| r_decimal_38 | decimal(38,0) | YES | | NULL | |
| r_decimal_38_unsigned | decimal(38,0) unsigned | YES | | NULL | |
| r_decimal_38_16 | decimal(38,16) | YES | | NULL | |
| r_decimal_38_16_unsigned | decimal(38,16) unsigned | YES | | NULL | |
+--------------------------+-------------------------+------+-----+---------+-------+
18 rows in set (0.00 sec)

MySQL初心者なのでワーニングメッセージを表示させる方法が判らない。ヘルプで見てみると、 show warnings がそれらしいので試してみと
表のデータベースエンジンの指定は、typeではなく、engineを利用しなさいということらしい。とりあえず表は作成されたのでこのまま進めることにした。
(日付型の検証を行ったときにも出ていたのだが・・・・。確認漏れだ)

mysql> show warnings;
+---------+------+--------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------------------------+
| Warning | 1287 | 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead |
+---------+------+--------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

typeよりengineのほうが分かりやすいと思うが、type= としたらエラーにしちゃえばいいじゃん。ワーニングにしておく意味があるのだろうか。と思うのは私だけか?! 
とMySQLのオンラインマニュアルのcreate table文を確認してみたのだが、これに関連する記述が見当たらない。4.1のマニュアルを見ても、typeはengineのシノニムですという記述だけだったのだ。まぁ、マニュアルのメンテ漏れなのだろうとよい方に解釈して、次から engine=innoDB を使う事にする。
次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月 8日 (水)

Mac De Oracle Heterogeneous! #31

前回のつづきです。やっと、数値型(PostgreSQL編)の最終回。PostgreSQLの数値型をGeneric Connectivity経由でアクセス。

real型。関わっているシステムではほとんど使っていないのだが、念のために試してみた。なんとか使えそう。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(3.4e38);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(-3.4e38);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(1.2e-38);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(-1.2e-38);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(3.5e38);
insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(3.5e38)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: type "real" value out of range: overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(-3.5e38);
insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(-3.5e38)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: type "real" value out of range: overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(1.1e-38);
insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(1.1e-38)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: type "real" value out of range: underflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(-1.1e-38);
insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(-1.1e-38)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: type "real" value out of range: underflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(3.4e39);
insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(3.4e39)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: type "real" value out of range: overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(1.2e-39);
insert into num_test_postgresql749_mac@oracle10g_win("r_real") values(1.2e-39)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: type "real" value out of range: underflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11* "rownum" > 47
CORYDORAS> /

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
48 NULL NULL NULL NULL NULL 3.4000E+38 NULL
49 NULL NULL NULL NULL NULL -3.400E+38 NULL
50 NULL NULL NULL NULL NULL 1.2000E-38 NULL
51 NULL NULL NULL NULL NULL -1.200E-38 NULL

CORYDORAS>

double precision型。関わっているシステムでは全く利用されていなかったのだが、これまた興味本位で調べてみた。問合せでは、tilde表示されていた 1.79e308と-1.79e308だが insert時にはエラーになる。前述した通り、現時点ではdouble precisionは利用しない方が無難かな。
パススルーさせれば登録できなくもないと思うが。。。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_double") values(1.79e308);
insert into num_test_postgresql749_mac@oracle10g_win("r_double") values(1.79e308)
*
行1でエラーが発生しました。:
ORA-01426: 数値オーバーフローが発生しました


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_double") values(-1.79e308);
insert into num_test_postgresql749_mac@oracle10g_win("r_double") values(-1.79e308)
*
行1でエラーが発生しました。:
ORA-01426: 数値オーバーフローが発生しました


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_double") values(2.3e-308);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_double") values(-2.3e-308);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。


CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11 "rownum" > 51;

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
52 NULL NULL NULL NULL NULL NULL 0
53 NULL NULL NULL NULL NULL NULL 0

CORYDORAS>

========================
数値型のまとめ(PostgreSQL7.4.9編)

利用している psqlODBCドライバなどはこちら

数値型マッピング
PostgreSQL7.4.9Oracle10g R1Generic Connectivityでの利用備 考
smallint型number型
integer型
bigint型
numeric型 Oracle number型の精度と位置取り範囲内であれば問題なし。但し、精度と位置取りを超えていても格納されている値が精度と位置取り範囲内であれば利用できないこともないが、利用する際には十分な事前調査が必要。
real型
double precision型×Oracle number型の精度範囲内であれば利用できないこともないが、利用するのは避けたほうが無難。どうしても利用したいならOracleのbinary double型にマップするようなアプローチ方法を考えたほうがよいと思う。

numeric型の精度には注意が必要だが、double precision型以外はGeneric Connectivity経由でも違和感無く利用できそうだ。

次回は、MySQLで数値型の癖を確認することにする。

| | コメント (0) | トラックバック (0)

2006年2月 7日 (火)

Mac De Oracle Heterogeneous! #30

前回のつづきです。numeric型について少しだけ掘り下げてみた。

PostgreSQLのnumeric型の精度は無制限となっている。一方Oracleのnumber型はprecisionが38、scaleが−84から127となっている。
当然だが、Oracleのnumber型の精度と位置取りの制限を超える値の場合は問題が発生する。以下は精度を80に設定した場合の例である。
Oracle側では、number(80,0)とはできないのでエラーになってしまう。但し、PostgreSQL型の定義がnumeric(80,0)であっても、格納されている値が制限範囲内であれば問題はない。numeric型や、decimal型がPostgreSQL側で利用されている場合には、定義されているprecisionやscale及び、格納されている値の最小値、最大値も調査しておいたほうがよいだろう。

PostgreSQL側で numeric(80,0)の列を追加して、値を設定しておく。

pb17:˜ postgres$ psql -U scott postgresql749
Password:
Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=>
postgresql749=>
postgresql749=>
postgresql749=> ¥d num_test
Table "scott.num_test"
Column | Type | Modifiers
----------------+------------------+-----------
r_smallint | smallint |
r_integer | integer |
r_bigint | bigint |
r_numeric38 | numeric(38,0) |
r_numeric38_16 | numeric(38,16) |
r_real | real |
r_double | double precision |

postgresql749=> alter table num_test add column r_numeric numeric(80,0);
ALTER TABLE
postgresql749=> commit;
COMMIT
postgresql749=> ¥d num_test
Table "scott.num_test"
Column | Type | Modifiers
----------------+------------------+-----------
r_smallint | smallint |
r_integer | integer |
r_bigint | bigint |
r_numeric38 | numeric(38,0) |
r_numeric38_16 | numeric(38,16) |
r_real | real |
r_double | double precision |
r_numeric | numeric(80,0) |

postgresql749=> insert into num_test(r_numeric) values(9e79);
INSERT 25529 1
postgresql749=> commit;
COMMIT
postgresql749=> select r_numeric from num_test where r_numeric is not null;
r_numeric
----------------------------------------------------------------------------------
90000000000000000000000000000000000000000000000000000000000000000000000000000000
(1 row)

postgresql749=>


Oracle側で問い合わせてみると・・・・・・以下のようになる。number型の精度内の値が設定されていれば問題ないが、それを超えているとエラーが発生する。

CORYDORAS>
CORYDORAS> select "r_numeric" from num_test_postgresql749_mac@oracle10g_win where "r_numeric" is not null;
select "r_numeric" from num_test_postgresql749_mac@oracle10g_win where "r_numeric" is not null
*
行1でエラーが発生しました。:
ORA-28528: 異機種間サービス・データ型の変換中にエラーが発生しました。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(ORACLE10G_WIN)。

CORYDORAS> delete from num_test_postgresql749_mac@oracle10g_win where "r_numeric" > 0;

1行が削除されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric") values(9e37);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select "r_numeric" from num_test_postgresql749_mac@oracle10g_win where "r_numeric" > 0;

r_numeric
----------
9.0000E+37

CORYDORAS>


次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月 6日 (月)

Mac De Oracle Heterogeneous! #29

つづきです。PostgreSQLの数値型をGeneric Connectivity経由でアクセス。

numeric型も特に扱いづらいという点は無さそうだ。(小数点以下を指定してしまった場合の扱いもオラクルと同じで四捨五入してくれる)

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(-99999999999999999999999999999999999999);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(99999999999999999999999999999999999999);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(-100000000000000000000000000000000000000);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(-100000000000000000000000000000000000000)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: numeric field overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(100000000000000000000000000000000000000);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(100000000000000000000000000000000000000)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: numeric field overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(-0.4);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(-0.5);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(0.4);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values(0.5);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11 "rownum" > 37;

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
38 NULL NULL NULL -99999999999999999999999999999999999999 NULL NULL NULL
39 NULL NULL NULL 99999999999999999999999999999999999999 NULL NULL NULL
40 NULL NULL NULL 0 NULL NULL NULL
41 NULL NULL NULL -1 NULL NULL NULL
42 NULL NULL NULL 0 NULL NULL NULL
43 NULL NULL NULL 1 NULL NULL NULL

6行が選択されました。

CORYDORAS>


scaleを16にした例だが、特に気になる点はない。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.9999999999999999);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(9999999999999999999999.9999999999999999);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999995);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999995)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_numeric38_16 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(9999999999999999999999.99999999999999994);

1行が作成されました。

CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999995);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999995)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_numeric38_16 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999994);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999994)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_numeric38_16 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(9999999999999999999999.99999999999999995);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(9999999999999999999999.99999999999999995)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: numeric field overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(9999999999999999999999.9999999999999994);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(99999999999999999999999.9999999999999999);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(99999999999999999999999.9999999999999999)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: numeric field overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-99999999999999999999999.9999999999999999);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-99999999999999999999999.9999999999999999)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_numeric38_16 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-99999999999999999999999.999999999999999);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-99999999999999999999999.999999999999999)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: numeric field overflow (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999995);
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(-9999999999999999999999.99999999999999995)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC][A0C9] Value for column r_numeric38_16 exceeds column's length.
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(0.99999999999999995);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values(0.99999999999999994);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11 "rownum" > 43;

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
44 NULL NULL NULL NULL -9999999999999999999999.9999999999999999 NULL NULL
45 NULL NULL NULL NULL 9999999999999999999999.9999999999999999 NULL NULL
46 NULL NULL NULL NULL 1.0000000000000000 NULL NULL
47 NULL NULL NULL NULL .9999999999999999 NULL NULL

CORYDORAS>


さて、次回は、real型とdouble precision型。

| | コメント (0) | トラックバック (0)

2006年2月 5日 (日)

Mac De Oracle Heterogeneous! #28

つづきです。PostgreSQLの数値型をGeneric Connectivity経由でアクセス。

記事の内容とは関係ないけど、実はノベルティグッズ大好きなんです。
ということで昨日getしたノベルティ。しかも2個も!
CIMG8700


最近のOracle紅白まんじゅうなどに触発されてまた、コレクター魂が・・・・。Oracle Master Gold 9iASだったな〜〜昔は・・・今は自動的にSilverですが・・・取得記念の時計。と OOWで128ノードデモ成功記念テディベア3匹+Java TechDay記念のDuke。

CIMG8659CIMG8661

generic connectivity経由でpostgresqlのsmallint型に数値を設定してみた。PostgreSQL上で行った結果と同じである。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values(32767);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values(-32768);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values(32768);
insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values(32768)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: integer out of range (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values(-32769);
insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values(-32769)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: integer out of range (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11* "rownum" > 31
CORYDORAS> /

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
32 32767 NULL NULL NULL NULL NULL NULL
33 -32768 NULL NULL NULL NULL NULL NULL

CORYDORAS>

integer型へのinsert文も PostgreSQL上で行った場合と変わらない。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values(-2147483648);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values(2147483647);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values(2147483649);
insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values(2147483649)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: integer out of range (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values(2147483648);
insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values(2147483648)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: integer out of range (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> rollback;
CORYDORAS> list
1 select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11* "rownum" > 33
CORYDORAS> /

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
34 NULL -2147483648 NULL NULL NULL NULL NULL
35 NULL 2147483647 NULL NULL NULL NULL NULL

CORYDORAS>

bigint型も特に変わった癖は無い。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values(-9223372036854775808);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values(9223372036854775807);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values(-9223372036854775809);
insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values(-9223372036854775809)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: integer out of range (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values(9223372036854775808);
insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values(9223372036854775808)
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: integer out of range (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> rollback;

ロールバックが完了しました。

CORYDORAS> select *
2 from
3 (
4 select
5 rownum as "rownum",
6 a.*
7 from
8 num_test_postgresql749_mac@oracle10g_win a
9 )
10 where
11 "rownum" > 35;

rownum r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
36 NULL NULL -9223372036854775808 NULL NULL NULL NULL
37 NULL NULL 9223372036854775807 NULL NULL NULL NULL

CORYDORAS>

次回、numeric型につづく。

| | コメント (0) | トラックバック (0)

2006年2月 4日 (土)

Mac De Oracle Heterogeneous! #27

つづきです。PostgreSQLの数値型をGeneric Connectivity経由でアクセス。

PostgreSQL側で行ったことと同じ操作を行う。まず、0の設定とnullの設定。問題なし。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win
2 values(0,0,0,0,0,0,0);

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win
2 values(null,null,null,null,null,null,null);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select * from num_test_postgresql749_mac@oracle10g_win;

r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
0 0 0 0 .0000000000000000 0 0
NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL 0 NULL
NULL NULL NULL NULL NULL NULL 0
32767 NULL NULL NULL NULL NULL NULL
-32768 NULL NULL NULL NULL NULL NULL
NULL -2147483648 NULL NULL NULL NULL NULL
NULL 2147483647 NULL NULL NULL NULL NULL
NULL NULL -9223372036854775808 NULL NULL NULL NULL
NULL NULL 9223372036854775807 NULL NULL NULL NULL
NULL NULL NULL -99999999999999999999999999999999999999 NULL NULL NULL
NULL NULL NULL 0 NULL NULL NULL
NULL NULL NULL -1 NULL NULL NULL
NULL NULL NULL 0 NULL NULL NULL
NULL NULL NULL 99999999999999999999999999999999999999 NULL NULL NULL
NULL NULL NULL NULL -9999999999999999999999.9999999999999999 NULL NULL
NULL NULL NULL NULL 9999999999999999999999.9999999999999999 NULL NULL
NULL NULL NULL NULL 1.0000000000000000 NULL NULL
NULL NULL NULL NULL .9999999999999999 NULL NULL
NULL NULL NULL NULL NULL 3.4000E+38 NULL
NULL NULL NULL NULL NULL -3.400E+38 NULL
NULL NULL NULL NULL NULL 1.2000E-38 NULL
NULL NULL NULL NULL NULL -1.200E-38 NULL
NULL NULL NULL NULL NULL NULL ˜
NULL NULL NULL NULL NULL NULL -˜
NULL NULL NULL NULL NULL NULL 0
NULL NULL NULL NULL NULL NULL 0
0 0 0 0 .0000000000000000 0 0
NULL NULL NULL NULL NULL NULL NULL

29行が選択されました。

CORYDORAS>


空文字の設定もエラーになり、変わった癖はない。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values('');
insert into num_test_postgresql749_mac@oracle10g_win("r_smallint") values('')
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: invalid input syntax for integer: "" (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values('');
insert into num_test_postgresql749_mac@oracle10g_win("r_integer") values('')
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: invalid input syntax for integer: "" (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values('');
insert into num_test_postgresql749_mac@oracle10g_win("r_bigint") values('')
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: invalid input syntax for type bigint: "" (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values('');
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38") values('')
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: invalid input syntax for type numeric: " " (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values('');
insert into num_test_postgresql749_mac@oracle10g_win("r_numeric38_16") values('')
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: invalid input syntax for type numeric: " " (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。


CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_real") values('');

1行が作成されました。

CORYDORAS> insert into num_test_postgresql749_mac@oracle10g_win("r_double") values('');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select * from num_test_postgresql749_mac@oracle10g_win;

r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
0 0 0 0 .0000000000000000 0 0
NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL 0 NULL
NULL NULL NULL NULL NULL NULL 0
32767 NULL NULL NULL NULL NULL NULL
-32768 NULL NULL NULL NULL NULL NULL
NULL -2147483648 NULL NULL NULL NULL NULL
NULL 2147483647 NULL NULL NULL NULL NULL
NULL NULL -9223372036854775808 NULL NULL NULL NULL
NULL NULL 9223372036854775807 NULL NULL NULL NULL
NULL NULL NULL -99999999999999999999999999999999999999 NULL NULL NULL
NULL NULL NULL 0 NULL NULL NULL
NULL NULL NULL -1 NULL NULL NULL
NULL NULL NULL 0 NULL NULL NULL
NULL NULL NULL 99999999999999999999999999999999999999 NULL NULL NULL
NULL NULL NULL NULL -9999999999999999999999.9999999999999999 NULL NULL
NULL NULL NULL NULL 9999999999999999999999.9999999999999999 NULL NULL
NULL NULL NULL NULL 1.0000000000000000 NULL NULL
NULL NULL NULL NULL .9999999999999999 NULL NULL
NULL NULL NULL NULL NULL 3.4000E+38 NULL
NULL NULL NULL NULL NULL -3.400E+38 NULL
NULL NULL NULL NULL NULL 1.2000E-38 NULL
NULL NULL NULL NULL NULL -1.200E-38 NULL
NULL NULL NULL NULL NULL NULL ˜
NULL NULL NULL NULL NULL NULL -˜
NULL NULL NULL NULL NULL NULL 0
NULL NULL NULL NULL NULL NULL 0
0 0 0 0 .0000000000000000 0 0
NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL 0 NULL
NULL NULL NULL NULL NULL NULL 0

31行が選択されました。

CORYDORAS>

長いので次回につづく。

| | コメント (0) | トラックバック (0)

2006年2月 3日 (金)

Mac De Oracle Heterogeneous! #26

前回は、PostgreSQL7.4.9上で数値型の癖を確認した。
今日はPostgreSQLの数値型をGeneric Connectivity経由でアクセスする。

Oracle10g R1 Windowsに num_test_postgresql749_macというシノニムを作成し、以下の経路で
gencon_blog_img02
アクセスしている。

CORYDORAS> select synonym_name from user_synonyms@oracle10g_win;

SYNONYM_NAME
------------------------------
NUM_TEST_POSTGRESQL749_MAC
DATE_TEST_MYSQL4026_WIN
DATE_TEST_MYSQL4113A_MAC_SV
DATE_TEST_POSTGRESQL749_MAC
EMP_MYSQL4025_MAC
INNO_EMP_MYSQL4025_MAC
EMP_MYSQL4026_WIN
EMP_MYSQL4113A_MAC_SV
EMP_POSTGRESQL749_MAC
ORACLE_EMP_MYSQL4026_WIN

10行が選択されました。

CORYDORAS>


登録済みデータを問い合わせてみる。 PostgreSQL7.4.9の double precision型で問題発生。

CORYDORAS> 

r_smallint r_integer r_bigint r_numeric38 r_numeric38_16 r_real r_double
---------- ------------ ----------------------- --------------------------------------- ---------------------------------------- ---------- ----------
0 0 0 0 .0000000000000000 0 0
NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL 0 NULL
NULL NULL NULL NULL NULL NULL 0
32767 NULL NULL NULL NULL NULL NULL
-32768 NULL NULL NULL NULL NULL NULL
NULL -2147483648 NULL NULL NULL NULL NULL
NULL 2147483647 NULL NULL NULL NULL NULL
NULL NULL -9223372036854775808 NULL NULL NULL NULL
NULL NULL 9223372036854775807 NULL NULL NULL NULL
NULL NULL NULL -99999999999999999999999999999999999999 NULL NULL NULL
NULL NULL NULL 0 NULL NULL NULL
NULL NULL NULL -1 NULL NULL NULL
NULL NULL NULL 0 NULL NULL NULL
NULL NULL NULL 99999999999999999999999999999999999999 NULL NULL NULL
NULL NULL NULL NULL -9999999999999999999999.9999999999999999 NULL NULL
NULL NULL NULL NULL 9999999999999999999999.9999999999999999 NULL NULL
NULL NULL NULL NULL 1.0000000000000000 NULL NULL
NULL NULL NULL NULL .9999999999999999 NULL NULL
NULL NULL NULL NULL NULL 3.4000E+38 NULL
NULL NULL NULL NULL NULL -3.400E+38 NULL
NULL NULL NULL NULL NULL 1.2000E-38 NULL
NULL NULL NULL NULL NULL -1.200E-38 NULL
NULL NULL NULL NULL NULL NULL ˜
NULL NULL NULL NULL NULL NULL -˜
NULL NULL NULL NULL NULL NULL 0
NULL NULL NULL NULL NULL NULL 0

27行が選択されました。

CORYDORAS>

dump()関数で Oracle側の型を確認してみると、double precision型も含めて、全て number型にマッピングされている。
Oracleのnumber型の精度を超えている箇所は TILDEが表示されている。number型の精度を超えていないことが事前に確認できるようならば、double precision型もマッピングできそうではあるが、直接取り込むようなことはしないほうが無難だと思われる。
指数表現でCSVファイルとして出力、それをOracle側で、BINARY_DOUBLE型マッピングした外部表にして取り込むという方法がよさそうに思える(尚、外部表にして取り込む方法は未確認)。

CORYDORAS> list
1 select
2 dump("r_smallint") as "smallint",
3 dump("r_integer") as "integer",
4 dump("r_bigint") as "bigint",
5 dump("r_numeric38") as "numeric38_0",
6 dump("r_numeric38_16") as "numeric38_16",
7 dump("r_real") as "real",
8 dump("r_double") as "double_precision"
9 from
10 num_test_postgresql749_mac@oracle10g_win
11 where
12* rownum = 1
CORYDORAS> /

smallint integer bigint numeric38_0 numeric38_16 real double_precision
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------
Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=2 Len=1: 128

CORYDORAS>

長くなるので、一旦この辺で。

| | コメント (0) | トラックバック (0)

2006年2月 2日 (木)

Mac De Oracle Heterogeneous! #25

前回までで日付、時間型の癖は把握できた。ここからは数値型について見ていく。まず初めに、PowerBook G4 1Ghz MacOSX Tiger 10.4.4 (アップデータしたので)に作成した PostgreSQL7.4.9から。

以下のような表をPostgreSQl7.4.9に作成した。

pb17:˜ postgres$ psql -U scott postgresql749
Password:
Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=>
postgresql749=> ¥d num_test
Table "scott.num_test"
Column | Type | Modifiers
----------------+------------------+-----------
r_smallint | smallint |
r_integer | integer |
r_bigint | bigint |
r_numeric38 | numeric(38,0) |
r_numeric38_16 | numeric(38,16) |
r_real | real |
r_double | double precision |

postgresql749=>

正常の登録できて当然なところから。

postgresql749=> insert into num_test values(0,0,0,0,0,0,0);
INSERT 25454 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test values(null,null,null,null,null,null,null);
INSERT 25455 1
postgresql749=> commit;
COMMIT

さて、空文字はどうか? real型とdouble precision型では空文字を受け入れる。それぞれ 0 が設定される。それ以外の数値型では空文字は許容されない。

postgresql749=> insert into num_test values('',null,null,null,null,null,null);
ERROR: invalid input syntax for integer: ""
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test values(null,'',null,null,null,null,null);
ERROR: invalid input syntax for integer: ""
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test values(null,null,'',null,null,null,null);
ERROR: invalid input syntax for type bigint: ""
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test values(null,null,null,'',null,null,null);
ERROR: invalid input syntax for type numeric: ""
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test values(null,null,null,null,'',null,null);
ERROR: invalid input syntax for type numeric: ""
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test values(null,null,null,null,null,'',null);
INSERT 25456 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test values(null,null,null,null,null,null,'');
INSERT 25457 1
postgresql749=> commit;
COMMIT
postgresql749=> select * from num_test;
r_smallint | r_integer | r_bigint | r_numeric38 | r_numeric38_16 | r_real | r_double
------------+-----------+----------+-------------+--------------------+--------+----------
0 | 0 | 0 | 0 | 0.0000000000000000 | 0 | 0
| | | | | |
| | | | | 0 |
| | | | | | 0
(4 rows)

postgresql749=>

次はsmallint型。変わった癖は無い。

postgresql749=> insert into num_test(r_smallint) values(32767);
INSERT 25458 1
postgresql749=> insert into num_test(r_smallint) values(-32768);
INSERT 25459 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_smallint) values(32768);
ERROR: integer out of range
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_smallint) values(-32769);
ERROR: integer out of range
postgresql749=> rollback;
ROLLBACK
postgresql749=>

integer型。

postgresql749=> insert into num_test(r_integer) values(-2147483648);
INSERT 25460 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_integer) values(-2147483649);
ERROR: integer out of range
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_integer) values(2147483647);
INSERT 25461 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_integer) values(2147483648);
ERROR: integer out of range
postgresql749=> rollback;
ROLLBACK
postgresql749=>


postgresql749=> insert into num_test(r_bigint) values(-9223372036854775808);
INSERT 25462 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_bigint) values(-9223372036854775809);
ERROR: integer out of range
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_bigint) values(9223372036854775807);
INSERT 25463 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_bigint) values(9223372036854775808);
ERROR: integer out of range
postgresql749=> rollback;
ROLLBACK
postgresql749=>

numeric型で 38,0 の精度。Oracleのnumber型のような使い勝手。

postgresql749=> insert into num_test(r_numeric38) values(-99999999999999999999999999999999999999);
INSERT 25464 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_numeric38) values(-999999999999999999999999999999999999991);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^38 for field with precision 38, scale 0.
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_numeric38) values(-100000000000000000000000000000000000000);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^38 for field with precision 38, scale 0.
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_numeric38) values(-0.1);
INSERT 25465 1
postgresql749=> insert into num_test(r_numeric38) values(-0.5);
INSERT 25466 1
postgresql749=> insert into num_test(r_numeric38) values(-0.4);
INSERT 25467 1
postgresql749=> commit;
COMMIT
postgresql749=> select * from num_test;
r_smallint | r_integer | r_bigint | r_numeric38 | r_numeric38_16 | r_real | r_double
------------+-------------+----------------------+-----------------------------------------+--------------------+--------+----------
0 | 0 | 0 | 0 | 0.0000000000000000 | 0 | 0
| | | | | |
| | | | | 0 |
| | | | | | 0
32767 | | | | | |
-32768 | | | | | |
| -2147483648 | | | | |
| 2147483647 | | | | |
| | -9223372036854775808 | | | |
| | 9223372036854775807 | | | |
| | | -99999999999999999999999999999999999999 | | |
| | | 0 | | |
| | | -1 | | |
| | | 0 | | |
(14 rows)

精度を変えたnumeric型も変な癖はないようだ。

postgresql749=> insert into num_test(r_numeric38) values(99999999999999999999999999999999999999);
INSERT 25468 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_numeric38) values(100000000000000000000000000000000000000);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^38 for field with precision 38, scale 0.
postgresql749=> rollback;
ROLLBACK
postgresql749=>
postgresql749=> insert into num_test(r_numeric38_16) values(-9999999999999999999999.9999999999999999);
INSERT 25476 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_numeric38_16) values(-10000000000000000000000.9999999999999999);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^22 for field with precision 38, scale 16.
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_numeric38_16) values(9999999999999999999999.9999999999999999);
INSERT 25477 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_numeric38_16) values(10000000000000000000000.9999999999999999);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^22 for field with precision 38, scale 16.
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_numeric38_16) values(-9999999999999999999999.99999999999999995);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^22 for field with precision 38, scale 16.
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_numeric38_16) values(9999999999999999999999.99999999999999995);
ERROR: numeric field overflow
DETAIL: The absolute value is greater than or equal to 10^22 for field with precision 38, scale 16.
postgresql749=> rollback
postgresql749-> rollback;
ERROR: syntax error at or near "rollback" at character 10
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test (r_numeric38_16) values(0.99999999999999995);
INSERT 25478 1
postgresql749=> insert into num_test (r_numeric38_16) values(0.99999999999999994);
INSERT 25479 1
postgresql749=> commit;
COMMIT
postgresql749=> select * from num_test;
r_smallint | r_integer | r_bigint | r_numeric38 | r_numeric38_16 | r_real | r_double
------------+-------------+----------------------+-----------------------------------------+------------------------------------------+--------+----------
0 | 0 | 0 | 0 | 0.0000000000000000 | 0 | 0
| | | | | |
| | | | | 0 |
| | | | | | 0
32767 | | | | | |
-32768 | | | | | |
| -2147483648 | | | | |
| 2147483647 | | | | |
| | -9223372036854775808 | | | |
| | 9223372036854775807 | | | |
| | | -99999999999999999999999999999999999999 | | |
| | | 0 | | |
| | | -1 | | |
| | | 0 | | |
| | | 99999999999999999999999999999999999999 | | |
| | | | -9999999999999999999999.9999999999999999 | |
| | | | 9999999999999999999999.9999999999999999 | |
| | | | 1.0000000000000000 | |
| | | | 0.9999999999999999 | |
(19 rows)

postgresql749=>


次は、real型。

postgresql749=> 
postgresql749=> insert into num_test(r_real) values(3.4e38);
INSERT 25487 1
postgresql749=> insert into num_test(r_real) values(-3.4e38);
INSERT 25488 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_real) values(1.2e-38);
INSERT 25489 1
postgresql749=> insert into num_test(r_real) values(-1.2e-38);
INSERT 25490 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_real) values(3.4e39);
ERROR: type "real" value out of range: overflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_real) values(-3.4e39);
ERROR: type "real" value out of range: overflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_real) values(-3.5e38);
ERROR: type "real" value out of range: overflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_real) values(-3.41e38);
ERROR: type "real" value out of range: overflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_real) values(1.2e-39);
ERROR: type "real" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_real) values(1.1e-38);
ERROR: type "real" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_real) values(-1.1e-38);
ERROR: type "real" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> select * from num_test;
r_smallint | r_integer | r_bigint | r_numeric38 | r_numeric38_16 | r_real | r_double
------------+-------------+----------------------+-----------------------------------------+------------------------------------------+----------+----------
0 | 0 | 0 | 0 | 0.0000000000000000 | 0 | 0
| | | | | |
| | | | | 0 |
| | | | | | 0
32767 | | | | | |
-32768 | | | | | |
| -2147483648 | | | | |
| 2147483647 | | | | |
| | -9223372036854775808 | | | |
| | 9223372036854775807 | | | |
| | | -99999999999999999999999999999999999999 | | |
| | | 0 | | |
| | | -1 | | |
| | | 0 | | |
| | | 99999999999999999999999999999999999999 | | |
| | | | -9999999999999999999999.9999999999999999 | |
| | | | 9999999999999999999999.9999999999999999 | |
| | | | 1.0000000000000000 | |
| | | | 0.9999999999999999 | |
| | | | | 3.4e+38 |
| | | | | -3.4e+38 |
| | | | | 1.2e-38 |
| | | | | -1.2e-38 |
(23 rows)

postgresql749=>

最後に double precision型。

postgresql749=> insert into num_test(r_double) values(1.79e308);
INSERT 25495 1
postgresql749=> insert into num_test(r_double) values(-1.79e308);
INSERT 25496 1
postgresql749=> insert into num_test(r_double) values(2.3e-308);
INSERT 25497 1
postgresql749=> insert into num_test(r_double) values(-2.3e-308);
INSERT 25498 1
postgresql749=> commit;
COMMIT
postgresql749=> insert into num_test(r_double) values(1.80e308);
ERROR:"180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000" is out of range for type double precision
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(-1.80e308);
ERROR:"-18000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000" is out of range for type double precision
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(1.79e309);
ERROR:"179000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000" is out of range for type double precision
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(-1.79e309);
ERROR:"-17900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000" is out of range for type double precision
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(2.2e-308);
ERROR: type "double precision" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(-2.2e-308);
ERROR: type "double precision" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(2.3e-309);
ERROR: type "double precision" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> insert into num_test(r_double) values(-2.3e-309);
ERROR: type "double precision" value out of range: underflow
postgresql749=> rollback;
ROLLBACK
postgresql749=> select * from num_test;
r_smallint | r_integer | r_bigint | r_numeric38 | r_numeric38_16 | r_real | r_double
------------+-------------+----------------------+-----------------------------------------+------------------------------------------+----------+------------
0 | 0 | 0 | 0 | 0.0000000000000000 | 0 | 0
| | | | | |
| | | | | 0 |
| | | | | | 0
32767 | | | | | |
-32768 | | | | | |
| -2147483648 | | | | |
| 2147483647 | | | | |
| | -9223372036854775808 | | | |
| | 9223372036854775807 | | | |
| | | -99999999999999999999999999999999999999 | | |
| | | 0 | | |
| | | -1 | | |
| | | 0 | | |
| | | 99999999999999999999999999999999999999 | | |
| | | | -9999999999999999999999.9999999999999999 | |
| | | | 9999999999999999999999.9999999999999999 | |
| | | | 1.0000000000000000 | |
| | | | 0.9999999999999999 | |
| | | | | 3.4e+38 |
| | | | | -3.4e+38 |
| | | | | 1.2e-38 |
| | | | | -1.2e-38 |
| | | | | | 1.79e+308
| | | | | | -1.79e+308
| | | | | | 2.3e-308
| | | | | | -2.3e-308
(27 rows)

postgresql749=>
postgresql749=> ¥q
pb17:˜ postgres$

日付型とは異なり変わった癖はなさそうな予感。次回はgeneric connectivity経由でOracleからアクセスしてみる。

| | コメント (0) | トラックバック (0)

2006年1月31日 (火)

Mac De Oracle Heterogeneous! #24

引き続き、Generic Connectivity経由でアクセスした場合、Oracle側では日付、時刻型がどのようにどのように扱われるか確認する。

PostgreSQLの場合と同様に、現在時刻を指定するためにはPL/SQLからexecute immediate文を利用する必要がありそうだ。

CORYDORAS> list
1 insert into date_test_mysql4113a_mac_sv@oracle10g_win
2 values(
3 (select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual),
4 (select to_char(sysdate,'yyyy-mm-dd') from dual),
5 (select to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss.ff') from dual),
6 (select to_char(sysdate,'hh24:mi:ss') from dual),
7 (select to_char(sysdate,'yyyy') from dual)
8* )
CORYDORAS> /
insert into date_test_mysql4113a_mac_sv@oracle10g_win
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではsubqueriesをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


CORYDORAS>
CORYDORAS> list
1 declare
2 v_datetime varchar2(19);
3 v_date varchar2(10);
4 v_timestamp varchar2(30);
5 v_time varchar2(8);
6 v_year varchar2(4);
7 begin
8 v_datetime := to_char(sysdate,'yyyy-mm-dd hh24:mi:ss');
9 v_date := to_char(sysdate, 'yyyy-mm-dd');
10 v_timestamp := to_char(systimestamp , 'yyyy-mm-dd hh24:mi:ss.ff');
11 v_time := to_char(sysdate, 'hh24:mi:ss');
12 v_year := to_char(sysdate, 'yyyy');
13 --
14 insert into date_test_mysql4113a_mac_sv@oracle10g_win
15 values(
16 v_datetime, v_date, v_timestamp, v_time, v_year
17 );
18 commit;
19* end;
CORYDORAS> /
insert into date_test_mysql4113a_mac_sv@oracle10g_win
*
行14でエラーが発生しました。:
ORA-06550: 行14、列3:
PL/SQL: ORA-00980: シノニム変換が無効です。
ORA-06550: 行14、列3:
PL/SQL: SQL Statement ignored


CORYDORAS>
CORYDORAS> list
1 declare
2 v_datetime_string varchar2(19);
3 v_date_string varchar2(10);
4 v_timestamp_string varchar2(30);
5 v_time_string varchar2(8);
6 v_year_string varchar2(4);
7 v_sql varchar2(1000);
8 begin
9 v_datetime_string := to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss');
10 v_date_string := to_char(sysdate, 'yyyy-mm-dd');
11 v_timestamp_string := to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss');
12 v_time_string := to_char(sysdate, 'hh24:mi:ss');
13 v_year_string := to_char(sysdate, 'yyyy');
14 v_sql :=
15 'insert into date_test_mysql4113a_mac_sv@oracle10g_win values('||
16 '''' || v_datetime_string ||
17 ''',''' || v_date_string ||
18 ''',''' || v_timestamp_string ||
19 ''',''' || v_time_string ||
20 ''',''' || v_year_string || ''')'
21 ;
22 execute immediate v_sql;
23 end;
24*
CORYDORAS> /

PL/SQLプロシージャが正常に完了しました。

CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp r_time r_year
-------------------------- -------------------------- -------------------------- -------------------- -------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:12:32
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:30:56
2006/01/24 23:32:31
2006/01/24 23:43:53
0000/00/00 00:00:00
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/25 00:06:11
2006/01/27 01:00:12
0000/00/00 00:00:00 0001/01/01 00:00:00 0
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/10 00:30:12 2006/02/10 00:00:00 2006/03/04 13:50:12 0001/01/01 12:30:01 2005
2006/01/27 10:13:10
2006/01/27 10:33:34 2006/01/27 00:00:00 0000/00/00 00:00:00 0001/01/01 10:33:34 2006
2006/01/27 10:48:01 2006/01/27 00:00:00 2006/01/27 10:48:01 0001/01/01 10:48:01 2006

23行が選択されました。

CORYDORAS>

DBMS_HS_PASSTHROUGHパッケージが利用できれば、それを利用する手もあるかもしれないが、このように
gencon_blog_img1

特殊な構成ではどうなのだろうか・・・・。

それは別途調べることにして、単純な環境ならば以下のようにして利用できる。
以下は、Windows XP ProfessionalのOracle10g R1 EEから MacOSX Tiger ServerのMySQL4.1.13a対して、DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEプロシージャを利用してMySQL向けSQLをパススルーして実行した例。
尚、dbms_hs_passthroughパッケージは、仮想パッケージとの記載があった。dba_objectsビュ−を覗いても存在していないし、desc dbms_hs_passthrough としても存在しないので驚かないように。
このようにアクセスしている。
gencon_blog_img99

SQL> select * from "date_test"@mysql4113a_mac_sv;

r_datetime r_date r_timestamp r_time r_year
------------------- ------------------- ------------------- ------------------- ----------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:12:32
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:30:56
2006/01/24 23:32:31
2006/01/24 23:43:53
0000/00/00 00:00:00
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/25 00:06:11
2006/01/27 01:00:12
0000/00/00 00:00:00 0001/01/01 00:00:00 0
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/10 00:30:12 2006/02/10 00:00:00 2006/03/04 13:50:12 0001/01/01 12:30:01 2005
2006/01/27 10:13:10
2006/01/27 10:33:34 2006/01/27 00:00:00 0000/00/00 00:00:00 0001/01/01 10:33:34 2006
2006/01/27 10:44:42 2006/01/27 00:00:00 0000/00/00 00:00:00 0001/01/01 10:44:42 2006
2006/01/27 10:48:01 2006/01/27 00:00:00 2006/01/27 10:48:01 0001/01/01 10:48:01 2006

24行が選択されました。

SQL> DECLARE
2 num_rows PLS_INTEGER;
3 BEGIN
4 num_rows := DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE@mysql4113a_mac_sv
5 (
6 'insert into date_test values(now(), now(), now(), now(), now())'
7 );
8 END;
9 /

PL/SQLプロシージャが正常に完了しました。

SQL> select * from "date_test"@mysql4113a_mac_sv;

r_datetime r_date r_timestamp r_time r_year
------------------- ------------------- ------------------- ------------------- ----------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:12:32
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:30:56
2006/01/24 23:32:31
2006/01/24 23:43:53
0000/00/00 00:00:00
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/25 00:06:11
2006/01/27 01:00:12
0000/00/00 00:00:00 0001/01/01 00:00:00 0
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/10 00:30:12 2006/02/10 00:00:00 2006/03/04 13:50:12 0001/01/01 12:30:01 2005
2006/01/27 10:13:10
2006/01/27 10:33:34 2006/01/27 00:00:00 0000/00/00 00:00:00 0001/01/01 10:33:34 2006
2006/01/27 10:44:42 2006/01/27 00:00:00 0000/00/00 00:00:00 0001/01/01 10:44:42 2006
2006/01/27 10:48:01 2006/01/27 00:00:00 2006/01/27 10:48:01 0001/01/01 10:48:01 2006
2006/01/28 14:55:38 2006/01/28 00:00:00 2006/01/28 14:55:38 0001/01/01 14:55:38 2006

25行が選択されました。

SQL> commit;

コミットが完了しました。

SQL>

=======================
結構苦戦しそうだが、MySQLの日付型、時刻型を利用する際の注意点をまとめておくと、

利用しているMyODBC Driverは、ここを参照してもらいたい

MySQLOracle
datetime型date型
date型
timestamp型
time型
year型number型
・検索時には、date型ではなく文字列で検索する。 ・MySQL側の型がtimestamp型である場合には、0000年00月00日かをCASE式かDECODE関数を利用してNULLにする必要がる。 ・MySQL側の型がyear型の場合、0ならば、NULLにしておいたほうがよいだろう。 ・逆にOracleからMySQL側に登録する際には、日付や時間の書式チェックを厳重に行うようにしたほうがよい。そうでないと0000年0月0日が設定されてしまう可能性もある。 ・現在日付や時刻を設定する場合には、PL/SQLからexecute immediate文を利用する必要がありそう。
gencon_blog_img1
(このような特殊な構成の場合だけだと思うが。。)  通常の構成ならば、dbms_hs_passthroughパッケージを利用するのもよいだろう。


やっと日付、時間型の確認が終わり、次回は、数値型(多分整数だけ)について、MySQL側の癖から確認してみようと思う。

| | コメント (0) | トラックバック (0)

2006年1月30日 (月)

Mac De Oracle Heterogeneous! #23

引き続き、Generic Connectivity経由でアクセスした場合、Oracle側では日付、時刻型がどのようにどのように扱われるか確認する。

Oracle側の関数や、逆にMySQL側の関数を利用した場合には、PostgreSQLの場合と同様にエラーとなる。

CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values(sysdate,null,null,null,null);
insert into date_test_mysql4113a_mac_sv@oracle10g_win values(sysdate,null,null,null,null)
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではspecial functionsをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values(now(),null,null,null,null);
insert into date_test_mysql4113a_mac_sv@oracle10g_win values(now(),null,null,null,null)
*
行1でエラーが発生しました。:
ORA-00904: "NOW": 無効な識別子です。


CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values(to_char(sysdate,'yyyymmddhh24miss'),null,null,null,null);
insert into date_test_mysql4113a_mac_sv@oracle10g_win values(to_char(sysdate,'yyyymmddhh24miss'),null,null,null,null)
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではTO_CHARをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values(to_date('20061212235534','yyyymmddhh24miss'),null,null,null,null);
insert into date_test_mysql4113a_mac_sv@oracle10g_win values(to_date('20061212235534','yyyymmddhh24miss'),null,null,null,null)
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4113A_MAC_SVはこのコンテキストではTO_DATEをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


CORYDORAS>

以下のようなリテラル指定ではうまく登録できるようだ。

CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values('2006-01-10 00:30:12','2006-02-10','2006-03-04 13:50:12','12:30:01',2005);

1行が作成されました。

CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp r_time r_year
-------------------------- -------------------------- -------------------------- -------------------- -------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:12:32
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:30:56
2006/01/24 23:32:31
2006/01/24 23:43:53
0000/00/00 00:00:00
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/25 00:06:11
2006/01/27 01:00:12
0000/00/00 00:00:00 0001/01/01 00:00:00 0
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/10 00:30:12 2006/02/10 00:00:00 2006/03/04 13:50:12 0001/01/01 12:30:01 2005

20行が選択されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS>

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
| 2006-00-00 00:00:00 | NULL | 2006-01-24 23:43:53 | NULL | NULL |
| NULL | NULL | 0000-00-00 00:00:00 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 2006-00-00 00:00:00 | NULL | 2006-01-25 00:06:11 | NULL | NULL |
| NULL | NULL | 2006-01-27 01:00:12 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 2006-01-10 00:30:12 | 2006-02-10 | 2006-03-04 13:50:12 | 12:30:01 | 2005 |
+---------------------+------------+---------------------+----------+--------+
20 rows in set (0.00 sec)

mysql>

13月とか40日とか、44時、65分、76秒などもOracle側でエラーにならずに登録できる。但し、MySQL側では0000年00月00日という日付になってしまう。Oracle側で日付を問い合わせるとNULLになる(MyODBCドライバの仕様通り)。

CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values('2006-13-40 44:65:76',null,null,null,null);

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp r_time r_year
-------------------------- -------------------------- -------------------------- -------------------- -------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:12:32
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:30:56
2006/01/24 23:32:31
2006/01/24 23:43:53
0000/00/00 00:00:00
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/25 00:06:11
2006/01/27 01:00:12
0000/00/00 00:00:00 0001/01/01 00:00:00 0
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/10 00:30:12 2006/02/10 00:00:00 2006/03/04 13:50:12 0001/01/01 12:30:01 2005
2006/01/27 10:13:10

21行が選択されました。

CORYDORAS>


mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
| 2006-00-00 00:00:00 | NULL | 2006-01-24 23:43:53 | NULL | NULL |
| NULL | NULL | 0000-00-00 00:00:00 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 2006-00-00 00:00:00 | NULL | 2006-01-25 00:06:11 | NULL | NULL |
| NULL | NULL | 2006-01-27 01:00:12 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 2006-01-10 00:30:12 | 2006-02-10 | 2006-03-04 13:50:12 | 12:30:01 | 2005 |
| 0000-00-00 00:00:00 | NULL | 2006-01-27 10:13:10 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
21 rows in set (0.00 sec)

mysql>

長いので、また、次回につづく。

| | コメント (0) | トラックバック (0)

2006年1月29日 (日)

Mac De Oracle Heterogeneous! #22

つづきです。前回は、MySQL側で日付、時刻型がどのように登録され、どのような癖があるのかを確認した。
今回は、Generic Connectivity経由でアクセスした場合、Oracle側ではMySQLの日付、時刻型がどのようにどのように扱われるか確認する。
以下のような経路でアクセスしている。

gencon_blog_img01

MySQL4.1.13aには以下のようなデータが登録済み。気になるところは0000年00月00日が許容されている点だろう。

Last login: Thu Jan 26 00:32:31 on console
Welcome to Darwin!
G5Server:˜ discus$ mysql -u discus -p mysqldb41
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or ¥g.
Your MySQL connection id is 1 to server version: 4.1.13a

Type 'help;' or '¥h' for help. Type '¥c' to clear the buffer.

mysql>
mysql>
mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
| 2006-00-00 00:00:00 | NULL | 2006-01-24 23:43:53 | NULL | NULL |
| NULL | NULL | 0000-00-00 00:00:00 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 2006-00-00 00:00:00 | NULL | 2006-01-25 00:06:11 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
16 rows in set (0.02 sec)

mysql>

まず、単純に問い合わせてみる。datetime型、date型、timestamp型、time型は、Oracleのdate型にマッピングされている。year型はnumber型にマッピングされている。OracleではMySQLのtime型もdate型として扱われている。一番まずいのは、timestamp型に 0000年00月00日が設定されている場合、オラクル側でも0000年00月00日となってしまう点である。Oracle側ではその後の処理で問題になる。尚、ODBCの仕様では、NULLになるのが正しいようなのでこのテストで利用している MyODBCドライバの問題である可能性が高いと思われる。(timestamp型以外ではNULLが返されている)
CORYDORAS> alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss';

セッションが変更されました。

CORYDORAS> alter session set nls_timestamp_format = 'yyyy/mm/dd hh24:mi:ss.ff';

セッションが変更されました。

CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp r_time r_year
------------------- ------------------- ------------------- ------------------- ----------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:12:32
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/24 23:30:56
2006/01/24 23:32:31
2006/01/24 23:43:53
0000/00/00 00:00:00
0000/00/00 00:00:00 0001/01/01 00:00:00 0
2006/01/25 00:06:11

16行が選択されました。

CORYDORAS>

CORYDORAS> select
2 dump("r_datetime") as r_datetime,
3 dump("r_date") as r_date,
4 dump("r_timestamp") as r_timestamp,
5 dump("r_time") as r_time,
6 dump("r_year") as r_year
7 from
8 date_test_mysql4113a_mac_sv@oracle10g_win;

R_DATETIME R_DATE R_TIMESTAMP R_TIME R_YEAR
------------------------------------ ------------------------------------ ------------------------------------ ------------------------------------ ------------------------------------
Typ=12 Len=7: 119,190,1,1,1,1,1 NULL Typ=12 Len=7: 120,106,1,20,24,5,23 NULL NULL
Typ=12 Len=7: 120,100,12,1,1,1,1 NULL Typ=12 Len=7: 120,106,1,20,24,5,36 NULL NULL
NULL Typ=12 Len=7: 118,100,1,1,1,1,1 Typ=12 Len=7: 120,106,1,20,24,5,52 NULL NULL
NULL Typ=12 Len=7: 118,110,12,1,1,1,1 Typ=12 Len=7: 120,106,1,20,24,6,7 NULL NULL
NULL NULL Typ=12 Len=7: 120,102,12,1,1,1,1 NULL NULL
NULL NULL Typ=12 Len=7: 120,106,1,20,24,6,34 NULL NULL
NULL NULL Typ=12 Len=7: 100,100,0,0,1,1,1 Typ=12 Len=7: 100,101,1,1,1,1,1 Typ=2 Len=1: 128
NULL NULL Typ=12 Len=7: 120,106,1,24,24,13,33 NULL NULL
Typ=12 Len=7: 120,106,1,24,24,14,20 Typ=12 Len=7: 120,106,1,24,1,1,1 Typ=12 Len=7: 120,106,1,24,24,14,20 Typ=12 Len=7: 100,101,1,1,24,14,20 Typ=2 Len=3: 194,21,7
NULL NULL Typ=12 Len=7: 100,100,0,0,1,1,1 Typ=12 Len=7: 100,101,1,1,1,1,1 Typ=2 Len=1: 128
NULL NULL Typ=12 Len=7: 120,106,1,24,24,31,57 NULL NULL
NULL NULL Typ=12 Len=7: 120,106,1,24,24,33,32 NULL NULL
NULL NULL Typ=12 Len=7: 120,106,1,24,24,44,54 NULL NULL
NULL NULL Typ=12 Len=7: 100,100,0,0,1,1,1 NULL NULL
NULL NULL Typ=12 Len=7: 100,100,0,0,1,1,1 Typ=12 Len=7: 100,101,1,1,1,1,1 Typ=2 Len=1: 128
NULL NULL Typ=12 Len=7: 120,106,1,25,1,7,12 NULL NULL

16行が選択されました。

CORYDORAS>

nullを設定するのは問題なかった。次が問題、パススルーされているようで、MySQL側で空文字を設定した場合と同じ結果になる。MySQLではワーニングが表示されたりするが、generic connectivity 経由では正常に?処理されてしまう。(ワーニングを拾う方法はあるのか? 別途調べるか・・)

CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values(null,null,null,null,null);

1行が作成されました。

CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values('','','','','');

1行が作成されました。

CORYDORAS> set null 'NULL'
CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp r_time r_year
------------------------------ ------------------------------ ------------------------------ ------------------------------ ------
1990/01/01 00:00:00 NULL 2006/01/20 23:04:22 NULL NULL
2000/12/01 00:00:00 NULL 2006/01/20 23:04:35 NULL NULL
NULL 1800/01/01 00:00:00 2006/01/20 23:04:51 NULL NULL
NULL 1810/12/01 00:00:00 2006/01/20 23:05:06 NULL NULL
NULL NULL 2002/12/01 00:00:00 NULL NULL
NULL NULL 2006/01/20 23:05:33 NULL NULL
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 2006/01/24 23:12:32 NULL NULL
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 2006/01/24 23:30:56 NULL NULL
NULL NULL 2006/01/24 23:32:31 NULL NULL
NULL NULL 2006/01/24 23:43:53 NULL NULL
NULL NULL 0000/00/00 00:00:00 NULL NULL
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 2006/01/25 00:06:11 NULL NULL
NULL NULL 2006/01/27 01:00:12 NULL NULL
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0

18行が選択されました。

CORYDORAS>

year型はnumber型にマップされているので仕方ないが、date型にマップされている各型でもオラクルではエラーになる0000年や、00月、00日は登録できてしまう。

CORYDORAS> insert into date_test_mysql4113a_mac_sv@oracle10g_win values('0000-00-00 00:00:00','0000-00-00','0000-00-00 00:00:00.123456','0000-00-00 00:00:00','0000');

1行が作成されました。

CORYDORAS> commit;

コミットが完了しました。

CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp r_time r_year
------------------------------ ------------------------------ ------------------------------ ------------------------------ ------
1990/01/01 00:00:00 NULL 2006/01/20 23:04:22 NULL NULL
2000/12/01 00:00:00 NULL 2006/01/20 23:04:35 NULL NULL
NULL 1800/01/01 00:00:00 2006/01/20 23:04:51 NULL NULL
NULL 1810/12/01 00:00:00 2006/01/20 23:05:06 NULL NULL
NULL NULL 2002/12/01 00:00:00 NULL NULL
NULL NULL 2006/01/20 23:05:33 NULL NULL
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 2006/01/24 23:12:32 NULL NULL
2006/01/24 23:13:19 2006/01/24 00:00:00 2006/01/24 23:13:19 0001/01/01 23:13:19 2006
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 2006/01/24 23:30:56 NULL NULL
NULL NULL 2006/01/24 23:32:31 NULL NULL
NULL NULL 2006/01/24 23:43:53 NULL NULL
NULL NULL 0000/00/00 00:00:00 NULL NULL
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 2006/01/25 00:06:11 NULL NULL
NULL NULL 2006/01/27 01:00:12 NULL NULL
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0
NULL NULL 0000/00/00 00:00:00 0001/01/01 00:00:00 0

19行が選択されました。

CORYDORAS>

MySQL側では以下のようになっている。timestamp型の0000−00−00がOracle側ではNULLにならないのでOracle側のクエリでNULLに強制的に変換してやる必要がありそうだ。(year型の場合も強制的にNULLにするか、0001年にするようなクエリにする必要はありそうだ)
mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
| 2006-00-00 00:00:00 | NULL | 2006-01-24 23:43:53 | NULL | NULL |
| NULL | NULL | 0000-00-00 00:00:00 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 2006-00-00 00:00:00 | NULL | 2006-01-25 00:06:11 | NULL | NULL |
| NULL | NULL | 2006-01-27 01:00:12 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
+---------------------+------------+---------------------+----------+--------+
19 rows in set (0.00 sec)

mysql>

長くなるので次回につづく。

| | コメント (0) | トラックバック (0)

2006年1月24日 (火)

Mac De Oracle Heterogeneous! #21

つづきです。
今日は、MySQLの日付、時刻型について、Oracleとの違いを見ていく。

最初は、すべて 0 を設定してみる。
なんと正常に登録できてしまう。
しかもOracleやMySQLでも設定できなかった 0月 0日やOracleではエラーになってしまう 0000年が設定できるのである。generic connectivityでは問題になるかもしれないので注意しておく必要がある。

mysql> insert into date_test values(0,0,0,0,0);
Query OK, 1 row affected (0.09 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
+---------------------+------------+---------------------+----------+--------+
7 rows in set (0.00 sec)


nullableなのでNULLを設定しても問題ない。ただし、timestamp型はnullにならず必ずタイムスタンプが設定される。この辺りはOracleでも問題なることはないだろう。

mysql> insert into date_test values(null,null,null,null,null);
Query OK, 1 row affected (0.09 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
8 rows in set (0.00 sec)

mysql>


現在時刻、日付の設定も特に問題になるようなことはなさそうに感じる。ただ warningが出ているが、気にせずcommitすると登録できてしまうので、プログラムミスでwarningを拾わず、rollbackしなかったらおかしな日付が登録される危険性がある。
ちなみに、MySQL4.1.13aでは 1 warningとでているが、MySQL4.0.26-ntでは warining表示すら表示されていなかった。

mysql> insert into date_test values(now(), now(), now(), now(), now());
Query OK, 1 row affected, 1 warning (0.09 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
+---------------------+------------+---------------------+----------+--------+
9 rows in set (0.00 sec)

mysql>

さて、お次は問題。MySQLでは、PostgreSQLでも設定できなかった空文字が warningはでるがコミットはできてしまう。前述したがwarningを拾わずにcommitしてしまうようなプログラムがあれば日付としておかしな値が設定されてしまう危険性がある。

mysql> insert into date_test values('','','','','');
Query OK, 1 row affected, 5 warnings (0.07 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
+---------------------+------------+---------------------+----------+--------+
10 rows in set (0.00 sec)

mysql>

さすがに、13月や35日、26時間、 70分、70秒などは warningとして警告がでるが、やはり commitが行える。内容を見てみると、0000年0月0日 0時0分0秒となる。注意しなければ。。。

mysql> insert into date_test values('2006-13-35 26:70:70',null,null,null,null);
Query OK, 1 row affected, 1 warning (0.06 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
11 rows in set (0.00 sec)

mysql> insert into date_test values('99999999',null,null,null,null);
Query OK, 1 row affected, 1 warning (0.04 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
12 rows in set (0.00 sec)

mysql>

これもあぶない。0月、0日がワーニングもなく登録できるのである。

mysql> insert into date_test values('2006-00-00 00:00:00',null,null,null,null);
Query OK, 1 row affected (0.06 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
| 2006-00-00 00:00:00 | NULL | 2006-01-24 23:43:53 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
13 rows in set (0.00 sec)

mysql>

ざっと確認してみたところ、ポイントは

0000年
0月
0日

それぞれを許容してしまうあたりだろうか。。


次回は、Generic Connectivityを経由してMySQLにアクセスしてみる。Oracle側ではどの型にマッピングされ、どのような癖があるのかを確認する。

| | コメント (0) | トラックバック (0)

2006年1月23日 (月)

Mac De Oracle Heterogeneous! #20

前回は、PostgreSQL上で日付や時間型がどのように扱われるか確認してみた。今日はGenneric Connectivity経由でPostgreSQLに日付や時間を登録してみる。

いつものように、date型とtimestamp型の書式を設定しておく

CORYDORAS> alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss';

セッションが変更されました。

CORYDORAS> alter session set nls_timestamp_format = 'yyyy/mm/dd hh24:mi:ss.ff';

セッションが変更されました。

Oracle10g R1 (MacOSX Server : PowerMac G5) --> oracle10g_win(データベースリンク) --> Oracle10g R1 (Windows XP Professional)のdate_test_postgresql749_mac(シノニム)--> generic connectivity agent --> MyODBCドライバ --> PostgreSQL7.4.9 の date_test表(MacOSX : PowerBook G4)という経路で問い合わせている。

PostgreSQL7.4.9の date型、time型、timestamp型すべてが、Oracleのdate型にマップされているため以下のような点に注意。

PostgreSQLのtime型は時間だけだが、Oracle側ではdate型になるため、0001/01/01+時間となる。
PostgreSQLのdate型は日付だけだが、Oracle型ではdate型なので 時間が00:00:00になる。
PostgreSQLのtimestamp型は、Oracleのdate型にマップされてしまうため、秒の少数部が欠落する。

ということになる。
以下は、generic connectivity経由でOracleから問い合わせた結果である。dump()関数を利用してデータタイプも確認してある。

CORYDORAS> select * from date_test_postgresql749_mac@oracle10g_win;

r_date r_timestamp r_time
------------------- ------------------- -------------------
1900/01/01 00:00:00
2006/01/20 00:00:00
1981/01/01 00:00:00
1990/12/01 00:00:00
0001/01/01 00:00:00
2007/03/07 00:00:00
0001/01/01 00:00:00
2007/09/11 00:00:00
2006/01/01 00:00:00
0001/01/01 23:59:59
2006/01/02 00:00:00
2006/01/02 03:01:00
2006/01/22 00:00:00 2006/01/22 21:57:25 0001/01/01 21:57:25
2008/11/07 04:50:03

14行が選択されました。

CORYDORAS>
CORYDORAS> list
1 select
2 dump("r_date") as r_date,
3 dump("r_timestamp") as r_timestamp,
4 dump("r_time") as r_time
5 from
6* date_test_postgresql749_mac@oracle10g_win
CORYDORAS> /

R_DATE R_TIMESTAMP R_TIME
---------------------------------------- ---------------------------------------- ----------------------------------------
Typ=12 Len=7: 119,100,1,1,1,1,1 NULL NULL
Typ=12 Len=7: 120,106,1,20,1,1,1 NULL NULL
NULL Typ=12 Len=7: 119,181,1,1,1,1,1 NULL
NULL Typ=12 Len=7: 119,190,12,1,1,1,1 NULL
Typ=12 Len=7: 100,101,1,1,1,1,1 NULL NULL
Typ=12 Len=7: 120,107,3,7,1,1,1 NULL NULL
NULL Typ=12 Len=7: 100,101,1,1,1,1,1 NULL
NULL Typ=12 Len=7: 120,107,9,11,1,1,1 NULL
NULL Typ=12 Len=7: 120,106,1,1,1,1,1 NULL
NULL NULL Typ=12 Len=7: 100,101,1,1,24,60,60
NULL Typ=12 Len=7: 120,106,1,2,1,1,1 NULL
NULL Typ=12 Len=7: 120,106,1,2,4,2,1 NULL
Typ=12 Len=7: 120,106,1,22,1,1,1 Typ=12 Len=7: 120,106,1,22,22,58,26 Typ=12 Len=7: 100,101,1,1,22,58,26
NULL Typ=12 Len=7: 120,108,11,7,5,51,4 NULL

14行が選択されました。

CORYDORAS>

次に、日付、時間型データを登録してみた。
パススルーされているのだろうか、to_date()関数は利用できない。(HS_CALL_NAME初期化パラメータでPostgreSQLのto_date関数が利用できるかは未確認。)

CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2 values(to_date('00000000','yyyymmdd'),null,null);
insert into date_test_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではTO_DATEをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

PostgreSQL上でもエラーになったINSERT文を実行してみると、これはPostgreSQLまで届いているようだ。PostgreSQL上で実行した時と同じエラーが返ってくる。

CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2 values('00000000',null,null);
insert into date_test_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: date/time field value out of range: "00000000" (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

Oracleのsysdate,systimestampを利用してみる。これは予想通りエラーとなる。

CORYDORAS> 
CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2 values(sysdate,systimestamp,sysdate);
insert into date_test_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではspecial functionsをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

to_char()関数を利用してみたが、これはto_date()関数と同じで利用できない。

CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2 values(to_char(sysdate,'yyyymmdd'), to_char(systimestamp,'yyyymmddhh24miss.ff'), to_char(sysdate,'hh24miss'));
insert into date_test_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではTO_CHARをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

では、暗黙型変換に任せて、単純に日付や時間を文字列指定した場合はどうか? 
やっと、登録できた。(よかった、よかった。と安心ばかりはしていられない。。。)


CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2  values('20061231','20060101 125959','235959');

1行が作成されました。

CORYDORAS> select * from date_test_postgresql749_mac@oracle10g_win;

r_date r_timestamp r_time
---------------------------------------- ---------------------------------------- ----------------------------------------
1900/01/01 00:00:00
2006/01/20 00:00:00
1981/01/01 00:00:00
1990/12/01 00:00:00
0001/01/01 00:00:00
2007/03/07 00:00:00
0001/01/01 00:00:00
2007/09/11 00:00:00
2006/01/01 00:00:00
0001/01/01 23:59:59
2006/01/02 00:00:00
2006/01/02 03:01:00
2006/01/22 00:00:00 2006/01/22 21:57:25 0001/01/01 21:57:25
2008/11/07 04:50:03
2006/12/31 00:00:00 2006/01/01 12:59:59 0001/01/01 23:59:59

15行が選択されました。

各列はnullableなのでNULLを設定することも問題ない。

CORYDORAS> 
CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2 values(null,null,null);

1行が作成されました。

Oracleでは、今のところ、空文字=NULLなのでNULLが登録されると予想していたがDML文がパススルーされているようで、PostgreSQL上で実行した場合と同様の結果(エラー)になる。(尚、本来は、空文字とNULLは別もの。オラクルのマニュアルにも記載があり空文字=NULLという扱いにはなっているが将来は変わる可能性があるというようなニュアンスのコメントが記載されている)

CORYDORAS> insert into date_test_postgresql749_mac@oracle10g_win
2 values('',null,null);
insert into date_test_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-28500: OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[Generic Connectivity Using ODBC]ERROR: invalid input syntax for type date: "" (SQL State: S1000; SQL Code: 7)
ORA-02063: 先行のエラー・メッセージを参照してください2 lines(POSTGRESQL749_MAC)。
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(ORACLE10G_WIN)。

しかし、リテラルでしか登録できないとなると、現在時間や日付を設定したい場合には非常に都合が悪い。スカラー副問合せを利用してみたがこれもエラーとなった。これは困った。

CORYDORAS> 
CORYDORAS> list
1 insert into date_test_postgresql749_mac@oracle10g_win
2 values(
3 (select to_char(sysdate,'yyyymmdd') from dual),
4 (select to_char(systimestamp,'yyyymmdd hh24miss.ff') from dual),
5 (select to_char(sysdate,'hh24miss') from dual)
6* )
CORYDORAS> /
insert into date_test_postgresql749_mac@oracle10g_win
*
行1でエラーが発生しました。:
ORA-02070: データベースPOSTGRESQL749_MACはこのコンテキストではsubqueriesをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

PL/SQLからなら、なんとかなるかとも知れないと以下のようにしてみたが、今度はシノニム変換で問題が発生した。

CORYDORAS> 
CORYDORAS> declare
2 v_datetime_string varchar2(25);
3 v_date_string varchar2(8);
4 v_time_string varchar2(6);
5 begin
6 v_date_string := to_char(sysdate,'yyyymmdd');
7 v_datetime_string := to_char(systimestamp, 'yyyymmdd hh24miss.ff');
8 v_time_string := to_char(sysdate,'hh24miss');
9 --
10 insert into date_test_postgresql749_mac@oracle10g_win
11 values(v_date_string, v_datetime_string, v_time_string);
12 commit;
13 end;
14 /
insert into date_test_postgresql749_mac@oracle10g_win
*
行10でエラーが発生しました。:
ORA-06550: 行10、列3:
PL/SQL: ORA-00980: シノニム変換が無効です。
ORA-06550: 行10、列3:
PL/SQL: SQL Statement ignored

CORYDORAS>

WindowsのOracle10g R1を踏み台にしている関係なのか、無理矢理構築したOracle10g R1 for MacOSX Serverだからなのか確かなことは言えないが、以下のような流れではシノニムの解決ができないようである。

もちろん、Oracle10g for MacOSX Serverで Oracle Heterogeneous ServiceのGeneric connectivityが正式にサポートされればこのような構成

gencon_blog_img1

にする必要はない。。。。趣味というか興味だけでやっていることなので、こんな”おもしろい”(変わっているとも言う)構成してあるのでご注意を。

ちなみにMacOSX Serverの先にあるOracle10g R1 for Windowsからだと上記PL/SQLブロックで実行可能であった。やはり踏み台方式もしくは無理矢理構築したOracle10g for MacOSX Server側の問題のような気がする。。

SQL> declare
2 v_datetime_string varchar2(25);
3 v_date_string varchar2(8);
4 v_time_string varchar2(6);
5 begin
6 v_date_string := to_char(sysdate,'yyyymmdd');
7 v_datetime_string := to_char(systimestamp, 'yyyymmdd hh24miss.ff');
8 v_time_string := to_char(sysdate,'hh24miss');
9 --
10 insert into date_test_postgresql749_mac
11 values(v_date_string, v_datetime_string, v_time_string);
12 commit;
13 end;
14 /

PL/SQLプロシージャが正常に完了しました。

そして最後の悪あがき! 
insert文をexecute immediate文で実行してみた。おお〜〜っ!、Oracle10g for MacOSX ServerからPL/SQLブロックが実行できた瞬間だった。(爆!)

CORYDORAS> list
1 declare
2 v_timestamp_string varchar2(25);
3 v_date_string varchar2(8);
4 v_time_string varchar2(6);
5 v_sql varchar2(1000);
6 begin
7 v_date_string := to_char(sysdate,'yyyymmdd');
8 v_timestamp_string := to_char(systimestamp,'yyyymmdd hh24miss.ff');
9 v_time_string := to_char(sysdate,'hh24miss');
10 v_sql :=
11 'insert into date_test_postgresql749_mac@oracle10g_win values('||
12 '''' || v_date_string ||
13 ''',''' || v_timestamp_string ||
14 ''',''' || v_time_string || ''')'
15 ;
16 execute immediate v_sql;
17 commit;
18* end;
CORYDORAS> /

PL/SQLプロシージャが正常に完了しました。

CORYDORAS> select * from date_test_postgresql749_mac@oracle10g_win;

r_date r_timestamp r_time
------------------- ------------------- -------------------
1900/01/01 00:00:00
2006/01/20 00:00:00
1981/01/01 00:00:00
1990/12/01 00:00:00
0001/01/01 00:00:00
2007/03/07 00:00:00
0001/01/01 00:00:00
2007/09/11 00:00:00
2006/01/01 00:00:00
0001/01/01 23:59:59
2006/01/02 00:00:00
2006/01/02 03:01:00
2006/01/22 00:00:00 2006/01/22 21:57:25 0001/01/01 21:57:25
2008/11/07 04:50:03
2006/12/12 00:00:00
2006/12/12 12:01:01
0001/01/01 23:59:59
2006/01/23 00:00:00 2006/01/23 23:38:56 0001/01/01 23:38:56
2006/01/23 00:00:00 2006/01/23 23:50:34 0001/01/01 23:50:34

19行が選択されました。

CORYDORAS>


今日はここまで。

======
Generic Connectivity
日付、時間型のまとめ(PostgresSQL7.4.9編)

参照時のポイント
・PostgreSQL7.4.9の date型、time型、timestamp型すべてが、Oracleのdate型にマップされる。
・PostgreSQLのtime型は時間だけだが、Oracle側ではdate型になるため、0001/01/01+時間となる。
・PostgreSQLのdate型は日付だけだが、Oracle型ではdate型なので 時間が00:00:00になる。
・PostgreSQLのtimestamp型は、Oracleのdate型にマップされてしまうため、秒の少数部が欠落する。

検索時のポイント
・to_date()を利用してdate型で検索することも、日付、時間を文字列として検索することも可能(Oracleの動きに類似している)

登録時のポイント
・日付、時間を文字列(リテラル)として指定ことしかできない。
・現在時間や、日付を設定する場合は、PL/SQLからINSERT文や、UPDATE文を実行する。
 (但し、このテストで利用しているような特殊構成ではPL/SQLから実行するDMLは、execute immediate文を利用したダイナミックSQLにしたほうがよいかも。この環境では、たまたま動作しただけかもしれないのでご注意を。)

次回はMySQLで同様の確認を行う予定。

| | コメント (0) | トラックバック (0)

2006年1月22日 (日)

Mac De Oracle Heterogeneous! #19

続きです。
日付、時間型がOracle側にはどのようにマッピングされるのか、どのような注意点があるのか検証してみる。
今日はPostgreSQL7.4.9の日付型、時間型について確認してみることにする

まず、PostgreSQL7.4.9のdate型、timestamp型、time型が、Oracleのdate型やtimestamp型とどのような違いがあるのかPostgreSQL上で確認してみることにする。

Oracleだとdate型とtimestamp型だけでなのでdate型が年月日だけ、time型が時間だけを格納するという点は覚えておくと良さそう。
timestamp型はOracleのtimestamp型と同じようなので特に注意する点はなさそうである。

重要なのは、Oracleのdate型やtimestamp型は日付や時間の妥当性チェックが厳しいというか、しっかりしているので日付として妥当でない文字列を受け入れることはないのだが、PostgreSQL7.4.9では、それを”調整して”受け入れてしまう点である。PostgreSQLに慣れている方なら驚くことではないと思うが、Oracleには慣れているが、PostgreSQLは初心者ということになると、かなり戸惑うことになる。(前回利用したdate_test表にtime型の列を追加した表を利用した。)

Last login: Fri Jan 20 22:41:46 on ttyp1
Welcome to Darwin!
pb17:˜ stargrass$ su - postgres
Password:
pb17:˜ postgres$ postmaster -S
pb17:˜ postgres$
pb17:˜ postgres$ psql -U scott postgresql749
Password:
Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=> alter table date_test add column r_time time;
ALTER TABLE
postgresql749=> commit;
COMMIT
postgresql749=> ¥d date_test;
Table "scott.date_test"
Column | Type | Modifiers
-------------+-----------------------------+-----------
r_date | date |
r_timestamp | timestamp without time zone |
r_time | time without time zone |

postgresql749=> select * from date_test;
r_date | r_timestamp | r_time
------------+---------------------+--------
1900-01-01 | |
2006-01-20 | |
| 1981-01-01 00:00:00 |
| 1990-12-01 00:00:00 |
(4 rows)

※Oracleならエラーになる。
postgresql749=> insert into date_test values(to_date('00000000','yyyymmdd'),null,null);
INSERT 25433 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(to_date('20061435','yyyymmdd'),null,null);
INSERT 25434 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(null,to_date('00000000','yyyymmdd'),null);
INSERT 25435 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(null,to_date('20062040','yyyymmdd'),null);
INSERT 25436 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(null,to_date('20060101479999','yyyymmddhh24miss'),null);
INSERT 25437 1

postgresql749=> insert into date_test values(null,null,'235959');
INSERT 25438 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(null,'2006-01-01 240000',null);
INSERT 25439 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(null,'2006-01-01 266060',null);
INSERT 25440 1


postgresql749=> insert into date_test values(current_date, current_timestamp, current_time);
INSERT 25441 1

※Oracleならエラーになる。
postgresql749=> insert into date_test values(null,to_timestamp('20063433284963','yyyymmddhh24miss'),null);
INSERT 25442 1
postgresql749=> commit;
COMMIT
postgresql749=> select * from date_test;
r_date | r_timestamp | r_time
---------------+----------------------------+-----------------
1900-01-01 | |
2006-01-20 | |
| 1981-01-01 00:00:00 |
| 1990-12-01 00:00:00 |
0001-01-01 BC | |
2007-03-07 | |
| 0001-01-01 00:00:00 BC |
| 2007-09-11 00:00:00 |
| 2006-01-01 00:00:00 |
| | 23:59:59
| 2006-01-02 00:00:00 |
| 2006-01-02 03:01:00 |
2006-01-22 | 2006-01-22 21:57:25.372923 | 21:57:25.372923
| 2008-11-07 04:50:03 |
(14 rows)

postgresql749=>
postgresql749=>

※空文字は指定できないようだ。(Oracleでは、空文字もNULLとして扱っているので Genneric Connectivity経由だとエラーにはならないかもしれない)
postgresql749=> insert into date_test values('',null,null);
ERROR: invalid input syntax for type date: ""
postgresql749=> rollback;
ROLLBACK

見ての通り、Oracleではエラーになるケースが含まれているのだがPostgreSQLではすべて正常に登録できてしまう。(しかも日付は調整された形で登録されてしまう。)
Oracleに慣れていると日付や時間に設定する文字列が日付や時間として妥当であるか厳密にチェックされているという事に慣れすぎているのでかなり驚く。
14月とか20月、63秒なんて存在しないからエラーにするという考え方のOracleと、14月と指定すれば1年と2ヶ月として”勝手に”日付を調整してくれるPostgreSQL、戸惑わないほうがおかしい。


上記は、to_date()や、to_timestamp()という関数の動きなのだが、以下のようにto_date()やto_timestamp()関数を利用しないで暗黙型変換?を利用すると挙動が異なるのでさらに戸惑う。
文字列のままで暗黙型変換だと、ちゃんと文字列が日付や時間として妥当な文字列かチェックしてくれるのである。いや〜結構ハマりそうだ。

postgresql749=> insert into date_test values('00000000',null,null);
ERROR: date/time field value out of range: "00000000"
HINT: Perhaps you need a different "datestyle" setting.
postgresql749=> insert into date_test values('20060101',null,null);
ERROR: current transaction is aborted, commands ignored until end of transaction block
postgresql749=> rollback;
ROLLBACK

postgresql749=> insert into date_test values('20060101',null,null);
INSERT 25443 1

postgresql749=> insert into date_test values('20061349',null,null);
ERROR: date/time field value out of range: "20061349"
HINT: Perhaps you need a different "datestyle" setting.
postgresql749=> insert into date_test values('2006-13-49',null,null);
ERROR: current transaction is aborted, commands ignored until end of transaction block
postgresql749=> select * from date_test;
ERROR: current transaction is aborted, commands ignored until end of transaction block
postgresql749=> rollback;
ROLLBACK

postgresql749=> insert into date_test values('2006-13-49',null,null);
ERROR: date/time field value out of range: "2006-13-49"
HINT: Perhaps you need a different "datestyle" setting.
postgresql749=> rollback;
ROLLBACK

postgresql749=>

ということで今日はここまで。
次回は、Genneric Connectivity経由でPostgreSQLに日付や時間を登録してみる。(どのようになるか楽しみである。)

---
都心では9センチの積雪とか言っていたけど、車にはもっと積もっているような気がする。

| | コメント (0) | トラックバック (0)

2006年1月21日 (土)

Mac De Oracle Heterogeneous! #18

前回からのつづきです。
Generic Connectivity経由でMySQLにアクセスする際、日付型ではうまく検索できないというものだった。

データ型のマッピンングについて確認していこうと思うが、その前に、日付を条件に指定した検索ができないという問題を回避する方法を探してみることにした。

対象データを日付で絞り込もうとして where句に指定してみると正しく検索できない。

CORYDORAS> list
1 select
2 *
3 from
4 oracle_emp_mysql4026_win@oracle10g_win
5 where
6* "hiredate" >= to_date('19870101','yyyymmdd')
CORYDORAS> /

empno ename job mgr hiredate sal comm deptno
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850
7782 CLARK MANAGER 7839 81-06-09 2450 10
7788 SCOTT ANALYST 7566 87-04-19 3000 20
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7876 ADAMS CLERK 7788 87-05-23 1100 20
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10

14行が選択されました。

経過: 00:00:00.10
CORYDORAS>

上記は、Windows XP Professionalに構築したMySQL4.0.26-nt.
その他のPlatformに構築したMySQLそれにPostgreSQLでも確認してみることにした。

PowerMac G5 Dual 2.7Ghz MacOSX Tiger Serverに構築した MySQL4.1.13a及び、PowerBookに構築した PostgreSQL7.4.9の日付型について試してみた。

今回は以下のような経路でアクセスした。

gencon_blog_img1


dump()関数で型を確認するのもいいがDATEかTIMESTAMPのいずれかなので以下のようなフォーマットを設定して区別しやすくしておく。
どちらの形式で表示されるかでマッピングされているのがdate型かtimestamp型なのかが判る。

CORYDORAS> alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss';

セッションが変更されました。

CORYDORAS> alter session set nls_timestamp_format = 'yyyy/mm/dd hh24:mi:ss.ff';

セッションが変更されました。

CORYDORAS>

まずは、PowerMac G5 Dual 2.7Ghz MacOSX Tiger ServerのMySQL4.1.13aで検証した。以下のようなデータを用意。
r_datetime:datetime型、
r_date:date型、
r_timestamp:timestamp型
としてある。
マニュアルによればOracle側ではdate型にマップされることになっているようだ。(実際にはODBCドライバの実装に影響されるようだが。今回 Generic Connectivityで利用しているODBCドライバについてはこちらを参照してほしい。
全データを問い合わせてみると、全てNLS_DATE_FORMATに指定した書式で表示されているのでDATE型にマッピングされているのが判る。

CORYDORAS> 
CORYDORAS> select * from date_test_mysql4113a_mac_sv@oracle10g_win;

r_datetime r_date r_timestamp
------------------- ------------------- -------------------
1990/01/01 00:00:00 2006/01/20 23:04:22
2000/12/01 00:00:00 2006/01/20 23:04:35
1800/01/01 00:00:00 2006/01/20 23:04:51
1810/12/01 00:00:00 2006/01/20 23:05:06
2002/12/01 00:00:00
2006/01/20 23:05:33

6行が選択されました。

では、早速、MySQLのデータを日付を条件として検索してみる。DATE型にマッピングされているようなので、to_date()関数を利用してDATE型同士で検索してみるが1件もヒットしない。
CORYDORAS> select *
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5 "r_datetime" <= to_date('19910101','yyyymmdd');

レコードが選択されませんでした。

文字列として比較させると該当するデータが返される。どうやらDATE型ではうまく検索できないようである。
CORYDORAS> select * 
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5 "r_datetime" = '19900101';

r_datetime r_date r_timestamp
------------------- ------------------- -------------------
1990/01/01 00:00:00 2006/01/20 23:04:22

1行が選択されました。

暗黙型変換ではなく、to_char()により明示的に文字列に変換して比較してみると、やはり、正しい結果が得られた。
CORYDORAS> list
1 select *
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5* to_char("r_datetime",'yyyymmdd') >= '19900201'
CORYDORAS> /

r_datetime r_date r_timestamp
------------------- ------------------- -------------------
2000/12/01 00:00:00 2006/01/20 23:04:35

1行が選択されました。

MySQLのdate型、及び、timestamp型についても同様の結果だった。
CORYDORAS> select *
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5 "r_date" <= to_date('18100101','yyyymmdd');

レコードが選択されませんでした。

CORYDORAS> select *
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5 "r_date" <= '18100101';

r_datetime r_date r_timestamp
------------------- ------------------- -------------------
1800/01/01 00:00:00 2006/01/20 23:04:51

1行が選択されました。

CORYDORAS> select *
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5 "r_timestamp" <= to_date('20040101','yyyymmdd');

レコードが選択されませんでした。

CORYDORAS> list
1 select *
2 from
3 date_test_mysql4113a_mac_sv@oracle10g_win
4 where
5* "r_timestamp" <= '20040101'
CORYDORAS> /

r_datetime r_date r_timestamp
------------------- ------------------- -------------------
2002/12/01 00:00:00

1行が選択されました。

CORYDORAS>


MySQLでは、date型の検索に多少難ありという結果だったが、PostgreSQL7.4.9ではどうなるかも検証してみた。
PostgreSQL7.4.9では、r_dateをdate型、r_timestampをtimestamp型として定義した。問い合わせると、NLS_DATE_FORMATに指定した書式で表示されるので、これらの型もOracle側ではdate型にマッピングされていることが判る。

CORYDORAS> 
CORYDORAS> select * from date_test_postgresql749_mac@oracle10g_win;

r_date r_timestamp
------------------- -------------------
1900/01/01 00:00:00
2006/01/20 00:00:00
1981/01/01 00:00:00
1990/12/01 00:00:00

4行が選択されました。

MySQLの時と同様に、to_date()関数によるdate型での検索、文字列(暗黙型変換)、to_char()関数による明示型変換それぞれについて検証してみた。結果は、どの方法でも正しく検索できた。
Genneric Connectivity経由のアクセスでは、(Oracleデータベースに慣れている方なら)違和感無く利用できる可能性が高いPostgreSQLのほうが楽だと感じる場面が多いかもしれない。(私感)
CORYDORAS> select *
2 from
3 date_test_postgresql749_mac@oracle10g_win
4 where
5 "r_date" <= to_date('19900101','yyyymmdd');

r_date r_timestamp
------------------- -------------------
1900/01/01 00:00:00

1行が選択されました。

CORYDORAS> select *
2 from
3 date_test_postgresql749_mac@oracle10g_win
4 where
5 to_char("r_date",'yyyymmdd') <= '19900101';

r_date r_timestamp
------------------- -------------------
1900/01/01 00:00:00

1行が選択されました。

CORYDORAS> select *
2 from
3 date_test_postgresql749_mac@oracle10g_win
4 where
5 "r_date" <= '19900101';

r_date r_timestamp
------------------- -------------------
1900/01/01 00:00:00

1行が選択されました。

CORYDORAS> select *
2 from
3 date_test_postgresql749_mac@oracle10g_win
4 where
5 "r_timestamp" <= to_date('19820101');

r_date r_timestamp
------------------- -------------------
1981/01/01 00:00:00

1行が選択されました。

CORYDORAS> select *
2 from
3 date_test_postgresql749_mac@oracle10g_win
4 where
5 to_char("r_timestamp",'yyyymmdd') <= '19820101';

r_date r_timestamp
------------------- -------------------
1981/01/01 00:00:00

1行が選択されました。

CORYDORAS> select *
2 from
3 date_test_postgresql749_mac@oracle10g_win
4 where
5 "r_timestamp" <= '19810101';

r_date r_timestamp
------------------- -------------------
1981/01/01 00:00:00

1行が選択されました。

CORYDORAS>

まとめ。
日付型に関して、Generic Connectivity経由(ODBCドライバ経由)の検索では以下のような点に注意する必要がある。
(各ODBCドライバがアップデートされると挙動が異なる可能性が高いので、実際に利用する際には事前に実機調査されることをお勧めする)

MySQLの日付型をGeneric Connectivity経由で検索する場合には、文字型に変換して検索する。
PostgreSQLの日付型をGenneric Connecvitity経由で検索する場合には、日付型でも文字型でも検索できるので特に注意する点はない。(但し、パフォーマンス面を考えると日付型で検索したほうがよいのではないか?。未検証なので想像ですが。)

次回は、Generic Connectivity経由でリンクされているMySQL4.0.x,4.1.x及びPostgreSQL7.4.9の時間型などについて、Oracle側ではどの型にマッピングされ、どのような”癖”があるのか見てみることにする。

| | コメント (0) | トラックバック (0)

2006年1月20日 (金)

Mac De Oracle Heterogeneous! #17

つづきです。今日は分析用関数編(すべてではないですが、幾つか試してみました。簡単なところだけですが。。)
gencon_blog_img1

以下のような emp表がMySQL上にあります。おなじみの表です。

CORYDORAS> select * from oracle_emp_mysql4026_win@oracle10g_win;

empno ename job mgr hiredate sal comm deptno
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500 30
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850 30
7782 CLARK MANAGER 7839 81-06-09 2450 10
7788 SCOTT ANALYST 7566 87-04-19 3000 20
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7876 ADAMS CLERK 7788 87-05-23 1100 20
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10

14行が選択されました。

CORYDORAS>

ランキング関数 RANK() 。 

CORYDORAS> 
CORYDORAS> list
1 select
2 rank() over (order by "sal") as rank,
3 "empno",
4 "ename",
5 "sal"
6 from
7* oracle_emp_mysql4026_win@oracle10g_win
CORYDORAS> /

RANK empno ename sal
---------- ---------- -------------------- ----------
1 7369 SMITH 800
2 7900 JAMES 950
3 7876 ADAMS 1100
4 7521 WARD 1250
4 7654 MARTIN 1250
6 7934 MILLER 1300
7 7844 TURNER 1500
8 7499 ALLEN 1600
9 7782 CLARK 2450
10 7698 BLAKE 2850
11 7566 JONES 2975
12 7788 SCOTT 3000
12 7902 FORD 3000
14 7839 KING 5000

14行が選択されました。

CORYDORAS>

同じくランキング関数 ROW_NUMBER()。

CORYDORAS> list
1 select
2 row_number() over (order by "empno") as row_number,
3 "empno",
4 "ename"
5 from
6* oracle_emp_mysql4026_win@oracle10g_win
CORYDORAS> /

ROW_NUMBER empno ename
---------- ---------- --------------------
1 7369 SMITH
2 7499 ALLEN
3 7521 WARD
4 7566 JONES
5 7654 MARTIN
6 7698 BLAKE
7 7782 CLARK
8 7788 SCOTT
9 7839 KING
10 7844 TURNER
11 7876 ADAMS
12 7900 JAMES
13 7902 FORD
14 7934 MILLER

14行が選択されました。

経過: 00:00:00.03
CORYDORAS>

集計ウィンドウ関数 FIRST_VALUE() 及び、LAST_VALUE()。

CORYDORAS> break on deptno on first_empno on last_empno skip page
CORYDORAS> list
1 select
2 first_value("empno")
3 over
4 (
5 partition by "deptno"
6 ) as first_empno,
7 last_value("empno")
8 over
9 (
10 partition by "deptno"
11 ) as last_empno,
12 "deptno",
13 "empno",
14 "ename"
15 from
16 oracle_emp_mysql4026_win@oracle10g_win
17 order by
18 "deptno",
19* "empno"
CORYDORAS> /

FIRST_EMPNO LAST_EMPNO deptno empno ename
----------- ---------- ---------- ---------- --------------------
7782 7934 10 7782 CLARK
7839 KING
7934 MILLER

FIRST_EMPNO LAST_EMPNO deptno empno ename
----------- ---------- ---------- ---------- --------------------
7369 7902 20 7369 SMITH
7566 JONES
7788 SCOTT
7876 ADAMS
7902 FORD

FIRST_EMPNO LAST_EMPNO deptno empno ename
----------- ---------- ---------- ---------- --------------------
7499 7900 30 7499 ALLEN
7521 WARD
7654 MARTIN
7698 BLAKE
7844 TURNER
7900 JAMES

14行が選択されました。

経過: 00:00:00.05
CORYDORAS>

ここまでは、分析用関数を簡単な構文で試していたのだが、その過程でちょっと気になることがあった。
Generic ConnectivityでリンクしているMySQLの日付型である。ODBC経由では MySQL側のDatetime型は、OracleのDATE型にマップされるようなのだが。。。

CORYDORAS> list
1 select
2 "ename",
3 to_char("hiredate", 'yyyy/mm/dd') as hiredate
4 from
5* oracle_emp_mysql4026_win@oracle10g_win
CORYDORAS> /

ename HIREDATE
-------------------- ----------
SMITH 1980/12/17
ALLEN 1981/02/20
WARD 1981/02/22
JONES 1981/04/02
MARTIN 1981/09/28
BLAKE 1981/05/01
CLARK 1981/06/09
SCOTT 1987/04/19
KING 1981/11/17
TURNER 1981/09/08
ADAMS 1987/05/23
JAMES 1981/12/03
FORD 1981/12/03
MILLER 1982/01/23

14行が選択されました。

経過: 00:00:00.05

対象データを日付で絞り込もうとして where句に指定してみると以下のようになってしまう。

CORYDORAS> list
1 select
2 *
3 from
4 oracle_emp_mysql4026_win@oracle10g_win
5 where
6* "hiredate" >= to_date('19870101','yyyymmdd')
CORYDORAS> /

empno ename job mgr hiredate sal comm deptno
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850
7782 CLARK MANAGER 7839 81-06-09 2450 10
7788 SCOTT ANALYST 7566 87-04-19 3000 20
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7876 ADAMS CLERK 7788 87-05-23 1100 20
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10

14行が選択されました。

経過: 00:00:00.10
CORYDORAS>

あれ? 条件に合わないデータまで取得できちゃうの? なんで?
ということで、次回からは異機種データベースとのデータ型の相性というか、データ型マッピングについて確認してみようと思う。
Generic Connectivityの場合、間にあるODBCドライバの影響も受けるはずなのでどのようなことになりますか。。。

ちなみに、oracle10g R1 for MacOSX Server -> oracle10g R1 for Windows間で同じことをやってみると予想通り正しい結果が返る。

CORYDORAS> list
1* select * from emp@oracle10g_win
CORYDORAS> /

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7788 SCOTT ANALYST 7566 87-07-13 3000 20
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500 30
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850 30
7782 CLARK MANAGER 7839 81-06-09 2450 10
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10
7876 ADAMS CLERK 7788 87-07-13 1100 20

14行が選択されました。

CORYDORAS> select *
2 from
3 emp@oracle10g_win
4 where
5 hiredate >= to_date('19870101','yyyymmdd');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7788 SCOTT ANALYST 7566 87-07-13 3000 20
7876 ADAMS CLERK 7788 87-07-13 1100 20

CORYDORAS>

次回につづく。

| | コメント (0) | トラックバック (0)

2006年1月19日 (木)

Mac De Oracle Heterogeneous! #16

さて、Generic Connectivityネタはまだ続きます。
今日はMySQLに Oracleではおなじみの scott.emp表を作り、階層問合せをやってみよう!
できるのか不安だが。。

Last login: Tue Jan 17 20:51:04 on console
Welcome to Darwin!
G5Server:˜ discus$ su - oracle
Password:
G5Server:˜ oracle$ sqlplus /nolog

SQL*Plus: Release 10.1.0.3.0 - Production on 火 1月 17 23:08:28 2006

Copyright (c) 1982, 2004, Oracle. All rights reserved.

> conn / as sysdba
アイドル・インスタンスに接続しました。
SYS> startup
ORACLEインスタンスが起動しました。

Total System Global Area 293601280 bytes
Fixed Size 778888 bytes
Variable Size 99360120 bytes
Database Buffers 192937984 bytes
Redo Buffers 524288 bytes
データベースがマウントされました。
データベースがオープンされました。
SYS>
SYS> conn corydoras
パスワードを入力してください:
接続されました。
CORYDORAS>
CORYDORAS>
CORYDORAS>
CORYDORAS>

Oracleではおなじみの、scottユーザにある emp表をMySQL4.0.26 Windowsに作成し、ORACLE_EMP_MYSQL4026_WIN というシノニムを Windows の Oracle10g R1に作成した。

アクセス経路は以下のようなイメージになる。
gencon_blog_img1


CORYDORAS> select synonym_name from user_synonyms@oracle10g_win;

SYNONYM_NAME
------------------------------
EMP_MYSQL4025_MAC
INNO_EMP_MYSQL4025_MAC
EMP_MYSQL4026_WIN
EMP_MYSQL4113A_MAC_SV
EMP_POSTGRESQL749_MAC
ORACLE_EMP_MYSQL4026_WIN

6行が選択されました。

CORYDORAS> select * from oracle_emp_mysql4026_win@oracle10g_win;

empno ename job mgr hiredate sal comm deptno
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500 30
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850 30
7782 CLARK MANAGER 7839 81-06-09 2450 10
7788 SCOTT ANALYST 7566 87-04-19 3000 20
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7876 ADAMS CLERK 7788 87-05-23 1100 20
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10

14行が選択されました。

CORYDORAS>

階層問合せを実行してみると・・・・。
CORYDORAS> list
1 select
2 level,
3 "empno",
4 "ename",
5 "mgr"
6 from
7 oracle_emp_mysql4026_win@oracle10g_win
8 start with
9 "mgr" is null
10 connect by
11* prior "empno" = "mgr"
CORYDORAS> /
select
*
行1でエラーが発生しました。:
ORA-02070: データベースMYSQL4026_WINはこのコンテキストではa connect by clauseをサポートしません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。

できないかな〜。
しばし考え込む、MySQL側で階層問い合わせができないのは当然なのだが、階層問い合せ自体ががスルーされないようにできないか。。。
お! ダミー表を用意して外部結合すれば・・・・・早速試してみる。
CORYDORAS> 
CORYDORAS> list
1 select
2 lpad(' ',(level-1)*2,' ')||"empno" as empno,
3 "ename",
4 "mgr",
5 connect_by_isleaf as "Is leaf?"
6 from
7 oracle_emp_mysql4026_win@oracle10g_win remote left outer join
8 (select -1 as dummy from dual) dummy
9 on remote."empno" = dummy.dummy
10 start with
11 "mgr" is null
12 connect by
13* prior "empno" = "mgr"
CORYDORAS> /

EMPNO ename mgr Is leaf?
-------------------- -------------------- ---------- ----------
7839 KING 0
7566 JONES 7839 0
7788 SCOTT 7566 0
7876 ADAMS 7788 1
7902 FORD 7566 0
7369 SMITH 7902 1
7698 BLAKE 7839 0
7499 ALLEN 7698 1
7521 WARD 7698 1
7654 MARTIN 7698 1
7844 TURNER 7698 1
7900 JAMES 7698 1
7782 CLARK 7839 0
7934 MILLER 7782 1

14行が選択されました。

経過: 00:00:00.11
CORYDORAS>
CORYDORAS>

ということで階層問い合せを実行することができた。
ついでに実行計画を取ってみると。
CORYDORAS> set autot trace
CORYDORAS> /

14行が選択されました。


実行計画
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=55 Card=2000 Bytes=80000)
1 0 CONNECT BY (WITH FILTERING)
2 1 FILTER
3 2 COUNT
4 3 HASH JOIN (RIGHT OUTER) (Cost=55 Card=2000 Bytes=80000)
5 4 TABLE ACCESS (FULL) OF 'DUAL' (TABLE) (Cost=2 Card=1 Bytes=2)
6 4 REMOTE* (Cost=52 Card=2000 Bytes=76000) ORACLE10G_WIN
7 1 HASH JOIN
8 7 CONNECT BY PUMP
9 7 COUNT
10 9 HASH JOIN (RIGHT OUTER) (Cost=55 Card=2000 Bytes=80000)
11 10 TABLE ACCESS (FULL) OF 'DUAL' (TABLE) (Cost=2 Card=1 Bytes=2)
12 10 REMOTE* (Cost=52 Card=2000 Bytes=76000) ORACLE10G_WIN
13 1 COUNT
14 13 HASH JOIN (RIGHT OUTER) (Cost=55 Card=2000 Bytes=80000)
15 14 TABLE ACCESS (FULL) OF 'DUAL' (TABLE) (Cost=2 Card=1 Bytes=2)
16 14 REMOTE* (Cost=52 Card=2000 Bytes=76000) ORACLE10G_WIN


6 SERIAL_FROM_REMOTE SELECT "empno","ename","mgr" FROM "ORACLE_EMP_MYSQL4026_WIN" "REMOTE"
12 SERIAL_FROM_REMOTE SELECT "empno","ename","mgr" FROM "ORACLE_EMP_MYSQL4026_WIN" "REMOTE"
16 SERIAL_FROM_REMOTE SELECT "empno","ename","mgr" FROM "ORACLE_EMP_MYSQL4026_WIN" "REMOTE"


統計
----------------------------------------------------------
0 recursive calls
0 db block gets
15 consistent gets
0 physical reads
0 redo size
917 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
14 rows processed

CORYDORAS>

巨大な表で重くなることも覚悟の上であればこの手法を用いればいろいろとできそうではある。

| | コメント (0) | トラックバック (0)

2006年1月18日 (水)

Mac De Oracle Heterogeneous! #15

Generic Connectivityの続き。

前回はリモートトランザクションと分散トランザクションについて確認したが、分散クエリーはどうなのか? 念のため確認しておこう。

unionを利用してSQL1文で行ってみた。尚、表及びデータベースリンクはシノニムにしてあるので必要ないのだが、列名は引用識別子にする必要があるのでお忘れなく。

CORYDORAS> 
CORYDORAS> break on table_name skip page
CORYDORAS> select
2 'mysql4025_mac.emp' as table_name,
3 "empno",
4 "ename"
5 from
6 emp_mysql4025_mac@oracle10g_win
7 union all
8 select
9 'mysql4025_mac.inno_emp' as table_name,
10 "empno",
11 "ename"
12 from
13 inno_emp_mysql4025_mac@oracle10g_win
14 union all
15 select
16 'mysql4026_win.emp' as table_name,
17 "empno",
18 "ename"
19 from
20 emp_mysql4026_win@oracle10g_win
21 union all
22 select
23 'mysql4113a_mac_sv.emp' as table_name,
24 "empno",
25 "ename"
26 from
27 emp_mysql4113a_mac_sv@oracle10g_win
28 union all
29 select
30 'postgresql749_mac.emp' as table_name,
31 "empno",
32 "ename"
33 from
34 emp_postgresql749_mac@oracle10g_win
35 order by
36 1,2;

TABLE_NAME empno ename
------------------------------ ---------- ------------------------------
mysql4025_mac.emp 1 おらおら
2 ほげ
3 化けないよねー〜
4 can't rollback

TABLE_NAME empno ename
------------------------------ ---------- ------------------------------
mysql4025_mac.inno_emp 1 おらおら
2 ほげ
3 化けないよねー〜
4 -ー−〜˜

TABLE_NAME empno ename
------------------------------ ---------- ------------------------------
mysql4026_win.emp 1 おらおら
2 ほげ
3 化けないよな〜−
4 -ー−〜˜

TABLE_NAME empno ename
------------------------------ ---------- ------------------------------
mysql4113a_mac_sv.emp 1 ほげほげ
2 ほげ
3 化けないよな〜−
4 -ー−〜˜

TABLE_NAME empno ename
------------------------------ ---------- ------------------------------
postgresql749_mac.emp 1 ほげほげ
2 ほげ
3 化けないよね〜ー
4 -ー−〜˜

20行が選択されました。

経過: 00:00:00.63
CORYDORAS>

問題なくできそうだ。

| | コメント (0) | トラックバック (0)

2006年1月17日 (火)

Mac De Oracle Heterogeneous! #14

前回にひきつづき、Generic Connectivityでのトランザクションに関連する挙動を見てみた。

Generic Connectivityでは分散トランザクションは行えない。
分散トランザクションを行おうとした場合、どのようなエラーが発生するか見てみることにする。

CORYDORAS> 
CORYDORAS> -- ここまでは、リモートトランザクションなので問題なく実行できる。
CORYDORAS> insert into emp_mysql4026_win@oracle10g_win values(5,'remote transaction');

1行が作成されました。

経過: 00:00:00.03
CORYDORAS>
CORYDORAS> -- 異なるデータベースを更新しようとしているのでここで分散トランザクションになる。
CORYDORAS> insert into emp_mysql4113a_mac_sv@oracle10g_win values(5,'distributed transaction');
insert into emp_mysql4113a_mac_sv@oracle10g_win values(5,'distributed transaction')
*
行1でエラーが発生しました。:
ORA-02047: 動作中の分散トランザクションは結合できません。
ORA-02063: 先行のエラー・メッセージを参照してくださいline(ORACLE10G_WIN)。


経過: 00:00:00.05
CORYDORAS> rollback;

ロールバックが完了しました。

経過: 00:00:00.05
CORYDORAS>

簡単なテストでトランザクションに関する挙動を見てきたが、リモートトランザクションとして実行するようにすれば特に面倒なことはなさそうである。
MySQLを利用する場合には、非トランザクションセーフなエンジンが表に利用されていないか確認しておいたほうがよい。

| | コメント (0) | トラックバック (0)

2006年1月16日 (月)

Mac De Oracle Heterogeneous! #13

前回からのつづきです。

Generic Connectivityを利用し、異機種データベースのデータを更新するリモートトランザクションの挙動を確認する。

(Oracle Generic Connectivityではトランザクションに関する制限があり分散トランザクションは行えない。リモートトランザクションとローカルトランザクションだけが行えるということになる。)

PowerBook G4 MacOSX Tiger 10.4.3に構築したMySQL4.0.25のemp表は、エンジンにMyISAMを利用している。MyISAMは非トランザクションセーフである。つまり、トランザクションという概念が存在しない。commit文、rollback文がその意味をなさないのである。したがって、INSERT文、UPDATE文、DELETE文を発行すると即座に反映され、rollbackすることはできない。MySQLをリモートデータベースにしている場合にはアクセスする表がトランザクションセーフなエンジンを利用しているかを事前に確認しておいたほうがよいだろう。

CORYDORAS> 
CORYDORAS> insert into emp_mysql4025_mac@oracle10g_win values(4,'can''t rollback');

1行が作成されました。

経過: 00:00:00.68
CORYDORAS> select * from emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜
4 can't rollback

経過: 00:00:00.03
CORYDORAS> rollback;

ロールバックが完了しました。

経過: 00:00:00.05
CORYDORAS> select * from emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜
4 can't rollback

経過: 00:00:00.05
CORYDORAS>

さて、同じデータベースにInnoDBをエンジンとして作成した表はトランザクションセーフなのでrollbackすることができる。

CORYDORAS> 
CORYDORAS> insert into inno_emp_mysql4025_mac@oracle10g_win values(5,'rollback test');

1行が作成されました。

経過: 00:00:00.03
CORYDORAS> select * from inno_emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜
4 -ー−〜˜
5 rollback test

経過: 00:00:00.43
CORYDORAS> rollback;

ロールバックが完了しました。

経過: 00:00:00.15
CORYDORAS> select * from inno_emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜
4 -ー−〜˜

経過: 00:00:00.06
CORYDORAS>

PostgreSQLもトランザクションセーフなのでrollbackすることができる。

CORYDORAS> 
CORYDORAS> insert into emp_postgresql749_mac@oracle10g_win values(5,'rollback test');

1行が作成されました。

経過: 00:00:00.03
CORYDORAS> select * from emp_postgresql749_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよね〜ー
4 -ー−〜˜
5 rollback test

経過: 00:00:00.03
CORYDORAS> rollback;

ロールバックが完了しました。

経過: 00:00:00.01
CORYDORAS> select * from emp_postgresql749_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよね〜ー
4 -ー−〜˜

経過: 00:00:00.06
CORYDORAS>

次回は分散トランザクションを行おうとするとどのようなエラーが返されるか確認してみることにする。

| | コメント (0) | トラックバック (0)

2006年1月15日 (日)

Mac De Oracle Heterogeneous! #12

使用しているフォントによっては判りにくいかもしれないが

半角ダッシュ  :"-"
カタカナ長音符号:"ー"
全角ダッシュ  :"−"
全角波線    :"〜"
チルダ(半角):"˜"

を 

Oracle10g R1 (MacOSX Tiger Server) ---database link + synonym --->
---> Oracle10g R1 (Windows) ---> database link + generic connectivity + odbc--->
---> MySQL or PostgreSQLの表

という流れで Oracle10g R1 (MacOSX Tiger Server)からデータを登録し、

Oracle10g R1 (MacOSX Tiger Server) <---
<--- database link + synonym <--- Oracle10g R1 (windows) <---
<--- database link + generic connectivity + odbc <--- MySQL or PostgreSQLの表

という流れで Oracle10g R1 (MacOSX Tiger Server)より問合せ、文字化けしないか確認してみた。
イメージはこんな感じ
gencon_blog_img1

CORYDORAS> insert into inno_emp_mysql4025_mac@oracle10g_win values(4,'-ー−〜˜');

1行が作成されました。

経過: 00:00:01.51
CORYDORAS> commit;

コミットが完了しました。

経過: 00:00:00.18
CORYDORAS> insert into emp_mysql4026_win@oracle10g_win values(4,'-ー−〜˜');

1行が作成されました。

経過: 00:00:00.05
CORYDORAS> commit;

コミットが完了しました。

経過: 00:00:00.05
CORYDORAS> insert into emp_mysql4113a_mac_sv@oracle10g_win values(4,'-ー−〜˜');

1行が作成されました。

経過: 00:00:00.10
CORYDORAS> commit;

コミットが完了しました。

経過: 00:00:00.16
CORYDORAS> insert into emp_postgresql749_mac@oracle10g_win values(4,'-ー−〜˜');

1行が作成されました。

経過: 00:00:00.05
CORYDORAS> commit;

コミットが完了しました。

経過: 00:00:00.63
CORYDORAS>
CORYDORAS> select * from inno_emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜
4 -ー−〜˜

経過: 00:00:00.08
CORYDORAS> select * from emp_mysql4026_win@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよな〜−
4 -ー−〜˜

経過: 00:00:00.05
CORYDORAS> select * from emp_mysql4113a_mac_sv@oracle10g_win;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよな〜−
4 -ー−〜˜

経過: 00:00:00.06
CORYDORAS> select * from emp_postgresql749_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよね〜ー
4 -ー−〜˜

経過: 00:00:00.05
CORYDORAS>

これらに関しては特に問題はでていないようである。
次回はこの環境でトランザクションはどうなるのか?  簡単に確認してみることにする。

| | コメント (0) | トラックバック (0)

2006年1月14日 (土)

Mac De Oracle Heterogeneous! #11

前回からのつづきです。
やっと準備が完了といいますか、Windowsに作成したOracle10g R1 10.1.0.3.0からMySQLやPostgreSQLにアクセスできることまでは確認した。
さて、問題になるのは、どうやってPowerMac G5 Dual2.7Ghz Oracle10g R1 10.1.0.3.0 for MacOSX ServerからWindows版 Oracle10g R1の向うにあるMySQLやPostgreSQLにアクセスするのかという点である。
データベースリンクのネストなんて文法上許されてない訳だし。。。で思いついたのが。。。。

シノニムを利用するということだった。

では早速、Windows XP Professionalに作成したOracle10g R1 10.1.0.3.0に作ったデータベースリンクを利用して、各データベースに作成した emp表向けシノニムを作成する。

まずは作成済みデータベースリンクを確認しておく。

SQL*Plus: Release 10.1.0.2.0 - Production on 土 1月 14 17:22:34 2006

Copyright (c) 1982, 2004, Oracle. All rights reserved.
SQL> conn / as sysdba
接続されました。
SQL> select * from v$version;

BANNER
---------------------------------------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Prod
PL/SQL Release 10.1.0.3.0 - Production
CORE 10.1.0.3.0 Production
TNS for 32-bit Windows: Version 10.1.0.3.0 - Production
NLSRTL Version 10.1.0.3.0 - Production

SQL>
SQL> conn discus
パスワードを入力してください: ************
接続されました。
SQL> select db_link from user_db_links;

DB_LINK
--------------------------------------------------------------------------------
MYSQL4025_MAC
MYSQL4026_WIN
MYSQL4113A_MAC_SV
POSTGRESQL749_MAC

この例では、プライベート・シノニムを作成した。シノニムは各データベースのemp表毎に作成した。
尚、MySQL4.0.25 に作成した emp表は MyISAM 、inno_emp表は、InnoDBその他のMySQLでは、emp表はInnoDBをエンジンとしている。

SQL> set linesize 132
SQL> col ename for a30
SQL>
SQL> -- PowerMac G4 MacOSX Tiger 10.4.3 MySQL4.0.25
SQL> create synonym emp_mysql4025_mac for "emp"@mysql4025_mac;

シノニムが作成されました。

SQL> -- PowerMac G4 MacOSX Tiger 10.4.3 MySQL4.0.25
SQL> create synonym inno_emp_mysql4025_mac for "inno_emp"@mysql4025_mac;

シノニムが作成されました。

SQL> -- AMD AthronMP Dual 2800+ Windows XP Professional
SQL> create synonym emp_mysql4026_win for "emp"@mysql4026_win;

シノニムが作成されました。

SQL> -- PowerMac G5 Dual 2.7Ghz MacOSX Tiger 10.4.3 Server MySQL4.1.13a
SQL> create synonym emp_mysql4113a_mac_sv for "emp"@mysql4113a_mac_sv;

シノニムが作成されました。

SQL> -- PowerMac G4 MacOSX Tiger 10.4.3 PostgreSQL7.4.9
SQL> create synonym emp_postgresql749_mac for "emp"@postgresql749_mac;

シノニムが作成されました。


SQL> select synonym_name from user_synonyms;

SYNONYM_NAME
----------------------------------------------------------
EMP_MYSQL4025_MAC
INNO_EMP_MYSQL4025_MAC
EMP_MYSQL4026_WIN
EMP_MYSQL4113A_MAC_SV
EMP_POSTGRESQL749_MAC

シノニムの確認も兼ねて各表に登録されているデータを確認しておく。

SQL> -- PowerMac G4 MacOSX Tiger 10.4.3 MySQL4.0.25
SQL> select * from emp_mysql4025_mac;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜

SQL> -- PowerMac G4 MacOSX Tiger 10.4.3 MySQL4.0.25
SQL> select * from inno_emp_mysql4025_mac;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜

SQL> -- AMD AthronMP Dual 2800+ Windows XP Professional
SQL> select * from emp_mysql4026_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよな〜−

SQL> -- PowerMac G5 Dual 2.7Ghz MacOSX Tiger 10.4.3 Server MySQL4.1.13a
SQL> select * from emp_mysql4113a_mac_sv;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよな〜−

SQL> -- PowerMac G4 MacOSX Tiger 10.4.3 PostgreSQL7.4.9
SQL> select * from emp_postgresql749_mac;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよね〜ー

SQL>

となっている。

今回の目的である Windows XP ProfessionalのOracle10g R1を踏み台にして、generic connectivityが組み込まれていない MacOSX版 Oracle10g R1からMySQLやPostgreSQLにアクセスするための準備はもう少しある。
それは、MacOSX Tiger 10.4.3 Serverに構築したOracle10g R1 10.1.0.3.0から Windows XP Professionalに構築したOracle10g R1 10.1.0.3.0にデータベースリンクを作成し、前述したシノニムにアクセスできるようにすることである。
以下は、MacOSX Tiger 10.4.3 ServerのOracle10g R1での作業である。まず tnsnames.oraを編集し、Windows XP Professionalに構築したOracle10g R1に接続できるようにする。接続文字列 CATFISHがそれである。

Last login: Sat Jan 14 16:36:47 on console
Welcome to Darwin!
G5Server:˜ discus$ su - oracle
Password:
G5Server:˜ oracle$ cat $ORACLE_HOME/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /Volumes/Discus/4oracle/oracle/u01/app/oracle/product/10.1.0/tigerx/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

XTIGER =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.19)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = xtiger)
)
)

CATFISH =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = catfish)
)
)

次に CATFISH にアクセスするためのデータベースリンクを作成する。
テスト用にユーザ(corydoras)を新たに作成してプライベートデータベースリンク(oracle10g_win)を作成した。

G5Server:˜ oracle$ 
G5Server:˜ oracle$
G5Server:˜ oracle$ sqlplus /nolog

SQL*Plus: Release 10.1.0.3.0 - Production on 土 1月 14 16:48:04 2006

Copyright (c) 1982, 2004, Oracle. All rights reserved.

> conn / as sysdba
アイドル・インスタンスに接続しました。
SYS> startup
ORACLEインスタンスが起動しました。

Total System Global Area 293601280 bytes
Fixed Size 778888 bytes
Variable Size 99360120 bytes
Database Buffers 192937984 bytes
Redo Buffers 524288 bytes
データベースがマウントされました。
データベースがオープンされました。
SYS>
SYS> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Prod
PL/SQL Release 10.1.0.3.0 - Production
CORE 10.1.0.3.0 Production
TNS for MacOS X Server: Version 10.1.0.3.0 - Production
NLSRTL Version 10.1.0.3.0 - Production

SYS>
SYS>
SYS>
SYS> create user corydoras identified by xxxxx
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

ユーザーが作成されました。

SYS> grant
2 connect,
3 create synonym,
4 create database link,
5 create table
6 to
7 corydoras;

権限付与が成功しました。

SYS> conn corydoras
パスワードを入力してください:
接続されました。
CORYDORAS>
CORYDORAS> create database link oracle10g_win
2 connect to discus identified by xxxxx using 'catfish';

データベース・リンクが作成されました。

作成したデータベースリンクでアクセスできるか確認を兼ねて、Windows XP Professional の Oracle10gにある discusユーザの user_db_linksビュー及び user_synonymsビューを問い合わせてみる。

CORYDORAS> select db_link from user_db_links@oracle10g_win;

DB_LINK
--------------------------------------------------------------------------------
MYSQL4025_MAC
MYSQL4026_WIN
MYSQL4113A_MAC_SV
POSTGRESQL749_MAC

CORYDORAS>
CORYDORAS> set linesize 132
CORYDORAS> col db_link for a40
CORYDORAS> select
2 synonym_name,
3 table_name,
4 db_link
5 from user_synonyms@oracle10g_win;

SYNONYM_NAME TABLE_NAME DB_LINK
------------------------------ ------------------------------ ----------------------------------------
EMP_MYSQL4025_MAC emp MYSQL4025_MAC
INNO_EMP_MYSQL4025_MAC inno_emp MYSQL4025_MAC
EMP_MYSQL4026_WIN emp MYSQL4026_WIN
EMP_MYSQL4113A_MAC_SV emp MYSQL4113A_MAC_SV
EMP_POSTGRESQL749_MAC emp POSTGRESQL749_MAC

CORYDORAS>

さて、いよいよ Windows XP Professional に構築した Oracle10g R1 の generic connectivityを経由して、generic connetivityのない MacOSX Server版 Oracle10g R1 から MySQLやPostgreSQLの表を問い合わせてみる! どうなるか。。。。

CORYDORAS> set timi on
CORYDORAS> col ename for a30
CORYDORAS>
CORYDORAS> select * from emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜

経過: 00:00:09.48
CORYDORAS> select * from inno_emp_mysql4025_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜

経過: 00:00:01.28
CORYDORAS> select * from emp_mysql4026_win@oracle10g_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよな〜−

経過: 00:00:00.70
CORYDORAS> select * from emp_mysql4113a_mac_sv@oracle10g_win;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよな〜−

経過: 00:00:01.11
CORYDORAS> select * from emp_postgresql749_mac@oracle10g_win;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよね〜ー

経過: 00:00:08.45
CORYDORAS>

やりました〜〜〜〜〜!。 ふ〜。ひとまず、狙い通りの結果がで、よかったよかった。これでこのネタで、もう少し引っ張れそうな気が。。しかし、Oracle10g R2のPreview Releaseがされたら、すぐにそちらで遊びだすかもしれない。噂通り早めにIntel版 Macもリリースされたことだし。

| | コメント (0) | トラックバック (0)

2006年1月13日 (金)

Mac De Oracle Heterogeneous! #10

前回まででWindowsに作成したOracle10g R1をMySQL及び、PostgreSQLをアクセスするHUBにするための構成は完了した。

リスナーの構成を反映させるためリスナーの再起動を行った。まずは再起動したリスナーの状態を確認。
各サービスのインスタンスがリストされているのが判るだろうか?

C:¥Documents and Settings¥Administrator>
C:¥Documents and Settings¥Administrator>lsnrctl status

LSNRCTL for 32-bit Windows: Version 10.1.0.2.0 - Production on 09-1月 -2006 15:02:20

Copyright (c) 1991, 2004, Oracle. All rights reserved.

(DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC)))に接続中
リスナーのステータス
------------------------
別名 LISTENER
バージョン TNSLSNR for 32-bit Windows: Version 10.1.0.2.0 - Production
開始日 09-1月 -2006 15:01:33
稼働時間 0 日 0 時間 0 分 51 秒
トレース・レベル off
セキュリティ ON: Local OS Authentication
SNMP OFF
パラメータ・ファイル E:¥oracle¥product¥10.1.0¥catfish¥network¥admin¥listener.ora
ログ・ファイル E:¥oracle¥product¥10.1.0¥catfish¥network¥log¥listener.log
リスニング・エンドポイントのサマリー...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=¥¥.¥pipe¥EXTPROCipc)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.2)(PORT=1521)))
サービスのサマリー...
サービス"PLSExtProc"には、1件のインスタンスがあります。
インスタンス"PLSExtProc"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
サービス"PostgreSQL749"には、1件のインスタンスがあります。
インスタンス"PostgreSQL749"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
サービス"mysql4025_MacOSX"には、1件のインスタンスがあります。
インスタンス"mysql4025_MacOSX"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
サービス"mysqldb4026_windows"には、1件のインスタンスがあります。
インスタンス"mysqldb4026_windows"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
サービス"mysqldb4113a_MacOSX_Server"には、1件のインスタンスがあります。
インスタンス"mysqldb4113a_MacOSX_Server"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
コマンドは正常に終了しました。

C:¥Documents and Settings¥Administrator>




データベースリンクを作成してリモートデータベースにアクセスするのだが、今回はプライベートデータベースリンクを作成することにし、新たにユーザを作成した。
SQL> conn / as sysdba
SQL> create user discus identified by xxxxxxxx
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

ユーザーが作成されました。

SQL> grant
2 connect,
3 create synonym,
4 create database link,
5 create table
6 to
7 discus;

権限付与が成功しました。




データベースリンクを作成する前に確認しておくことが1点ある。global_names=falseであることを確認しておくことである。
SQL> conn / as sysdba
SQL> show parameter global_names

NAME TYPE VALUE
------------ -------------- ---------------
global_names boolean FALSE
SQL>

もし、trueならば、falseに変更しておく。動的パラメータなので
SQL> alter system set global_names = false scope=both;

システムが変更されました。

SQL>
で変更可能である。
尚、これはspfile の利用を前提に記述している。pfileを利用している場合には、init_<SID>.oraファイルを変更し、再起動が必要である。(ただし、scope=memoryとしてalter system文を発行し、後日再起動しても同じである。)

さていよいよ、プライベートデータベースリンクを作成し、MySQL及び、PostgreSQLにアクセスしてみる。
これがうまくいけば、Windowsに作成したOracle10g R1がMySQL及び、PostgreSQLのデータを纏めるHUBとしての機能を持つ事になる。MySQLやPostgreSQLにアクセスするデータベースリンクの作成で大切な点は、ユーザ名及び、パスワードを "" で囲むことである。ちなみに、MySQLやPostgreSQLにあるオブジェクトも""で囲む必要がる。ようするにユーザ名やパスワードは大文字小文字を区別させる必要があり、オブジェクト名は小文字で参照させるということを意味している。

Note:
"で囲まれた部分を 引用識別子(quoted identifier)と呼ぶ。逆に囲まれていない場合は非引用識別子(nonquoted identifier)と呼ぶ。

SQL> conn discus
パスワードを入力してください: ************
接続されました。
SQL>
SQL>
SQL>
SQL> create database link mysql4026_win
2 connect to "catfish" identified by "xxxxxxx" using 'MYSQL4026_WIN';

データベース・リンクが作成されました。

SQL> select * from "emp"@mysql4026_win;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよな〜ー

SQL>
SQL> create database link mysql4113a_mac_sv
2 connect to "discus" identified by "xxxxxxxxx" using 'MYSQL4113A_MAC_SV';

データベース・リンクが作成されました。

SQL> select * from "emp"@mysql4113a_mac_sv;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよな〜ー

SQL>
SQL> create database link mysql4025_mac
2 connect to "jobs" identified by "xxxxxx" using 'MYSQL4025_MAC';

データベース・リンクが作成されました。

SQL> select * from "emp"@mysql4025_mac;

empno ename
---------- ------------------------------
1 おらおら
2 ほげ
3 化けないよねー〜

SQL>
SQL> create database link postgresql749_mac
2 connect to "scott" identified by "xxxxxxx" using 'POSTGRESQL749_MAC';

データベース・リンクが作成されました。

SQL> select * from "emp"@postgresql749_mac;

empno ename
---------- ------------------------------
1 ほげほげ
2 ほげ
3 化けないよね〜ー

SQL>

次回はMacOSX Tiger 10.4.3に作成したOracle10g R1から、Windows XP Professionalに作成したOracle10g R1にデータベースリンクを経由してアクセスしてみる。
WindowsのOracle10g R1を踏み台とし、MacOSX Tiger Server 10.4.3のOracle10gから間接的にMySQL及び、PostgreSQLにアクセスできることを確認する。

| | コメント (0) | トラックバック (0)

2006年1月12日 (木)

Mac De Oracle Heterogeneous! #9

前回のつづきです。
さて、Generic connectivityエージェントの構成も終了し、残すところあと僅か。Oracle Net Serviceの構成を行う。

Oracle Net Service構成ファイルは、%ORACLE_HOME%¥network¥admin以下にある。Oracleに慣れた方なら見慣れた構成ファイル。listener.ora及び、tnsnames.oraファイルである。

listener.oraファイルの内容は以下の通り。
大事な点は SID_NAMEパラメータに データソース名を設定するということと、PROGRAMパラメータには、hsodbc を設定する点である。

# listener.ora Network Configuration File: E:¥oracle¥product¥10.1.0¥catfish¥network¥admin¥listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = E:¥oracle¥product¥10.1.0¥catfish)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = mysql4025_MacOSX)
(PROGRAM = hsodbc)
(ORACLE_HOME = E:¥oracle¥product¥10.1.0¥catfish)
)
(SID_DESC =
(SID_NAME = mysqldb4026_windows)
(PROGRAM = hsodbc)
(ORACLE_HOME = E:¥oracle¥product¥10.1.0¥catfish)
)
(SID_DESC =
(SID_NAME = mysqldb4113a_MacOSX_Server)
(PROGRAM = hsodbc)
(ORACLE_HOME = E:¥oracle¥product¥10.1.0¥catfish)
)
(SID_DESC =
(SID_NAME = PostgreSQL749)
(PROGRAM = hsodbc)
(ORACLE_HOME = E:¥oracle¥product¥10.1.0¥catfish)
)
)

LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
)
)
)




tnsnames.oraファイルの内容は以下の通り。
接続文字列は判りやすい名称にすればよいが、SIDパラメータにデータソース名を指定する点がポイント。HS=OK というお約束の設定も忘れずに。

# tnsnames.ora Network Configuration File: E:¥oracle¥product¥10.1.0¥catfish¥network¥admin¥tnsnames.ora
# Generated by Oracle configuration tools.

CATFISH =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = catfish)
)
)

MYSQL4025_MAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
(CONNECT_DATA =
(SID = mysql4025_MacOSX)
)
(HS=OK)
)

MYSQL4026_WIN =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
(CONNECT_DATA =
(SID = mysqldb4026_windows)
)
(HS=OK)
)

MYSQL4113A_MAC_SV =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
(CONNECT_DATA =
(SID = mysqldb4113a_MacOSX_Server)
)
(HS=OK)
)

POSTGRESQL749_MAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
(CONNECT_DATA =
(SID = PostgreSQL749)
)
(HS=OK)
)

EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
)

ここまでで generic connectivityエージェント構成ファイル及び、Oracle Net Serviceの構成が完了した。
さて、次回は、データベースリンクを作成し、MySQLやPostgreSQLにアクセスする。

| | コメント (0) | トラックバック (0)

2006年1月11日 (水)

Mac De Oracle Heterogeneous! #8

前回のつづきです。
Windows XP Professionalに作成したOracle10g R1をMySQL及び、PostgreSQLのデータを統合するためのHUBとして機能させるためOracle Generic Connectivityエージェントの構成を行う。

Generic Connectivityエージェントの構成ファイルは、%ORACLE_HOME%¥hs¥admin以下に作成する。尚、同ディレクトリにhsodbc.oraという構成ファイルのサンプルがあるので、そのファイルをコピーすれば簡単に作成することができる。また、構成ファイルはODBCデータソース毎に作成する必要がある。
今回は以下のようなに4ファイルを作成した。(尚、unix系では、$ORACLE_HOME/hs/admin以下に構成ファイルを作成する必要がある)

hs


構成ファイルのファイル名は以下の形式にする必要がある。(DSNはデータソース名である)


init<DSN>.ora

今回作成したシステムデータソース名は

mysql4025_MacOSX mysqldb4026_windows mysqldb4113a_MacOSX_Server PostgreSQL749

であるから、構成ファイル名は以下のようになる。

initmysql4025_MacOSX.ora initmysqldb4026_windows.ora initmysqldb4113a_MacOSX_Server.ora initPostgreSQL749.ora

上からそれぞれ、

PowerBook G4 1Ghz 17inch MacOSX Tiger 10.4.3 の MySQL4.0.25 Standard
AMD AthronMP Dual 2800+ Windows XP Professional の MySQL4.0.26-nt Standard
PowerMac G5 Dual 2.7Ghz MacOSX Tiger 10.4.3 Server の MySQL4.1.13a Standard
PowerBook G4 1Ghz 17inch MacOSX Tiger 10.4.3 の PostgreSQL 7.4.9
向けGeneric Connectivity構成ファイルである。

今回の構成ファイルは以下のような内容になっている。(MySQL向け構成ファイルの内容はデータソース名以外同じ)
尚、構成ファイルの各パラメータについては、マニュアル Oracle10g Heterogeneous Connectivity 管理者ガイド参照のこと。

initmysql4025_MacOSX.oraの内容。


# This is a sample agent init file that contains the HS parameters that are
# needed for an ODBC Agent.

#
# HS init parameters
#
HS_FDS_CONNECT_INFO = mysql4025_MacOSX
HS_FDS_TRACE_LEVEL = off
HS_FDS_SHAREABLE_NAME = C:¥WINNT¥system32¥myodbc3.dll

#
# Environment variables required for the non-Oracle system
#
#set <envvar>=<value>




initPostgreSQL749.oraの内容。
PostgreSQL Client 向けにAUTOCOMMITはoffに設定してある。


# This is a sample agent init file that contains the HS parameters that are
# needed for an ODBC Agent.

#
# HS init parameters
#
HS_FDS_CONNECT_INFO = PostgreSQL749
HS_FDS_TRACE_LEVEL = off
HS_FDS_SHAREABLE_NAME = C:¥WINNT¥system32¥psqlodbc.dll

#
# Environment variables required for the non-Oracle system
#
#set <envvar>=<value>
set AUTOCOMMIT=off

これで generic connectivityエージェント構成ファイルができた。続いて Oracle Net Service の構成を行う。

| | コメント (0) | トラックバック (0)

2006年1月10日 (火)

Mac De Oracle Heterogeneous! #7

前回からのつづきです。
MacOSX Tiger Server 10.4.3 : PowerMac G5 Dual 2.7GhzのMySQL4.1.13aと

MacOSX Tiger 10.4.3 : PowerBook G4 1Ghz 17inchのPostgreSQL7.4.9のデータソース設定と接続テストをFlashで。

MacOSX Tiger Server 10.4.3 PowerMac G5 Dual 2.7GhzのMySQL4.1.13a向けデータソース構成と接続テスト。











MacOSX Tiger 10.4.3 PowerBook G4 1Ghz 17inchのPostgreSQL7.4.9向けデータソース構成と接続テスト。psqlODBCには、MyODBCのような接続テスト機能がないのでMS Accessによる接続テストを行った。








次回は、Generic Connectivityの構成を行う。

| | コメント (0) | トラックバック (0)

2006年1月 9日 (月)

Mac De Oracle Heterogeneous! #6

前回からのつづきです。
MySQL4.0.25 (MacOSX Tiger : PowerBook G4 1Ghz)及び、MySQL4.0.26-nt (Windows XP Professional)のODBCデータソース構成及び接続テストをFlashで。

MacOSX Tiger : PowerBook G4 1Ghz 17inchのMySQL4.0.25向けシステムデータソース構成と接続テスト。









Windows XP Professional (localhost) にあるMySQL4.0.26-nt向けシステムデータソース構成と接続テスト。







次回、MySQL4.1.13aとPostgreSQL7.4.9のデータソース構成につづく。

| | コメント (0) | トラックバック (0)

2006年1月 8日 (日)

Mac De Oracle Heterogeneous! #5

前回のつづき。
Windows XP Professional(MySQL及び、PostgreSQLにGeneric Connectivityを経由してアクセスするためにOracle10g R1がインストールしてある)に各データベースのODBCドライバをインストールし、システムデータソースを作成した。

MacOSX 10.4.3 Tiger に構築したPostgreSQL 7.4.9へWindowsからアクセスするためのODBCドライバは、以下URLからダウンロードした。(psqlODBC3.0 Ver.07-03-0208)
http://cre-ent.skcapi.co.jp/〜saito/pgadmin/lib/PGODBC30_07030208.exe

ダウンロードページは以下 http://cre-ent.skcapi.co.jp/〜saito/pgadmin/download

MacOSX 10.4.3 Tiger Serverに構築したMySQL 4.1.13a、MacOSX 10.4.3 Tigerに構築したMySQL 4.0.25、及び、Windows XP Professionalに構築したMySQL 4.0.26-nt の各MySQLへWindowsからアクセスするためのODBCドライバは、以下URLからダウンロードした。(MySQL Connector/ODBC ver 3.51.12)
http://dev.mysql.com/get/Downloads/MyODBC3/mysql-connector-odbc-3.51.12-win32.zip/from/pick

尚、MySQLも PostgreSQLもデフォルトではリモート接続が遮断されているので、MySQLならgrant文でユーザを作成する際にアクセスを許可するホスト又はIP addressを指定しPostgreSQLであれば、/usr/local/pgsql/data/pg_hba.confでリモートアクセスを許可するユーザとip addressを設定する必要がる。
MacOSX Serverに搭載されたMySQL4.1.13aでは、grant文の他に MySQL Adminでリモート接続を許可する必要がある。MySQLのgrant文及び、MacOSX ServerのMySQL Adminでのリモート接続許可については以前の記事を参照してもらいたい。

PostgreSQL7.4.9のpg_hba.confの内容。
(今回は、192.168.1.2からのリモート接続を許可するよう設定した。ドライバのリリースやプラットフォームの違いにより、認証用メドッドが利用できないものもあるのでその都度接続できるか確認したほうがよいだろう。ちなみに、Redhatではmd5もpasswordもエラーとなったので trust に設定したこともあった。Linux上でのunixODBC及び、各ODBCドライバを利用したGeneric Connectivityについてはいずれ公開する予定である。)


# PostgreSQL Client Authentication Configuration File
# ===================================================
#
# Refer to the PostgreSQL Administrator's Guide, chapter "Client
# Authentication" for a complete description. A short synopsis
# follows.
#
# This file controls: which hosts are allowed to connect, how clients
# are authenticated, which PostgreSQL user names they can use, which
# databases they can access. Records take one of seven forms:
#
# local DATABASE USER METHOD [OPTION]
# host DATABASE USER IP-ADDRESS IP-MASK METHOD [OPTION]
# hostssl DATABASE USER IP-ADDRESS IP-MASK METHOD [OPTION]
# hostnossl DATABASE USER IP-ADDRESS IP-MASK METHOD [OPTION]
# host DATABASE USER IP-ADDRESS/CIDR-MASK METHOD [OPTION]
# hostssl DATABASE USER IP-ADDRESS/CIDR-MASK METHOD [OPTION]
# hostnossl DATABASE USER IP-ADDRESS/CIDR-MASK METHOD [OPTION]
#
# (The uppercase quantities should be replaced by actual values.)
# The first field is the connection type: "local" is a Unix-domain socket,
# "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl" is an
# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket.
# DATABASE can be "all", "sameuser", "samegroup", a database name (or
# a comma-separated list thereof), or a file name prefixed with "@".
# USER can be "all", an actual user name or a group name prefixed with
# "+" or a list containing either. IP-ADDRESS and IP-MASK specify the
# set of hosts the record matches. CIDR-MASK is an integer between 0
# and 32 (IPv6) or 128(IPv6) inclusive, that specifies the number of
# significant bits in the mask, so an IPv4 CIDR-MASK of 8 is equivalent
# to an IP-MASK of 255.0.0.0, and an IPv6 CIDR-MASK of 64 is equivalent
# to an IP-MASK of ffff:ffff:ffff:ffff::. METHOD can be "trust", "reject",
# "md5", "crypt", "password", "krb4", "krb5", "ident", or "pam". Note
# that "password" uses clear-text passwords; "md5" is preferred for
# encrypted passwords. OPTION is the ident map or the name of the PAM
# service.
#
# This file is read on server startup and when the postmaster receives
# a SIGHUP signal. If you edit the file on a running system, you have
# to SIGHUP the postmaster for the changes to take effect, or use
# "pg_ctl reload".

# Put your actual configuration here
# ----------------------------------
#
# CAUTION: The default configuration allows any local user to connect
# using any PostgreSQL user name, including the superuser, over either
# Unix-domain sockets or TCP/IP. If you are on a multiple-user
# machine, the default configuration is probably too liberal for you.
# Change it to use something other than "trust" authentication.
#
# If you want to allow non-local connections, you need to add more
# "host" records. Also, remember TCP/IP connections are only enabled
# if you enable "tcpip_socket" in postgresql.conf.

# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD

local all postgres trust
local all all md5
# IPv4-style local connections:
host all postgres 127.0.0.1 255.255.255.255 trust
host all all 127.0.0.1 255.255.255.255 md5
host all all 192.168.1.2 255.255.255.255 password
# IPv6-style local connections:
host all postgres ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff trust

Windows XP Professionalに前述のMyODBCドライバ及び、PostgreSQLドライバをインストールした後状態。


odbc1

odbc2

odbc3


作成したデータソース(システムDSN)は以下の通り。


odbc4

各データソースの設定内容のはFlashのサイズが大きいのでそれぞれ別記事としてアップする予定なので本日はここまで。

| | コメント (0) | トラックバック (0)

2006年1月 4日 (水)

Mac De Oracle Heterogeneous! #4

あけましておめでとうございます。
新年第一弾は、Oracle Heterogeneous Service - Generic Connectivityの続きから。

Windows XP ProへのMySQL 4.0.26-ntのインストールは省略する。googleなどで検索すれば多数のあるのでそれらで確認してほしい。また、MacOSX Tiger Serverには、MySQL4.1がインストール済みなのでこれまた省略。ということでメモ程度に表の内容や構成ファイルの設定内容などを記述しておく。

まずは、Windows XP ProfessionalにインストールしたMySQL 4.0.26-ntの構成ファイルと表に関することから。

LinuxやMacOSXでは、my.cnfにデフォルトキャラクタセットを設定していたが、Windowsでは、my.iniを利用して作成するデータベース(mysqldb)のデフォルトキャラクタセットを設定した。(ちなみに、my.cnfを利用することもできる。)

my.iniの場所と内容は以下の通り。

C:¥WINNT¥my.ini

#This File was made using the WinMySQLAdmin 1.4 Tool
#2005/11/25 22:29:45

#Uncomment or Add only the keys that you know how works.
#Read the MySQL Manual for instructions

[mysqld]
default-character-set=sjis
basedir=F:/msql
bind-address=localhost
datadir=F:/msql/data
#language=F:¥msql¥share¥japanese
#slow query log#=
#tmpdir#=
port=3306
#set-variable=key_buffer=16M

[WinMySQLadmin]
Server=F:/msql/bin/mysqld.exe
user=root
password=XXXXXXX

[mysqldb]
default-character-set=sjis


以下、MacOSXのMySQLの場合と同じ手順で作成したデータベースにemp表(エンジンはInnoDB)を作成しデータを登録しておく。

C:¥Documents and Settings¥Administrator>mysql -u catfish -p mysqldb
Enter password: *******
Welcome to the MySQL monitor. Commands end with ; or ¥g.
Your MySQL connection id is 5 to server version: 4.0.26-nt
Type 'help;' or '¥h' for help. Type '¥c' to clear the buffer.
mysql> select * from emp;
+-------+------------------+
| empno | ename |
+-------+------------------+
| 1 | おらおら |
| 2 | ほげ   |
| 3 | 化けないよね〜ー |
+-------+------------------+
3 rows in set (0.01 sec)

mysql>


お次は、 MacOSX 10.4.3 Tiger Serverの MySQL4.1.13a に作成したデータベースにemp表(エンジンはInnoDB)を作成しデータを登録しておく。作成したデータベース名は mysqldb41。)
mysql> use mysqldb41
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql>
mysql> show create database mysqldb41;
+-----------+--------------------------------------------------------------------+
| Database | Create Database |
+-----------+--------------------------------------------------------------------+
| mysqldb41 | CREATE DATABASE `mysqldb41` /*!40100 DEFAULT CHARACTER SET sjis */ |
+-----------+--------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table emp¥G
*************************** 1. row ***************************
Table: emp
CREATE TABLE `emp` (
`empno` int(11) NOT NULL default '0',
`ename` varchar(40) default NULL,
PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=sjis
1 row in set (0.00 sec)

mysql> select * from emp;
+-------+------------------+
| empno | ename |
+-------+------------------+
| 1 | おらおら |
| 2 | ほげ   |
| 3 | 化けないよね〜ー |
+-------+------------------+
3 rows in set (0.01 sec)

mysql>

尚、MacOSX 10.4.3 Tiger Serverでは、MySQLの管理ツールとしてMySQLマネージャがインストールされていて起動、停止やリモート接続の可否設定も行える。


gencon_blog4_mysql_admin_icon

gencon_blog4_mysql_admin


ということで以下のMySQL、PostgreSQLデータベースの作成が完了した。これでOracle Generric Connectivityを行うためのリモートデータベースは準備できた。残すはODBC構成及び接続確認とOracle Generic Connectivityの構成、データベースリンクの作成、動作確認である。

Platform Database DB Name Character set
PowerBook G4 1Ghz MacOSX 10.4 Tiger MySQL4.0.25 mysqldb sjis
AMD Athron MP Dual 2800+ Windows XP Professional MySQL4.0.26-nt mysqldb sjis
PowerMac G5 Dual 2.7Ghz MacOSX 10.4 Tiger Server MySQL4.1.13a mysqldb41 sjis
PowerBook G4 1Ghz MacOSX 10.4 Tiger PostgreSQL7.4.9 postgresql749 EUC_JP

次回は、Windows XP Professional で ODBCデータソースの設定及び、接続確認を行う。

| | コメント (0) | トラックバック (0)

2005年12月31日 (土)

Mac De Oracle Heterogeneous! #3

前回MySQLをインストールした PowerBook G4 1Ghz 17inch (MacOSX 10.4.3 Tiger)にPostgreSQL 7.4.9 もインストールしデータベースを構築する。

http://wwwmaster.postgresql.org/download/mirrors-ftp?file=source%2Fv7.4.9%2Fpostgresql-7.4.9.tar.gzからpostgresql-7.4.9.tar.gzを入手し、適当なフォルダ(/tmpなどで解凍する)。
この例では、/Volumes/WorkVol/temp以下で解凍した。

注意)
今回もPostgreSQLのインストールやデータベース作成は簡単に(それなりに端折って)記述しているのであしからず。
また、MacOSXにPostgreSQLをインストールする記事を書いているBlogも多数あるのでそれらも参考にしてほしい。
(Mac De Oracleでは、MySQLやPostgreSQLの構築方法がメインではなく、Oracle Generic Connectivityの動きを確認する事が目的なので。)

Terminalを起動しPostgreSQL 7.4.9を解凍して出来たディレクトリに移動する。作業はrootで行うので、sudo shでrootになっておく。


Last login: Fri Nov 25 15:56:39 on ttyp1
Welcome to Darwin!
pb17:˜ discus$ sudo sh
Password:
sh-2.05b#
sh-2.05b# cd /Volumes/WorkVol/temp/postgresql-7.4.9
sh-2.05b# ls -l
total 1752
-rw-r--r-- 1 root wheel 1192 Nov 26 08:43 COPYRIGHT
-rw-r--r-- 1 root wheel 3460 Nov 26 08:43 GNUmakefile.in
-rw-r--r-- 1 root wheel 269744 Nov 26 08:43 HISTORY
-rw-r--r-- 1 root wheel 40847 Nov 26 08:43 INSTALL
-rw-r--r-- 1 root wheel 1432 Nov 26 08:43 Makefile
-rw-r--r-- 1 root wheel 1376 Nov 26 08:43 README
-rw-r--r-- 1 root wheel 442 Nov 26 08:43 aclocal.m4
drwxr-xr-x 19 root wheel 646 Nov 26 08:42 config
-rwxr-xr-x 1 root wheel 523803 Nov 26 08:43 configure
-rw-r--r-- 1 root wheel 39896 Nov 26 08:43 configure.in
drwxr-xr-x 53 root wheel 1802 Nov 26 08:42 contrib
drwxr-xr-x 30 root wheel 1020 Nov 26 08:42 doc
drwxr-xr-x 22 root wheel 748 Nov 26 08:43 src


日本語EUCが利用できるようにconfigureする。


sh-2.05b# ./configure --enable-multibyte=EUC_JP
checking build system type... powerpc-apple-darwin8.3.0
checking host system type... powerpc-apple-darwin8.3.0
checking which template to use... darwin
checking whether to build with 64-bit integer date/time support... no
checking whether NLS is wanted... no
checking for default port number... 5432
checking for gcc... gcc

中略

configure: using CPPFLAGS=
configure: using LDFLAGS=
checking for gawk... no
checking for mawk... no
checking for sgmlspl... no
configure: creating ./config.status
config.status: creating GNUmakefile
config.status: creating src/Makefile.global
config.status: creating src/include/pg_config.h
config.status: linking ./src/backend/port/tas/dummy.s to src/backend/port/tas.s
config.status: linking ./src/backend/port/dynloader/darwin.c to src/backend/port/dynloader.c
config.status: linking ./src/backend/port/posix_sema.c to src/backend/port/pg_sema.c
config.status: linking ./src/backend/port/sysv_shmem.c to src/backend/port/pg_shmem.c
config.status: linking ./src/backend/port/dynloader/darwin.h to src/include/dynloader.h
config.status: linking ./src/include/port/darwin.h to src/include/pg_config_os.h
config.status: linking ./src/makefiles/Makefile.darwin to src/Makefile.port
sh-2.05b#

エラーもなくconfigureできたのでコンパイルする。


sh-2.05b# make
make -C doc all
gzip -d -c man.tar.gz | /usr/bin/tar xf -
for file in man1/*.1; do ¥
mv $file $file.bak && ¥
sed -e 's/¥¥fR(l)/¥¥fR(7)/' $file.bak >$file && ¥
rm -f $file.bak || exit; ¥
done
/bin/sh ../config/mkinstalldirs man7
mkdir man7
for file in manl/*.l; do ¥
sed -e '/^¥.TH/s/"l"/"7"/' ¥
-e 's/¥¥fR(l)/¥¥fR(7)/' ¥
$file >man7/`basename $file | sed 's/.l$/.7/'` || exit; ¥
done
make -C src all
make -C port all
gcc -no-cpp-precomp -O2 -fno-strict-aliasing -Wall -Wmissing-prototypes -Wmissing-declarations -I../../src/include -c -o path.o path.c
gcc -no-cpp-precomp -O2 -fno-strict-aliasing -Wall -Wmissing-prototypes -Wmissing-declarations -I../../src/include -c -o sprompt.o sprompt.c
gcc -no-cpp-precomp -O2 -fno-strict-aliasing -Wall -Wmissing-prototypes -Wmissing-declarations -I../../src/include -c thread.c
ar crs libpgport.a path.o sprompt.o thread.o
make -C backend all

中略

rm -f libplpgsql.so
ln -s libplpgsql.so.1.0 libplpgsql.so
All of PostgreSQL successfully made. Ready to install.
sh-2.05b#


コンパイルエラーもないようなので、インストールする。


sh-2.05b# make install
make -C include install
mkdir /usr/local/pgsql/include
mkdir /usr/local/pgsql/include/libpq
mkdir /usr/local/pgsql/include/internal
mkdir /usr/local/pgsql/include/internal/libpq
mkdir /usr/local/pgsql/include/internal/lib

中略

make[4]: Nothing to be done for `all'.
/bin/sh ../../../config/install-sh -c pg_encoding /usr/local/pgsql/bin/pg_encoding
make -C pl install
make -C src install
/bin/sh ../../../../config/install-sh -c -m 755 libplpgsql.so.1.0 /usr/local/pgsql/lib/plpgsql.so
PostgreSQL installation complete.
sh-2.05b#


次に キャタクタセット EUC_JP でデータベースクラスタを作成する。
データベースクラスタを作成しないと、インスタンスが起動できないので注意する。
(尚、MySQL、PostgreSQLは、Oracleとは異なり1インスタンスで複数データベースを管理することができる)

データベースクラスタを作成するには initdb コマンドを利用する。
尚、データベースクラスタは、/usr/local/pgsql/data以下に作成することにする。

インストールが終了すると postgres というユーザが作成されているのでそのユーザで作業する。


pb17:˜ discus$ su - postgres
Password:
pb17:˜ postgres$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -E EUC_JP
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale C.

fixing permissions on existing directory /usr/local/pgsql/data... ok
creating directory /usr/local/pgsql/data/base... ok
creating directory /usr/local/pgsql/data/global... ok
creating directory /usr/local/pgsql/data/pg_xlog... ok
creating directory /usr/local/pgsql/data/pg_clog... ok
selecting default max_connections... 50
selecting default shared_buffers... 300
creating configuration files... ok
creating template1 database in /usr/local/pgsql/data/base/1... ok
initializing pg_shadow... ok
enabling unlimited row size for system tables... ok
initializing pg_depend... ok
creating system views... ok
loading pg_description... ok
creating conversions... ok
setting privileges on built-in objects... ok
creating information schema... ok
vacuuming database template1... ok
copying template1 to template0... ok

Success. You can now start the database server using:

/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data
or
/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start

pb17:˜ postgres$

データベースクラスタができたのでPostgreSQLのインスタンスを起動する。


pb17:˜ postgres$ /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start
postmaster successfully started

問題なく起動したようだ。


Oracleでいうところの、SQL*Plusに相当するpsqlを起動する前に環境変数は以下のように設定しておく。
クライアントのキャラクタセットはSJISにする。


pb17:˜ postgres$ cat .bash_profile
export PATH=$PATH:/usr/local/pgsql/bin
export PGDATA=/usr/local/pgsql/data

# client encoding
export PGCLIENTENCODING=SJIS

pb17:˜ postgres$
pb17:˜ postgres$ . .bash_profile


次に postgresql749 というデータベースを作成する。
作成済みデータベースは、psql -l で確認できる。


pb17:˜ postgres$ createdb postgresql749
CREATE DATABASE
pb17:˜ postgres$

pb17:˜ postgres$ psql -l
List of databases
Name | Owner | Encoding
---------------+----------+----------
postgresql749 | postgres | EUC_JP
template0 | postgres | EUC_JP
template1 | postgres | EUC_JP
(3 rows)


psql で postgresql749 データベースに接続する。


pb17:˜ postgres$ psql postgresql749
Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=#

※ scott ユーザを作成する。


postgresql749=# create user scott with password 'xxxxxxx';
CREATE USER
postgresql749=# ¥du
List of database users
User name | User ID | Attributes
-----------+---------+----------------------------
postgres | 1 | superuser, create database
scott | 100 |
(2 rows)

postgresql749=#
postgresql749=# select * from pg_user;
usename | usesysid | usecreatedb | usesuper | usecatupd | passwd | valuntil | useconfig
----------+----------+-------------+----------+-----------+----------+----------+-----------
postgres | 1 | t | t | t | ******** | |
scott | 100 | f | f | f | ******** | |
(2 rows)

postgresql749=#

ユーザと同じ名称のスキーマを作成し所有者をscottにする。このようにすることでscottユーザがログインすると優先スキーマがscottスキーマになり、Oracleに近い感覚で利用できることになります。
(Oracleに慣れてしまっていると、つい、ユーザとスキーマが同じようなイメージで固まってしまいますが、実際には違うオブジェクトだということ思い出しますね。たまにはOracle以外のデータベースで遊ぶのもいいかもしれません。)

postgresql749=# create schema scott authorization scott; CREATE SCHEMA postgresql749=#
 postgresql749=# ¥dn
List of schemas
Name | Owner
--------------------+----------
information_schema | postgres
pg_catalog | postgres
pg_temp_1 | postgres
pg_toast | postgres
public | postgres
scott | scott
(6 rows)
pb17:˜ postgres$ psql -U scott postgresql749 Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=> select current_schema();
current_schema
----------------
scott
(1 row)


さて、psqlというクライアントでは、AUTOCOMIT ON がデフォルトになっている。これでは都合が悪いので ホームディレクトリに .pgsqlrc を作成し、¥set AUTOCOMMIT off と記述しておく。


postgresql749=#
pb17:˜ postgres$ cat .psqlrc
¥set AUTOCOMMIT off
pb17:˜ postgres$

さて、最後に表を作成する。MySQLと同じくemp表を作成してデータの登録、参照までを行う。


pb17:˜ postgres$ psql -U scott postgresql749
Welcome to psql 7.4.9, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
¥h for help with SQL commands
¥? for help on internal slash commands
¥g or terminate with semicolon to execute query
¥q to quit

postgresql749=>
postgresql749=> create table emp
postgresql749-> (
postgresql749(> empno numeric(10,0) primary key,
postgresql749(> ename varchar(40)
postgresql749(> );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "emp_pkey" for table "emp"
CREATE TABLE

postgresql749=> ¥d emp
Table "public.emp"
Column | Type | Modifiers
--------+-----------------------+-----------
empno | numeric(10,0) | not null
ename | character varying(40) |
Indexes:
"emp_pkey" primary key, btree (empno)

postgresql749=>
postgresql749=> ¥dt
            List of relations
Schema | Name | Type | Owner
--------+--------+-------+-------
scott | emp | table | scott
(1 row)

postgresql749=> insert into emp values(1,'¥202¥331¥202¥260¥202¥331¥202¥260');
INSERT 25420 1
postgresql749=> insert into emp values(2,'¥202¥331¥202¥260');
INSERT 25421 1
postgresql749=> insert into emp values(3,'¥211¥273¥202¥257¥202¥310¥202¥242¥202¥346¥202¥313¥201`¥201[');
INSERT 25422 1
postgresql749=> commit;
COMMIT


postgresql749=> select * from emp;
empno | ename
-------+------------------
1 | ほげほげ
2 | ほげ
3 | 化けないよね〜ー
(3 rows)

postgresql749=>

ここまでで、PowerBook G4 1Ghz 17inch (MacOSX 10.4.3 Tiger)に MySQL 4.0.25 mysqldb (SJIS) と PostgreSQL 7.4.9 postgresql749 (EUC_JP) という2つのデータベースができた。

次回は、MacOSX 10.4.3 Tiger Server に MySQL4.1.13a、そしてWindows XP Proに MySQL4.0.26-ntのデータベースを作成しODBCドライバの構成まで書く予定である。(尚、Windows XP Proには、Oracle10g R1 EEがインストール済みでデータベースも作成済みである)

| | コメント (0) | トラックバック (0)

2005年12月30日 (金)

Mac De Oracle Heterogeneous! #2

さて、Generic Connectivityを試す環境作りです。
まず最初は、MacOSX 10.4.3 Tiger (PowerBook G4 1Ghz 17inchに、MySQL 4.0.25 Standardをインストールしてデータベースを構築、表の作成、最後にデータ登録まで行う。

MacOSXでのMySQL構築を書いているBlogも多数存在するので、Mac De Oracleではその辺りは簡単に(端折ってとも言う)書く事にするので悪しからず。

MacOSX 10.4 Serverならば、MySQL4.1も付属していますが、Server版ではないのでダウンロードしてインストールする。
これをダウンロードして利用した。
インストーラをダブルクリックするだけでインストールできるので簡単です。
後は、インストーラに付属しているコントロールパネルをライブラリ/PreferencePanes/以下にコピーすればシステム環境設定から起動停止できるようになります。


gencon_blog2_img1


gencon_blog2_img2



MySQLは、/usr/local/mysql にインストールされるので以下のような感じで環境変数を設定しておく


pb17:〜 discus$ cat .bash_profile

export MYSQL_HOME=/usr/local/mysql
export PATH=$PATH:$MYSQL_HOME/bin

pb17:˜ discus$

以下のようにコマンド起動しても構わないが、システム環境設定にインストールしたコントロールパネルから起動したほうが楽ですね。自動起動の設定もこれでできます。


$ sudo mysqld_safe --user=mysql &

または、以下のコントロールパネルで起動。(私はGUIで起動してます。楽なので)


gencon_blog2_img3


gencon_blog2_img4



文字化けが気になるのでGeneric Connectivityで接続する環境はなるべく同一キャラクタセットにしておきたいがうまい具合に統一されていない場合も多々ある。今回はMySQLのデータベースはすべてsjisを想定しているので作成するデータベースのデフォルトキャラクタセットはsjisに設定しておく。 設定は、/etc/my.cnf で行う。

今回作成する mysqldb データベースのデフォルトキャラクタセットを以下のように設定しておく。


pb17:˜ discus$ cat /etc/my.cnf
[mysqld]
default-character-set = sjis
[mysqldump]
default-character-set = sjis
[mysql]
default-character-set = sjis
[mysqldb]
default-character-set = sjis
pb17:˜ discus$

念のため起動しているか確認。


Last login: Tue Nov 15 21:59:49 on console
Welcome to Darwin!
pb17:˜ discus$ sudo mysqladmin -u root -p ping
Enter password:
mysqld is alive

rootユーザで接続し、jobs というユーザを作成。localhostとWindows XP Proからだけ接続できれば十分なのだが、今回は全ホストからの接続を受け付けるようにした。
(セキュリティ上はNGなのだが。。)
ちなみに、ちゃんとやるのであれば、localhostとWindows XP Proからの接続を受け付けるように grant文を2回実行する必要がある。


pb17:˜ discus$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or ¥g.
Your MySQL connection id is 239 to server version: 4.0.25-standard

Type 'help;' or '¥h' for help. Type '¥c' to clear the buffer.

mysql> use mysql
Database changed
mysql> grant all on mysqldb.* to 'jobs'@'%' identified by 'xxxxxxxxxx';
Query OK, 0 rows affected (0.04 sec)

mysql> exit
Bye

mysqldb というデータベースを作成する。


pb17:˜ discus$ sudo sh
Password:
sh-2.05b# mysqladmin -u root -p create mysqldb
Enter password:
sh-2.05b#
sh-2.05b#
sh-2.05b# exit
exit


作成した jobs ユーザで mysqldbに接続し、キャラクタセットの確認後 MyISAMの表及び、InnoDBの表を作成する。最後にマルチバイトを含む文字列の登録と参照を行う。


pb17:˜ discus$ mysql -u jobs -p mysqldb
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or ¥g.
Your MySQL connection id is 100 to server version: 4.0.25-standard

Type 'help;' or '¥h' for help. Type '¥c' to clear the buffer.


※デフォルトキャラクタセットを確認しておく。

mysql> show variables like '%char%'¥G
*************************** 1. row ***************************
Variable_name: character_set
Value: sjis
*************************** 2. row ***************************
Variable_name: character_sets
Value: latin1 big5 czech euc_kr gb2312 gbk latin1_de sjis tis620 ujis dec8 dos german1 hp8 koi8_ru latin2 swe7 usa7 cp1251 danish hebrew win1251 estonia hungarian koi8_ukr win1251ukr greek win1250 croat cp1257 latin5
*************************** 3. row ***************************
Variable_name: convert_character_set
Value:
3 rows in set (0.00 sec)

※ emp表をMyISAMエンジンで作成する。

mysql> show create table emp¥G
*************************** 1. row ***************************
Table: emp
Create Table: CREATE TABLE `emp` (
`empno` int(11) NOT NULL default '0',
`ename` varchar(40) default NULL,
PRIMARY KEY (`empno`)
) TYPE=MyISAM
1 row in set (0.00 sec)

※Terminalから日本語を入力すると以下のようになるが、問い合わせると正常に表示される。
(現時点のTerminalの問題点なのでしかたない。)
  ちなみに、Terminalの文字エンードは 日本語MacOS(SJIS系)にしてある。


mysql> insert into emp values(1,'¥202¥250¥202¥347¥202¥250¥202¥347');
Query OK, 1 row affected (0.00 sec)

mysql> insert into emp values(2,'¥202¥331¥202¥260');
Query OK, 1 row affected (0.00 sec)

mysql> insert into emp values(3,'¥211¥273¥202¥257¥202¥310¥202¥242¥202¥346¥202¥313¥201[¥201`');
Query OK, 1 row affected (0.00 sec)


mysql> select * from emp;
+-------+------------------+
| empno | ename |
+-------+------------------+
| 1 | おらおら |
| 2 | ほげ |
| 3 | 化けないよねー〜 |
+-------+------------------+

3 rows in set (0.00 sec)

mysql>
mysql>


トランザクションをサポートしているinnoDBをエンジンに使った表も用意する。(BDBやMAXDBも存在するようだが、InnoDBを使っているところのほうが多そうなのでInnoDBに絞る。
InnoDBは、Oracleのようなマルチバージョニングを行っているエンジンであり、先日Oracleが買収したことでも有名。

(前述の表は、MyISAMをエンジンに利用しているため、commitや、rollbackが行えない。つまり、INSERT文や、UPDATE文、DELETE文は ”常に”AUTOCOMMIT されてしまう。
ROLLBACKができないので、その手の処理はプログラムに実装する必要があるのだ。常にトランザクションを意識している世界でプログラミングしていた方は要注意!)

当然、OracleにあるようなFlush back queryや、Flush back dropも無いのでバックアップから戻すことになる。rollback入力し、エラーが帰ってきたところで、あ! という声が発せられることになる。。。(自分で実験済み! ^^;;; )

ちなみに、今回はMySQLやPostgreSQL側にOracleからデータを参照することをメインに考えているのであまり影響ないが、どのような動きをするのかも確認しておきたいので、MyISAM及びInnoDB両エンジンを利用した表を準備しておく。

注)
show create table inno_emp; としても内容は確認できるが非常に読みにくく表示されるので show create table inno_emp¥G として表示形式を読みやすくしてある。
詳細は、mysql> help  としてヘルプで確認してもらいたい。
 
mysql> show create table inno_emp¥G
*************************** 1. row ***************************
Table: inno_emp
Create Table: CREATE TABLE `inno_emp` (
`empno` int(11) NOT NULL default '0',
`ename` varchar(40) default NULL,
PRIMARY KEY (`empno`)
) TYPE=InnoDB
1 row in set (0.07 sec)

emp表と同じデータを登録しておく。


mysql> insert into inno_emp select * from emp;
Query OK, 3 rows affected (0.08 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from inno_emp;


+-------+------------------+
| empno | ename |
+-------+------------------+
| 1 | おらおら |
| 2 | ほげ |
| 3 | 化けないよねー〜 |
+-------+------------------+
3 rows in set (0.00 sec)

mysql>

ここまでで、 MacOSX 10.4.3 Tiger (PowerBook G4 1Ghz)のMySQL4.0.25のデータベースの準備は完了した。
次は、同じMacに PostgreSQL7.4.9を構築する。

余談だが、妻は今 Scarab De MySQL と格闘中?!(環境できたかな〜)

| | コメント (1) | トラックバック (0)

2005年12月29日 (木)

Mac De Oracle Heterogeneous! #1

さて、しばらくご無沙汰していた記事投稿再開第一弾は、Generic Connectivityに関するものにした。
Generic Connectivityは、Oracle Database Heterogeneous Connectivity(異機種間接続)機能の一部で、
他に Transparent Gatewayという有償オプションも用意されている。(詳細は、マニュアル「Oracle Database Heterogeneous Connectivity管理者ガイド 10g」を参照するとよいだろう。)

Generic Connectivityは、ODBC又は、OLE DBを利用して行えるOracle Databaseの基本機能の一つ。
今回はODBCドライバが提供されている


MySQL4.0.25 (MacOSX 10.4 Tiger)
MySQL4.0.26-nt (WindowsXP Pro)
MySQL4.1.13a (MacOSX 10.4 Tiger Server付属のもの)
PostgreSQL7.4.9 (MacOSX 10.4 Tiger)

という4つのリモートデータベースに、Mac De Oracleらしく、MacOSX 10.4 Tiger Serverに無理矢理構築した、Oracle10g R1 EE 10.1.0.3から接続して動作上の癖を把握しておくことにした。

しかし、ここで問題発生。
現時点では、MacOSX版 Oracle10g には Heterogeneous Serviceが提供されていないのである。
どうするかしばし考えて浮かんだのが、Windows版又は、Linux版 Oracle10g R1 EEを踏み台にしてMacOSX Server上のOracle10gからアクセスするという方法。
そこまでしてそんなことやりたいのかという声が聞こえてきそうだが、最近、PostgreSQLやってくれとかMySQLがどうの。。。という話も多くなり、それらの勉強も兼ねて試してみることにした。(こんなことも試しておけば何かの役に立つこともあるだろうから。)
#そのうち FireBirdなどでも試してみるかもしれない。

ではまず、各リモートデータベースとするデータベースの構築から行っていく。尚、踏み台にするOracleはWindowsに構築することにした。
(LinuxはOracle9iで遊んでいるため今回は利用しないが、Unix/LinuxではunixODBC(ODBC driver Manager)及び、各データベースに対応したlinux向けODBC Driverがリリースされているし、Blogなどでも結構記事を見かけるのでそれを参考にするとよいだろう。また、unixODBCのODBCConfig(GUI)は、Windowsのデータソース管理の操作性に類似しているので戸惑うことは少ないと思う)

環境は以下の通り。
(キャタクタセットが統一できていれば一番よいが現実問題としてそうも行かない。が、今回、MySQLのデータベースはすべてSJISで作成した)

1、MacOSX 10.4.3 Tiger (PowerBook G4 1Ghz)


PostgreSQL 7.4.9 (キャラクタセット EUC。キャラクタセットにSJISが無いのでEUCにした。)
MySQL 4.0.25 standard (キャラクタセット SJIS)

  #ほんとうは、iMacG5に作りたかったけど、奥さん専用のMacなので今回は遠慮した。(^^;;

2、MacOSX 10.4.3 Tiger Server (Power Mac G5 Dual 2.7Ghz)


MySQL 4.1.13a (キャラクタセットSJIS、MacOSX 10.4 Serverに付属しているもの)
Oracle10g R1 EE 10.1.0.3(キャラクタセット JA16SJISTILDE、無理矢理構築したもの)

3、WindowsXP Professional (AMD AthronMP Dual 2800+)


Oracle10g R1 EE 10.1.0.3(キャラクタセット JA16SJISTILDE)
(これを踏み台にしてMacOSX のOracleから各リモートデータベースをアクセスする)

MySQL 4.0.26-nt standard(キャラクタセット SJIS)


イメージはこんな感じ


Deploymentdiagram_1


次回は、MacOSX 10.4.3 Tiger (PowerBook G4)にMySQL4.0.25 standard のデータベースを作成し、接続確認するための表を作成する。

| | コメント (0) | トラックバック (0)