エンタープライズ:特集 2003/08/24 11:32:00 更新

[JAVA Developer特別企画]2003年10月号
知っておきたいデータベース移行術「Oracle→DB2編」 (6/7)

JAVA Developer 2003年10月号より転載

■(4)SQL文
 マイグレーション作業において注意が必要となるSQL文(主にコマンド命令)の違いについて紹介します。

・(1)SAVEPOINT
 SAVEPOINT命令は、トランザクション内にセーブポイントを定義、ROLLBACK命令によって、任意のセーブポイントへロールバックできます。この命令は、主要なデータベース製品ではOracleとDB2が対応しているものです。
 セーブポイントを定義する文法は次のとおり。


Oracle
SAVEPOINT s1;

DB2
SAVEPOINT s1 ON ROLLBACK RETAIN CURSORS;

 DB2は、ON ROLLBACK RETAIN CURSORS句が必須です。また、単一トランザクション内に、複数のセーブポイントを定義することができません。
 定義したセーブポイントまでロールバックするROLLBACK命令は、文法上違いがありません。


ROLLBACK TO SAVEPOINT s1;

・(2)ROWNUM
 OracleのROWNUMは、自動採番や取得行制限のために使用される「疑似列」です。DB2の場合、自動採番にはROW_NUMBER関数を使用します。このROW_NUMBER関数は、Oracle8i以降でもサポートされています。
 ORDER BY句を含まない場合は、


Oracle
SELECT ROWNUM,no,salary FROM emp;

DB2
SELECT row_number() over(),no,salary FROM emp;

ORDER BY句を含む場合は、


Oracle
SELECT ROWNUM,no,salary FROM (SELECT no,salary FROM emp ORDER BY no);

DB2
SELECT row_number() over(),no,salary FROM emp ORDER BY no;

とします。
 OracleのROWNUMと違い、ROW_NUMBER関数は、ORDER BY処理のあとに番号を振ります。
 また、取得行制限には、FETCH FIRST n ROWS ONLY句を使用します。最初の10レコードを取得する場合は、

Oracle
SELECT * FROM emp WHERE ROWNUM<11;

DB2
SELECT * FROM emp FETCH FIRST 10 ROWS ONLY;

というSQL文になります。

・(3)NOWAIT
 NOWAITは、要求ロックが取得できない場合、ただちにエラーを返すよう要求する句です。「SELECT FOR UPDATE NOWAIT」のように用いられ、これによりアプリケーションはロック待ちをせずにすみます。
 DB2ではこれに対応する句はサポートされていません。ロック待ち時間を制限する「LOCKTIMEOUT」というデータベース構成パラメータがあり、これを0にすることで同じような効果は得られますが、データベース全体に影響を与えてしまいますので推奨できません。
 現実的な解決策としては、まずLOCKTIMEOUTを短め(30秒程度)に設定し、適度にロック待機を起こさせるようにすることです。さらにアプリケーション側では、タイムスタンプなどを使用して制御するなどが考えられます。

・(4)ROWID
 OracleのROWIDは、レコードの物理アドレスを示す疑似列です。DB2にはROWIDに対応するものはありません。索引は、行を識別するためにRID(レコードID)という表スペース内での識別子を使用していますが、これをアプリケーションが直接使用することはできません。
 解決策としては、ROWIDを使用している個所があればそれをユニークIDに置き換えるのが手っ取り早い方法です。もし、ROWID使用個所が多く書き換えが面倒であれば、ROWIDという列を別途作成するのがよいでしょう。それには、以下のようなパターンが使用できます。

・ROWIDをそのまま使用する
 ROWIDを含んだCSVファイルを作成し、新しい表を作成します。

  (1)CSV形式でROWIDも出力(SQL文をスプール)


    SELECT '''rowid || '',' ||
    id || ','' || name || '''
    FROM emp;

  (2)ROWIDを格納するユーザー定義特殊型を作成


    CREATE DISTINCT TYPE ROWID
    AS CHAR(18) WITH COMPARISONS;

  (3)ユーザー定義特殊型を使用する表を作成


    CREATE TABLE emp(
    rowid ROWID,
    id SMALLINT,
    name VARCHAR(10));

  (4)(1)で作成したファイルをロード


    LOAD FROM ファイル名
    OF DEL INSERT INTO emp;

・ROWIDを新たに振り直す
 GENERATE_UNIQUE関数を使用して、データベース固有の値を自動生成します。このケースではROWID列を含まないダミー表(ここではemp_dummy)を最初に作っておきます。

  (1)表を作成


    CREATE TABLE emp (
    ROWID CHAR(13) FOR BIT DATA,
    name VARCHAR(10));

  (2)ユニーク列を生成しながら、表にデータを挿入


    INSERT INTO emp
    SELECT generate_unique(),name
    FROM emp_dummy;

 例として2つの方法をあげましたが、このほかにもやり方はあると思います。アプリケーションに適した方法を選択してください。

・(5)外部結合
 Oracle8iまでの(+)記号を使用する外部結合形式は、DB2では下記のように書き換えます。


Oracle
SELECT * FROM
   samp1 t1,samp2 t2,samp3 t3
WHERE t1.name = t2.name(+)
AND t1.name = t3.name(+);

DB2
SELECT  * FROM samp1 t1
LEFT OUTER JOIN samp2 t2
   ON t1.name = t2.name
LEFT OUTER JOIN samp3 t3
   ON t1.name = t3.name;

 ANSI SQL92では、この例で示したDB2での記述式が標準として規定されています。(+)が左側の列についていたら、RIGHT OUTER JOINを使用します。またフルアウタージョインには、FULL OUTER JOIN句を使用します。

・(6)MINUS
 Oracleでは、差集合をMINUS演算子によって計算します。DB2では、MINUS演算子の代わりにEXCEPT演算子を使います。


Oracle
SELECT product_id FROM inventories
MINUS
SELECT product_id FROM order_items;

DB2
SELECT product_id FROM inventories
EXCEPT
SELECT product_id FROM order_items;

・(7)DECODE
 CASE文で対応します。

[JAVA Developer特別企画]
知っておきたいデータベース移行術「Oracle→DB2編」
・データベースオブジェクト
・データ型
・ビルトイン関数
・SQL文
・ロックと読み取り一貫性

関連リンク
▼JAVA Developer
▼定期購読のご案内
▼バックナンバー販売協力店

JAVA Developer10月号表紙 JAVA Developer 10月号

大特集
再入門 J2SE

特集2 Oracle9i Application Server
[特別企画]
・例外処理のメカニズム
・データベース移行術(2)
 「Oracle→DB2編」
・Tomcatで試すJava2セキュリティ

前のページ | 1 2 3 4 5 6 7 | 次のページ

[竹内 笑子,JAVA Developer]