« Mac De Oracle Heterogeneous! #23 | トップページ | Mac De Oracle Heterogeneous! #25 »

2006年1月31日 (火) / Author : Hiroshi Sekiguchi.

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側の癖から確認してみようと思う。

| |

トラックバック


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

コメント

コメントを書く