...

Oracle DB2 2013年1月

by user

on
Category: Documents
397

views

Report

Comments

Transcript

Oracle DB2 2013年1月
OracleからDB2 10への移行
- DB2の機能、ツール、および移行ポイント -
2013年1月
日本アイ・ビー・エム株式会社
本資料掲載事項は、ある特定の環境・使用状況においての正確性がIBMによって確認されていますが、すべての環境において同様の結果が得られる保証は
ありません。これらの技術を自身の環境に適用する際には、自己の責任において十分な検証と確認を実施いただくことをお奨めいたします。
1
© 2013 IBM Corporation
内容
 DB2とOracleの用語
 Oracleからの移行を容易にするDB2の機能
 移行ロードマップ
 移行ツール
 Oracleからの移行ポイント
※当資料はDB2 V10.1 for Linux, UNIX, and Windows Fix Pack 1の環境に基づいています。
2
© 2013 IBM Corporation
DB2とOracleの用語
3
© 2013 IBM Corporation
DB2とOracleの用語
設計
4
Oracle
DB2
インスタンス
インスタンスまたはデータベース・マネージャー
オンラインREDOログ
アクティブ・ログ
アーカイブ・ログ
アーカイブ・ログ
非アーカイブ・ログ・モード
循環ロギング
データ・ファイル
コンテナー
SYSTEM 表スペース
SYSCATSPACE 表スペース
表スペース
表スペース
エクステント
エクステント
データ・ブロック
データ・ページ
セグメント
ストレージ・オブジェクト
パーティション表
パーティション表
マテリアライズ・ビュー
マテリアライズ照会表 (MQT)
グローバル索引
非パーティション索引
ローカル索引
パーティション索引
データ・ディクショナリー
システム・カタログ
© 2013 IBM Corporation
DB2とOracleの用語
設定/メモリー
アプリ使用機能
運用
5
Oracle
DB2
ORACLE_SID 環境変数
DB2INSTANCE 環境変数
init.ora および Server Parameter File (SPFILE)
データベース・マネージャー構成ファイルおよびデータベース構成ファイル
System Global Area (SGA)
インスタンス共有メモリーおよびデータベース共有メモリー
Program Global Area (PGA)
アプリケーション共有メモリーおよびエージェント専用メモリー
User Global Area (UGA)
アプリケーション・グローバル・メモリー
データ・バッファー・キャッシュ
バッファー・プール
ラージ・プール
ユーティリティー・ヒープ
ライブラリー・キャッシュ
パッケージ・キャッシュ
データ・ディクショナリー・キャッシュ
カタログ・キャッシュ
グローバル一時表
グローバル一時表
カーソル共有
ステートメント・コンセントレーター
データベース・リンク
ニックネーム
DUAL 表
DUAL 表
Oracle Call Interface (OCI)
コール・レベル・インターフェース (CLI)
セッション
セッション、データベース接続
バインド変数
パラメータ・マーカー
動的なパフォーマンス・ビュー
スナップショット・モニター SQL 管理ビュー
アラート・ログ
管理通知ログ
bdump ディレクトリー
診断ログ (db2diag.log)
startup nomount
db2start
© 2013 IBM Corporation
Oracleからの移行を容易にするDB2の機能
6
© 2013 IBM Corporation
移行における課題
Transact-SQL
Oracle の
SQL および
PL/SQL
■
DB2 の SQL/PL
(SQL/PSM に基づく)
アプリケーションが、選択した RDBMS に特化している
– 異なる RDBMS へ移行するにはコードの大幅な書き直しが必要
– 既存スキルを活用できない
DB2は、これらの問題を解決するための機能を提供しており、その拡張を継続的に行っている
7
© 2013 IBM Corporation
Oracleの各機能に対応するDB2の機能
 Oracle
– データ・タイプ
– データ・ディクショナリー
– SQL
• 基本的なDDL
• データベース・リンク
• マテリアライズド・ビュー
• …
– 同時実行制御
– PL/SQL言語
– PL/SQLパッケージ
– JDBC
– Pro*C
– OCI
– C言語のAPI
– Oracle Forms
– SQL*Plus
– SQL*Loader
– RAC
–…
 DB2
– 互換フィーチャー
– 互換フィーチャー
– SQL
• ツール
• Federation(フェデレーション)
• マテリアライズ照会表、CDC※
• …
– 同時実行制御(Currently Committed)
– 互換フィーチャー
– 互換フィーチャー
– JDBC
– 組み込みSQL(互換フィーチャー付)
– DB2CI(Oracle互換)
– CLIがDB2本来のC言語用APIだが、
DB2CIもOracle互換APIとして提供
– パートナー製品の使用(Java Forms)
– CLPPlus
– IMPORT, LOAD, INGESTユーティリティ
– DB2 pureScale
–…
※ InfoSphere Change Data Capture
8
© 2013 IBM Corporation
互換フィーチャーの設定: DB2_COMPATIBILITY_VECTOR レジストリ変数
 この変数をセットすることで、他DBとの互換フィーチャーを有効にする
 db2set コマンドでセット
 ビットごとに互換フィーチャーが定義
– 例:
• 1ビット目: ROWNUM疑似列
• 2ビット目: DUAL表
 有効化するビットを1にして16進数(HEX)で表す、または予約ワードをセット
– 予約ワード
• ORA
Oracle互換フィーチャーを最大限に活用
• SYB
Sybase互換フィーチャーを最大限に活用
• MYS
MySQL互換フィーチャーを最大限に活用
–例
• db2set DB2_COMPATIBILITY_VECTOR=FFFF
• db2set DB2_COMPATIBILITY_VECTOR=ORA
(ORAは20FFFと同じ)
 設定を変えたらDB2インスタンスの再起動を行う
$ db2stop
$ db2start
9
© 2013 IBM Corporation
DB2_COMPATIBILITY_VECTORで設定可能な互換フィーチャー
ビット位置
互換性フィーチャー
1 (0x01)
2 (0x02)
3 (0x04)
4 (0x08)
5 (0x10)
6 (0x20)
7 (0x40)
8 (0x80)
ROWNUM
DUAL
外部結合演算子
階層照会
NUMBER ※
VARCHAR2 ※
DATE ※
TRUNCATE TABLE
9 (0x100)
文字リテラル
10 (0x200)
11 (0x400)
12 (0x800)
13 (0x1000)
14 (0x2000)
17 (0x10000)
18 (0x20000)
コレクションのメソッド
コメント
ROW_NUMBER() OVER() の同義語
DUAL ダミー表を使用可能化
外部結合演算子 (「+」記号) のサポートを使用可能化。
CONNECT BY 節を使用した階層照会のサポート。
NUMBER データ・タイプおよび関連した数値処理のサポート
VARCHAR2 型と NVARCHAR2 データ・タイプおよび関連した文字ストリング処理
DATE データ・タイプを TIMESTAMP(0) データ・タイプとして変換処理可能
TRUNCATE ステートメントの代替セマンティック
CHAR データ・タイプまたは GRAPHIC データ・タイプ (VARCHAR データ・タイプまたは
VARGRAPHIC データ・タイプの代替)
配列での演算を実行するためのメソッド (first、last、next、およびprevious など) を
使用可能化。
配列内の特定のエレメントを参照するときに大括弧の代わりに小括弧を使用可能化。
例: 「array1(i)」は「array1」のエレメント「i」を参照する。
データ・ディクショナリー互換ビュー ※ データ・ディクショナリー互換ビューはデータベースの作成時に作成
PL/SQL コンパイル
PL/SQL ステートメントのコンパイルおよび実行の可能化
インセンシティブ・カーソル
SELECT ステートメントが明示的に FOR UPDATE を指定しない場合、WITH RETURN
で定義されたカーソルがインセンシティブになる。
INOUT パラメーター
INOUT パラメーター宣言に対する DEFAULT の指定
SQL データ・アクセス・レベルの強制 実行時にルーチンが SQL データ・アクセス・レベルを強制可能。
Oracleデータベース・リンク構文
Oracleデータベース・リンク構文を有効にする
※ データベース作成前に設定必要
参照URL:
http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.apdv.porting.doc/doc/r0052867.html
10
© 2013 IBM Corporation
互換フィーチャー例
 以下の互換フィーチャーを有効にする
– ビット5 (0x10): Oracle NUMBER互換
– ビット6 (0x20): Oracle VARCHAR2互換
– ビット7 (0x40): Oracle DATE互換
– ビット11(0x400): Oracleデータ・ディクショナリー互換ビュー
0x10 + 0x20 + 0x40 + 0x400 = 0x470
 設定はDB2インスタンスを再起動して有効になる。その後、データベースを作成する
$ db2set DB2_COMPATIBILITY_VECTOR=470
$ db2stop
$ db2start
$ db2sample -name oradb ← サンプルDBを作成
 データ・タイプ互換の確認
– データ・タイプ互換の場合、DB構成情報で確認可能
$ db2 get db cfg for oradb
…
NUMBER データ・タイプの互換性
VARCHAR2 データ・タイプの互換性
データ・タイプ DATE の TIMESTAMP(0) への互換性
…
11
= ON
= ON
= ON
© 2013 IBM Corporation
Oracleデータ・ディクショナリー互換ビューの確認
 Oracleデータ・ディクショナリー互換ビューの例
– 接続ユーザーが作成した表情報の取得
select * from user_tables
– 接続ユーザーが作成したビュー情報の取得
select * from user_views
参照URL
http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.apdv.porting.doc/doc/c0054440.html
 DB2が提供しているカタログ・ビューも引き続き使用可能
– 接続ユーザーが作成した表名(スキーマ名.表名)の取得
select tabschema, tabname from syscat.tables where type='T' and
owner=current user
– 接続ユーザーが作成したビュー名とビュー定義の取得
select viewschema, viewname, text from syscat.views where
owner=current user
参照URL
http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0011297.html
12
© 2013 IBM Corporation
互換フィーチャーの追加設定
 互換フィーチャーの追加設定前
Oracle特有の
外部結合演算子
$ db2 -td/
db2 => select lastname,deptname from employee e, department d where e.workdept(+)=d.deptno/
SQL0104N "(+" に続いて予期しないトークン ")"
が見つかりました。予期されたトークンに "(" が含まれている可能性があります。
SQLSTATE=42601
db2 => set serveroutput on/
DB20000I SET SERVEROUTPUT コマンドが正常に完了しました。
db2 => declare
i number;
PL/SQL
begin
i := 10;
dbms_output.put_line('i=' || i);
end;
/
DB21034E コマンドが、有効なコマンド行プロセッサー・コマンドでないため、 SQL
ステートメントとして処理されました。 SQL 処理中に、次のエラーが返されました。
SQL0104N "BEGIN-OF-STATEMENT" に続いて予期しないトークン "declare i number;
begin i := 10;" が見つかりました。予期されたトークンに "<values>"
が含まれている可能性があります。 LINE NUMBER=1. SQLSTATE=42601
13
© 2013 IBM Corporation
互換フィーチャーの追加設定
 すべての互換フィーチャーをオンに設定変更して、既存のデータベースにアクセス
$ db2set DB2_COMPATIBILITY_VECTOR=ORA
$ db2stop
$ db2start
$ db2 connect to oradb
$ db2 -td/
Oracle特有の
外部結合演算子
 すべての互換フィーチャーをオンに設定した後の動作
db2 => select lastname,deptname from employee e, department d where e.workdept(+)=d.deptno/
LASTNAME
DEPTNAME
--------------- -----------------------------------HAAS
SPIFFY COMPUTER SERVICE DIV.
…
BRANCH OFFICE I2
BRANCH OFFICE J2
48 レコードが選択されました。
これは右外部結合。DB2本来の書き方は次のようになる(SQL92の規約に基づく)
db2 => select lastname,deptname from employee e right outer join department
d on e.workdept=d.deptno/
14
© 2013 IBM Corporation
互換フィーチャーの追加設定
 すべての互換フィーチャーをオンに設定した後の動作
db2 => set serveroutput on/
DB20000I SET SERVEROUTPUT コマンドが正常に完了しました。
db2 => declare
i number;
begin
i := 10;
dbms_output.put_line('i=' || i);
end;
/
DB20000I SQL コマンドが正常に完了しました。
PL/SQL
(Oracle互換フィーチャー)
i=10
db2 => begin
declare i integer;
set i = 10;
call dbms_output.put_line('i=' || i);
end
/
DB20000I SQL コマンドが正常に完了しました。
SQL PL (DB2本来の機能も引き続き利用可能)
i=10
15
© 2013 IBM Corporation
PL/SQL互換フィーチャー
 ネイティブ PL/SQL サポート: DB2 エンジンに PL/SQL コンパイラーも同梱
– エミュレーションなし(PL/SQLとSQL PLを同じレベルで実行可能)
– ソース・レベルのデバッグおよびプロファイル
エディター
PL/SQLもSQL PLも
アーキテクチャーは同じ
Data Studio
PL/SQL
コンパイラー
SQL PL
コンパイラー
デバッガー
DB2 サーバー
SURE
(SQL Unified Runtime Engine)
プロファイラー
データベース
16
© 2013 IBM Corporation
DB2 10 の組み込みパッケージ
フィーチャー
説明
DBMS_ALERT
クロス・セッション・セマフォー
DBMS_DDL
DDL オブジェクトの難読化
DBMS_JOB
ジョブ・スケジューラー、管理のプロシージャー
DBMS_LOB
LOB を操作する機能
DBMS_OUTPUT
「画面出力によるデバッグ」および簡単なレポート作成
DBMS_PIPE
クロス・セッション・データ・パイプ
DBMS_SQL
動的 SQL を実行するためのプロシージャー・セット
DBMS_UTILITY
さまざまな関数およびプロシージャー
MONREPORT
データのモニターとテキスト・レポートの生成
UTL_DIR
ディレクトリーの別名を維持するためのルーチン
UTL_FILE
サーバー・サイドの I/O API
UTL_MAIL
E メール送信機能(SMTPはDB構成情報定義を利用)
UTL_SMTP
SMTP を指定したEメール送信機能
参照URL
• http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.apdv.sqlpl.doc/doc/c0053670.html
17
© 2013 IBM Corporation
NUMBERデータ・タイプのサポート
 NUMBERデータ・タイプは以下のように変換される
Oracle
DB2
数値のタイプ
NUMBERのみ指定
DECFLOAT(16) ※
浮動小数点
NUMBER(最大桁数)
DECIMAL(最大桁数)
整数
NUMBER(最大桁数, 小数点以下桁数)
DECIMAL(最大桁数, 小数点以下桁数)
固定小数点
※ 値が16桁を超える場合、DECFLOAT(34) へ変更する
例
db2 => create table t1 (n1 number, n2 number(10), n3 number(20, 5));
db2 => describe table t1;
データ・タイ
列名
プ・スキーマ
------------------------------- --------N1
SYSIBM
N2
SYSIBM
N3
SYSIBM
データ・
列の
スケ
タイプ名
長さ
ール
------------------- ---------- ----DECFLOAT
8
0
DECIMAL
10
0
DECIMAL
20
5
NULL
-----はい
はい
はい
db2 => insert into t1 values (10, 100, 1000.11), (200, 2000, 20000.22222);
db2 => select * from t1;
N1
N2
N3
------------------------ ------------ ---------------------10
100.
1000.11000
200
2000.
20000.22222
18
© 2013 IBM Corporation
端数の丸め込み方法
 DECFLT_ROUNDING データベース構成パラメーターで設定
 DB2の場合、デフォルトは ROUND_HALF_EVEN
– 最も近い値に丸める
– 正確に等間隔の場合、末尾が偶数になるように丸める
– 例:
db2 => create table t2 (n1 number, n2 number(5,2));
db2 => insert into t2 values (1234567890.1234565, 123.455);
N1
N2
------------------------ ------1234567890.123456 123.46
1が付くと切り上げの方が近くなる
db2 => delete from t2;
db2 => insert into t2 values (1234567890.12345651, 123.465);
N1
N2
------------------------ ------1234567890.123457 123.46
 Oracleの場合、四捨五入 (ROUND_HALF_UP)
– Oracleと同じ、四捨五入にする場合
update db cfg for [DB名] using DECFLT_ROUNDING ROUND_HALF_UP
 参照URL
– http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.config.doc/doc/r0052298.html
19
© 2013 IBM Corporation
振る舞いが変わる主な機能 (VARCHAR2)
 VARCHAR データ・タイプに自動変換
 この互換フィーチャーをオンにすると、VARCHARデータ・タイプの振る舞いが変わる
20
VARCHAR2互換なし
VARCHAR2互換
空文字('')とNULLの区別
区別する
区別なし
(空文字はNULLに変換される)
非NULL制約
空文字の挿入可
空文字を挿入できない
文字列の比較
文字列末尾の空白の違いは
無視して比較
文字列末尾の空白が違うものは
違う文字として扱う
© 2013 IBM Corporation
振る舞いが変わる主な機能 (VARCHAR2)
VARCHAR2としてもよい
(VARCHARに自動変換)
例
VARCHAR2互換なし
create table t3 (c1 int,
c2 varchar(10) not null);
insert into t3 values (1, 'hello');
insert into t3 values (2, 'hello ');
create table t3 (c1 int,
c2 varchar(10) not null);
insert into t3 values (1, 'hello');
insert into t3 values (2, 'hello ');
select * from t3 where c2='hello';
C1
C2
----------- ---------- 文字列末尾の空白文字
の違いを無視
1 hello
2 hello
select * from t3 where c2='hello';
C1
C2
----------- ---------1 hello
insert into t3 values (3, '');
DB20000I SQL コマンドが正常に完了しました。
insert into t3 values (3, '');
SQL0407N NULL 値の NOT NULL 列
"TBSPACEID=3, TABLEID=7, COLNO=1"
への代入は許されていません。
SQLSTATE=23502
select * from t3;
C1
C2
----------- ---------1 hello
2 hello
3
21
VARCHAR2互換
非NULL制約でも空文字の挿入可
空文字はNULLに変換される
© 2013 IBM Corporation
振る舞いが変わる主な機能 (DATE)
 OracleのDATE型は時間を保持(時分秒)
 DB2のDATE型は時間を保持しない
 この互換フィーチャーをオンにすると、以下のような振る舞いとなる
DATE互換なし
DATE互換
DATE型の列
DATE型のまま
TIMESTAMP(0)に変換
CURRENT DATE
特殊レジスター
DATE値を戻す
TIMESTAMP(0)値を戻す
日付の演算
+ 1 day などと記述(1日加算)
+ 1 で1日加算
- 2/24 で2時間減算
+ 3/24/60 で3分加算
以下の表記はDATE型ではエラーと
なる(TIMESTAMP型で使用可能)
- 2 hour (2時間減算)
+ 3 minute (3分加算)
22
© 2013 IBM Corporation
振る舞いが変わる主な機能 (DATE)
 例: DATE互換なし
create table t4 (c1 int, c2 date);
select colname,typename,scale from syscat.columns where tabname='T4';
COLNAME TYPENAME
SCALE
-------- ----------- ----C1
INTEGER
0
C2
DATE
0
insert into t4 values (1, '2012-08-25');
insert into t4 values (2, '2012-09-05-10.20.30');
select * from t4;
C1
C2
時間は削除(無視)されて挿入される
----------- ---------1 2012-08-25
2 2012-09-05
select to_char(c2,'YYYY/MM/DD HH24:MI:SS') from t4;
1
---------------------2012/08/25 00:00:00
2012/09/05 00:00:00
select current date - 5 day from sysibm.sysdummy1;
1
---------2012-08-30
23
© 2013 IBM Corporation
振る舞いが変わる主な機能 (DATE)
 例: DATE互換
create table t4 (c1 int, c2 date);
select colname,typename,scale from syscat.columns where tabname='T4';
COLNAME TYPENAME
SCALE
-------- ----------- ----C1
INTEGER
0
C2
TIMESTAMP
0
insert into t4 values (1, '2012-08-25');
insert into t4 values (2, '2012-09-05-10.20.30');
select * from t4;
C1
C2
----------- ------------------1 2012-08-25-00.00.00
2 2012-09-05-10.20.30
select to_char(c2,'YYYY/MM/DD HH24:MI:SS') from t4;
1
---------------------2012/08/25 00:00:00
2012/09/05 10:20:30
select current date - 3 + 14/24 from dual;
1
------------------2012-09-02-01.58.45
24
© 2013 IBM Corporation
同時実行制御
 分離レベル
ISO分離レベル
DB2
Oracle
SERIALIZABLE
REPEATABLE READ (RR)
SERIALIZABLE
REPEATABLE READ
READ STABILITY (RS)
なし
READ COMMITTED
CURSOR STABILITY (CS)
• Currently Committed機能
(CUR_COMMIT=ON|OFF)
READ COMMITTED
READ UNCOMMITTED
UNCOMMITTED READ (UR)
なし
(*) 青字がデフォルト
 DB2の分離レベル CS では、Currently Committed の設定が可能
– DB構成パラメータ CUR_COMMIT で設定
– デフォルトは ON
db2 get db cfg for [DB名]
…
CS 分離レベルで現在コミット済みの結果を戻す (CUR_COMMIT) = ON
…
25
© 2013 IBM Corporation
同時実行制御
 Oracle の READ COMMITTED
– データの読み取り
• SQL文発行時点のコミット済みデータを取得
 UNDOセグメントを使って実現(ログとUNDOセグメントの両方に書き込み)
• 別のトランザクションがデータを更新中でも、それがコミットされるのを待たない
• SQL文発行後にコミットされたデータは読まない
SCN = システム変更番号
SCN=32
TRN1
UPDATE
UNDOセグメント
B
SCN=102
UPDATE
COMMIT
A
SCN=64
C
C’
C
D
D’
D
SCN=76
SCN=100
TRN2
SELECT
E
F
読んだデータは最新とは限らないが、参照処理のロック待機は発生しない
UNDOセグメントを使って実現(ログとUNDOセグメントの両方に書き込み)
26
© 2013 IBM Corporation
同時実行制御
 DB2 の Currently Committed
– データを読み取る際、最新のコミット済みデータを取得し、別のトランザクションが
データを更新中でも、それがコミットされるのを待たない
• ログのみを使って実現
A
TRN1
UPDATE
B
トランザクションログ
(ログバッファー)
C
C’
C
UPDATE
D
D’
D
TRN2
SELECT
E
F
読むデータは常に最新で、参照処理のロック待機も発生しない
ログのみを使って実現
27
© 2013 IBM Corporation
データベース・リンク、マテリアライズド・ビューの移行
 Oracleの代表的なDB連携
– データベース・リンク
• リアルタイムの外部Oracleへの仮想アクセス
Oracle
Oracle
DBLINK
SQL
Oracle
Oracle
– マテリアライズド・ビュー
• トリガー・ベースのテーブルの差分レプリケーション
Oracle
マテリアライズド
・ビュー
SQL
28
Oracle
差分トリガー
© 2013 IBM Corporation
データベース・リンク、マテリアライズド・ビューの移行
 フェデレーションとInfoSphere Change Data Captureが解決!
– フェデレーション
• リアルタイムに外部の多様なDBへの仮想アクセス
DB2
Oracle
フェデレーション
DB2
SQL
SQL Server
さまざまな
データソースを
サポート
(含非RDBデータ)
– InfoSphere Change Data Capture
• ログベースのテーブルの差分レプリケーション
DB2
Oracle
CDC
ログベースで
高速、軽量
CDC
SQL
ログ
29
© 2013 IBM Corporation
フェデレーション機能によるニックネーム・アクセス
ニックネームは実体をもたない仮想的な表

リモートの表やビュー、ストアードプロシージャの仮想オブジェクト
–
ローカル・オブジェクトのように操作

リアルタイムの参照・更新が可能

マルチソースのJoinが可能
多種多様なデータソースを
表のイメージでアクセス
ユーザー・アプリケーション
SELECT *
FROM ORAEMP
WHERE -------DB2 10.1 Fix Pack 1で以下の構文もサポート
(Oracle互換フィーチャー:0x20000)
SELECT *
FROM SCOTT.EMP@ORACLE
WHERE --------
30
DB2
ニックネーム
DB2ADMIN.ORAEMP
Oracle
ソース表
ORACLE.SCOTT.EMP
CREATE NICKNAME ORAEMP
FOR ORACLE. SCOTT.EMP
© 2013 IBM Corporation
IBM InfoSphere Change Data Capture
Point 
①
高速、軽量、低負荷な差分レプリケーション
– データベースのログから差分データを抽出
 幅広いDB、プラットフォームのサポート
– Oracle, DB2 for LUW, iSereis, z/OS, SQL Server, Sybase, Teradata, Netezza,
MQ, JMS, BEAなど
Point
②
Point
 簡単な操作
③
– nonプログラミング。GUIによる容易な定義や操作
モニタリング機能と構成
データベース
Information
Server
CDC
DB2, Oracle,
Microsoft SQL
Server等
31
データベース
ログ
ソース側エンジン
TCP/IP
CDC
ターゲット側エンジン
DataStage
メッセージ・
キュー
フラット・
ファイル
© 2013 IBM Corporation
SQL*Loaderの移行
 データを取り込むためのツール
 DB2では、従来から、LOAD, IMPORTユーティリティを提供
– LOAD
• データベース・コンテナー(ストレージ)に、フォーマット済みページを直接書き
込む(処理が高速なので大量のデータ挿入に向いている)
• 参照整合性制約等のチェックは、別途、SET INTEGRITYコマンドを発行する必要が
ある(それまでロードした表にアクセスできない)
• トリガーは起動しない、等の制約がある
– IMPORT
• INSERT文で実現
• 尐量のデータ挿入に向いている
– 参照URL
• http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.dm.doc/doc/r0004639.html
 DB2 10 から、さらに、INGESTユーティリティを提供
– INGESTコマンド処理中も、アプリケーションからのデータ・アクセスが可能
– INSERT/REPLACEの他に、UPDATE/DELETE/MERGEが可能(簡易ETL処理が可能)
– 再開可能なエラー発生時、最後にコミットした時点から再開が可能
– 継続的なデータ挿入や、簡単なETL処理を行いたい場合に向いている
– 参照URL
• http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.dm.doc/doc/c0057237.html
32
© 2013 IBM Corporation
OracleのSQL*LoaderとDB2のLOAD
• SQL*Loader のコントロール・ファイル
• 固定長フォーマットをロードするコントロールファイルの例
• 固定長フォーマットの場合、POSITION() 指定を METHOD Lを用いた
指定に変更する
Oracle SQL*Loader コントロールファイル
LOAD DATA
INFILE '/home/ora_usr/accounts.dat'
INTO TABLE accounts
( acct_id POSITION(0001:0003) NUMBER
,dept_code POSITION(0004:0006) CHAR
,acct_desc POSITION(0009:0100) VARCHAR2
,max_employees POSITION(0101:0103) NUMBER
,current_employees POSITION(0104:0106) NUMBER
,num_projects POSITION(0107:0107) NUMBER )
33
DB2 Load コマンド
LOAD FROM
'/home/ora_usr/accounts.dat'
OF ASC
METHOD L
( 0001 0003
,0004 0006
,0009 0100
,0101 0103
,0104 0106 )
INSERT INTO accounts
( acct_id
,dept_code
,acct_desc
,max_employees
,current_employees );
© 2013 IBM Corporation
OracleのSQL*LoaderとDB2のLOAD
• 可変長データの場合のコントロールファイル
• 可変長データの場合のコマンド比較
ロードするデータファイル (accounts.dat)
101,"ACT","Major Bank Co.",30,11,4
301,"ACT","Large Telco Inc.",30,0,4
101,"IT","Huge Software Co.",50,0,4
203,"MKT","Basic Insurance Co.",15,0,3
Oracle SQL*Loader コントロールファイル
INFILE '/home/ora_usr/accounts.dat'
INTO TABLE accounts
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED
BY '"'
( acct_id
,dept_code
,acct_desc
,max_employees
,current_employees
,num_projects )
34
DB2 Load コマンド
LOAD FROM
'/home/ora_usr/accounts.dat'
OF DEL
MODIFIED BY CHARDEL"" COLDEL,
METHOD P (1, 2, 3, 4, 5 )
INSERT INTO accounts
( acct_id
,dept_code
,acct_desc
,max_employees
,current_employees );
© 2013 IBM Corporation
INGESTユーティリティ
 シンプルなETL (Extract, Transform, Load) が実現可能
– 例1: 基本的なシンタックス
INGEST FROM FILE my_file.txt FORMAT DELIMITED INSERT INTO my_table;
– 例2: 固定長データの取り込み
INGEST FROM FILE my_file.txt FORMAT POSITIONAL(
$field1 POSITION(1:8) INTEGER EXTERNAL,
$field2 POSITION(10:19) DATE ’yyyy-mm-dd’,
$field3 POSITION(25:34) CHAR(10))
INSERT INTO my_tableVALUES($field1, $field2, $field3);
– 例3: 取り込んだデータを変換して挿入
INGEST FROM FILE my_file.txt FORMAT DELIMITED BY ‘|' (
$prod_ID CHAR(8),
$description CHAR(32),
$price DECIMAL(5,2) EXTERNAL,
$sales_tax DECIMAL(4,2) EXTERNAL,
$shipping DECIMAL(3,2) EXTERNAL )
INSERT INTO my_table(prod_ID, description, total_price)
VALUES($prod_id, $description, $price + $sales_tax + $shipping);
35
© 2013 IBM Corporation
INGESTユーティリティ
 UPDATE/MERGE/DELETE等も可能
– 例4: キーが一致するレコードの更新
INGEST FROM FILE myfile.txt FORMAT DELIMITED (
$key1 INTEGER EXTERNAL,
$key2 INTEGER EXTERNAL,
$data1 CHAR(8),
$data2 CHAR(32),
$data3 DECIMAL(5,2) EXTERNAL )
UPDATE my_table SET (data1, data2, data3) = ($data1, $data2, $data3)
WHERE (key1 = $key1) AND (key2 = $key2);
– 例5: キーが一致するレコードがあったら更新、なかったら挿入
INGEST FROM FILE myfile.txt FORMAT DELIMITED (
$key1 INTEGER EXTERNAL,
$key2 INTEGER EXTERNAL,
$data1 CHAR(8),
$data2 CHAR(32),
$data3 DECIMAL(5,2) EXTERNAL )
MERGE INTO my_table
ON (key1 = $key1) AND (key2 = $key2)
WHEN MATCHED THEN UPDATE SET (data1, data2, data3) = ($data1, $data2,
$data3)
WHEN NOT MATCHED THEN INSERT VALUES($key1, $key2, $data1, $data2, $data3);
36
© 2013 IBM Corporation
INGESTユーティリティ(リカバリー機能)
• エラー時の処理
o 事前にリスタート表を作成
db2 "CALL SYSPROC.SYSINSTALLOBJECTS('INGEST', 'C', NULL, NULL)"
o 以下のコマンドが失敗したら。。。
INGEST FROM FILE my_file.txt FORMAT DELIMITED (
$field1 INTEGER EXTERNAL,
$field2 DATE 'mm/dd/yyyy',
$field3 CHAR(32) )
このDB内でユニークな名前を付ける
RESTART NEW 'ingestjob001'
INSERT INTO my_table VALUES($field1, $field2, $field3);
o 次のコマンドで再開可能(CONTINUEの代わりにTERMINATEで再開中止)
INGEST FROM FILE my_file.txt FORMAT DELIMITED (
$field1 INTEGER EXTERNAL,
$field2 DATE 'mm/dd/yyyy',
$field3 CHAR(32) )
RESTART CONTINUE 'ingestjob001'
INSERT INTO my_table VALUES($field1, $field2, $field3);
37
© 2013 IBM Corporation
INGESTユーティリティ
 アーキテクチャー
– 3つのフェーズから構成
• Transporter, Formatter, Flusher
• マルチスレッドによる並列処理(Formatter, FlusherはINGEST SETコマンドで
スレッド数指定)
– DPF最適化
• データが保存されるパーティションに直接データを投入
 その他の機能
– 処理状況を表示するモニターコマンド (INGEST LIST, INGEST GET STATS)
– コミットのタイミング等、各種設定 (INGEST SET)
Transporter
Formatter
Formatter
1つまたは複数の
ファイル/パイプ
Flusher
Flusher
Formatter
Transporter
Formatter
SQL
SQL
SQL
DB2
Flusher
マルチスレッド・モデル(1つのINGESTコマンド単位)
38
© 2013 IBM Corporation
移行ロードマップ
39
© 2013 IBM Corporation
移行ロードマップ
アセスメント
& PoC
データベース
移行
アプリケーション
移行
機能検証
1. アセスメント & PoC
– 移行対象となる環境についての調査・理解
ツール
正確
– 移行ポイントと作業量の見積もり
• 主に机上による変更点の洗い出し(ポーティング・アセスメント)
• オプション:一部分を実際に移行して検証(PoC: Proof of Concept)
2. データベース移行
– データベース・オブジェクト(表やPL/SQLなど)の移行
– データの移行
3. アプリケーション移行
– アプリケーションを DB2 用に移行
4. 機能検証
– 一連のテストを実施
40
ツール
迅速
自動化
最小限の変更
テスト
© 2013 IBM Corporation
移行ツール
41
© 2013 IBM Corporation
新しい移行ツール: Database Conversion Workbench (DCW)
 従来のMEETツール、IDMT(IBM Data Movement Tool)ツールを統合
 IBM Data Studioにプラグイン
 2012年12月現在、DCW 1.0 がリリース
 移行ツールの利用効果
– 移行計画の精度向上
– 移行の一部自動化による移行コスト削減
42
© 2013 IBM Corporation
DCWの機能
 DCW 1.0 の主な機能
– DCW Task Launcher
• 統合ヘルプ環境。各処理手順をステップ・バイ・ステップで提供
– DDL Extraction
• OracleのデータベースからDDL定義を抽出
– Compatibility Evaluation and Code Conversion
• 互換率、非互換ポイントの提示と、一部シンタックスの自動変換
– Split DDL
• 1つのDDLファイルをオブジェクト・タイプごとに整理して分割
– Package Visualizer
• オブジェクト間の関係をグラフ表示
– Data Movement
• ソース・データベースからデータを抽出し、ターゲット・データベースに
ロード
43
© 2013 IBM Corporation
DCWを使用した移行の流れ
オブジェクト定義情報
Oracle
DDL
データ
DDL Extraction
Split DDL
Package
Visualizer
Oracle DDL
変換されたDDL
分割されたDDL
Compatibility Evaluation and
Code Conversion
Data Movement
DCW Task
Launcher
Database Conversion Workbench (DCW)
DB2 for LUW
44
© 2013 IBM Corporation
DCWプロジェクト
最初にDCWプロジェクトを作成する
45
© 2013 IBM Corporation
DCW Task Launcher
Task Launcherで処理したい内容を選択してゆくと、ウィザードが表示される
46
© 2013 IBM Corporation
DDL Extraction
以下のステップでDCWプロジェクトにDDLファイルが生成される
1. Extract DDL by creating a custom extraction script
DDLを抽出するためのスクリプトを生成して実行 (.outファイルの生成)
2. Import a DDL file
DCWプロジェクトに抽出したDDLファイル(.out)をインポート(.sqlファイルに変換される)
DDLを抽出するためのスクリプト生成
スクリプトの実行
> sqlplus user/pwd@sid @gen_ddl.sql
DDLファイルのインポート
47
© 2013 IBM Corporation
Compatibility Evaluation and Code Conversion (1/2)
互換率、非互換ポイントの提示と、一部シンタックスの自動変換
自動変換されたDDL、PL/SQL
(一部手動変換)
互換率、非互換ポイントの暗号化されたレポート
([email protected] に暗号解除依頼のメール送付)
48
© 2013 IBM Corporation
Compatibility Evaluation and Code Conversion (2/2)
暗号解除されたレポート
49
© 2013 IBM Corporation
Split DDL
1つのDDLファイルをオブジェクト・タイプごとに整理して分割
50
© 2013 IBM Corporation
Package Visualizer (1/2)
オブジェクト間の関係をグラフ表示
① 以下の設定を事前に行う
• Database connected modeをチェック(データベースに接続して情報を取得)
• Database configuration(データベース接続設定)
Offline mode はDCW1.0では未サポート
② DB Objects Explorerビューを表示
51
© 2013 IBM Corporation
Package Visualizer (2/2)
③ DB Objects Explorerビューで、参照したいオブジェクトをダブルクリック
52
© 2013 IBM Corporation
Data Movement (1/3)
事前にターゲット・データベースにDDLを登録しておき、ソース・データベースからデータを
抽出し、ターゲット・データベースにロード
① ターゲット・データベースにDDLを登録
53
© 2013 IBM Corporation
Data Movement (2/3)
② ソース・データベースのデータをフラット・ファイルに抽出、または、
パイプ経由で直接ターゲット・データベースにロード
54
© 2013 IBM Corporation
Data Movement (3/3)
③ソース・データベースのデータをフラット・ファイルに抽出した場合、
フラット・ファイルのデータをターゲット・データベースにロード
55
© 2013 IBM Corporation
Oracleからの移行ポイント
※ 主な移行ポイントについて述べており、すべての移行ポイントを網羅
している訳ではありません
※ また、Oracle互換フィーチャーの使用 (DB2_COMPATIBILITY_VECTOR=ORA)
を前提としています
56
© 2013 IBM Corporation
CREATE TABLEのPCTFREEオプション
 PCTFREEは、データの更新時にサイズが増えることを考慮し、挿入時に空きスペースを
あらかじめ確保しておくために利用する
 DB2では、ALTER TABLE文でPCTFREEの値をセットしてから、データをロードするか、
データの再編成(reorg)を行う
–例
alter table t1 pctfree 10;
load from data.del of del insert into t1;
set integrity for t1 immediate checked;
(※) set integrity コマンドは、参照整合性制約等のチェックが必要な場合発行する
57
© 2013 IBM Corporation
Oracleのファンクション索引の移行
 Oracleのファンクション索引の移行のポイント
– ファンクション索引に利用しているファンクションの結果を格納する列を表に追加する
– 追加する列のデータ・タイプはファンクションの戻りのデータ・タイプに合わせる
– ファンクション索引の代わりに、追加した列に対して索引を作成する
– generated always as を用い、データの挿入/変更時に自動更新されるようにする
– implicitly hiddenを指定して列を隠してもよい
• 隠してもSELECT文で明示的に列名を指定すると参照可能
• 隠さないとINSERT文で各列名を明示的に指定しないとデータが挿入できなくなる
– ファンクションを利用して参照するSQL文の修正は不要(DB2が自動的に索引を選択)
 例:
– SUBSTR2(C2, 2, 3)で検索する場合
• select .. from … where SUBSTR2(C2, 2, 3)='xxx'
– 表作成時に定義する場合
• create table [表名] (…, c2 varchar(20), c2_substr varchar(3) generated always as
(substr2(c2, 2, 3)) implicitly hidden);
• 上記、追加する列名を C2_SUBSTR としたが、他の列名と異なるなら何でもよい
– 表が定義されており、列を追加する場合(以下の3つのステップを実行する)
• set integrity for [表名] off;
• alter table [表名] add column c2_substr varchar(3) generated always as (substr2(c2,
2, 3)) implicitly hidden;
• set integrity for [表名] immediate checked force generated;
– 列名を表に追加したら、その列に索引を作成する
• create index xxx on [表名] (c2_substr);
58
© 2013 IBM Corporation
VIEW定義内でのORDER BYの使用
 VIEW定義内で ORDER BY を使用している場合、以下のように変換する
– Oracle
create view v1 as select … from t1 … order by c1
– DB2
create view v1 as select * from (select … from t1 … order by c1)
59
© 2013 IBM Corporation
ORDER BY xx ASC|DESC NULLS FIRST|LAST
 ORDER BYでNULLの扱いを指定している場合、以下のように変換する
– Oracle
select … from t1 … order by c1 nulls first
– DB2
select … from t1 … order by row_number() over (order by c1 nulls
first)
• DESC NULLS LAST等も同様に動作
60
© 2013 IBM Corporation
SELECT文の FOR UPDATE の移行
 Oracle で SELECT文に FOR UPDATE を付加している場合
– DB2では WITH RS を付ける。複数の表が対象の場合は、WITH RS USE AND KEEP
UPDATE LOCKS に変換する
– Oracle
select … from t1 where … for update;
– DB2
select … from t1 where … for update with rs;
select … from t1, t2 where … with rs use and keep update locks;
61
© 2013 IBM Corporation
SELECT文の NOWAIT の移行
 Oracleで SELECT文に NOWAIT を付加している場合
– DB2ではSELECT文の前に TIMEOUT設定を変える "SET CURRENT LOCK TIMEOUT"
ステートメントを発行し、SELECT文の発行後に、設定を元に戻す
– Oracle
select … from t1 where … for update nowait;
– DB2
set current lock timeout not wait;
select … from t1 where … for update with rs;
set current lock timeout null;
※ set 文は、発行したセッションでのみ設定が変更されるので、
他のセッションへの影響なし
 タイムアウト時の動作
– タイムアウトすると、トランザクションがロールバックされる(デフォルトの動作)
– 発行したSELECT文のみエラーとする場合、以下の設定を行う
db2set DB2LOCK_TO_RB=STATEMENT
※ DB2インスタンス・レベルでの設定となるため、影響範囲がインスタンス全体に渡る
62
© 2013 IBM Corporation
DB2のロック・タイムアウト設定
 デフォルトは、DB構成パラメーター LOCKTIMEOUT の値が使用される
$ db2 get db cfg for [DB名]
…
ロック・タイムアウト (秒)
…
(LOCKTIMEOUT) = -1
※ -1 はデフォルトでロック・タイムアウトなし
 SET CURRENT LOCK TIMEOUT ステートメントには、待ち時間をセットすることも可能
 参照URL: SET CURRENT TIMEOUT
– http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0011874.html
63
© 2013 IBM Corporation
LENGTH / LENGTHB 関数の移行
 OracleのLENGTH/LENGTHB関数の仕様
Oracleの関数名
仕様
LENGTH('文字列')
文字列の文字数を返す
LENGTHB('文字列')
文字列のバイト数を返す
 DB2への移行時、以下のように変換する
64
Oracleの関数名
DB2の関数名
LENGTH('文字列')
LENGTH('文字列', CODEUNITS32)
LENGTHB('文字列')
LENGTH('文字列') または
LENGTH('文字列', OCTETS)
© 2013 IBM Corporation
SUBSTR / INSTR 関数の移行
 DB2への移行時、以下のように変換する
Oracleの関数名
DB2の関数名
SUBSTR(…)
SUBSTR2(…) ※ または、
SUBSTRING('文字列', x, y, CODEUNITS32)
INSTR('文字列', '検索文字列')
INSTR('文字列', '検索文字列', x)
INSTR('文字列', '検索文字列', x, y)
INSTR('文字列', '検索文字列', 1, 1, CODEUNITS32)
INSTR('文字列', '検索文字列', x, 1, CODEUNITS32)
INSTR('文字列', '検索文字列', x, y, CODEUNITS32)
※ SUBSTR2(…)は、CODEUNITS16で処理 (JIS第3,4水準を使用していなければCODEUNITS16でも
問題なし)
 SUBSTRB / INSTRB 関数はOracleと同じなので、変換不要
65
© 2013 IBM Corporation
TO_CHAR 関数の移行
 数値、日付等を文字列の指定の書式にフォーマットする
 数値フォーマットのFM等、異なる点があるので確認が必要(FMは以下のように変換する)
例
– Oracleの例
結果
OracleのTO_CHAR
TO_CHAR(-1234.56, '9,999,999.99')
'
-1,234.56'
TO_CHAR(-1234.56, 'FM9,999,999.99')
'-1,234.56'
– DB2の例(最初の例はOracleと同じなので変換不要)
結果
DB2のTO_CHAR
TO_CHAR(-1234.56, '9,999,999.99')
'
-1,234.56'
TRIM(TO_CHAR(-1234.56, '9,999,999.99'))
'-1,234.56'
 参照URL: VARCHAR_FORMAT関数 (= TO_CHAR関数)
– http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0007110.html
66
© 2013 IBM Corporation
SYSTIMESTAMPの移行
 OracleのSYSTIMESTAMPは、CURRENT TIMESTAMPに置き換える
– Oracleの使用例
select TO_CHAR(SYSTIMESTAMP, 'YYYY/MM/DD HH24:MI:SS') from
dual;
– DB2への変換
select TO_CHAR(CURRENT TIMESTAMP, 'YYYY/MM/DD HH24:MI:SS')
from dual;
 SYSDATEはDB2でも使用可能 (CURRENT DATE と同じ)
67
© 2013 IBM Corporation
DBMS_APPLICATION_INFO および V$SESSION の移行(1/2)
 クライアント情報を付加して、セッション(アプリケーション)情報と関連付ける
 DB2では、以下の情報を付加できる
– ApplicationName, ClientAccountingInformation, ClientHostname, ClientUser
 Javaでの付加
– ConnectionオブジェクトのsetClientInfoメソッドの利用
DataSource ds = (DataSource)ctx.lookup("java:/comp/env/jdbc/xxx");
Connection con = ds.getConnection();
con.setClientInfo("ClientUser", "User1");
con.setClientInfo("ApplicationName", "My Java Application1");
– 参照URL
• http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.apdv.java.doc/src/tpc/imjcc_t0052428.html
 プロシージャーでの付加
– WLM_SET_CLIENT_INFOプロシージャーの利用
db2 => call WLM_SET_CLIENT_INFO('User2', null, 'My CLP2', null, null);
リターン状況 = 0
– 参照URL
• http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.rtn.doc/doc/r0053116.html
68
© 2013 IBM Corporation
DBMS_APPLICATION_INFO および V$SESSION の移行(2/2)
 アプリケーション情報の取得
– SYSIBMADM.SNAPAPPL_INFO管理ビューの利用
db2 => select agent_id,
substr(appl_name,1,20) appl_name,
substr(appl_id,1,30) appl_id,
substr(tpmon_client_userid,1,10) tpmon_client_userid,
substr(tpmon_client_app,1,25) tpmon_client_app
from sysibmadm.snapappl_info;
AGENT_ID APPL_NAME
APP
-------- ------------------------------344 db2bp.exe
311 db2bp.exe
317 db2fw1
323 db2jcc_application
cation1
316 db2fw0
...
APPL_ID
TPMON_CLIENT_USERID TPMON_CLIENT_
------------------------------ ------------------- ------------*LOCAL.DB2.120911234210
*LOCAL.DB2.120911232102
*LOCAL.DB2.120911232110
127.0.0.1.50469.120911232312
User2
User1
My CLP2
My Java Appli
*LOCAL.DB2.120911232109
-
-
db2 => list application;
Auth Id
Application
Name
-------- -------------MOHKAWA db2bp.exe
MOHKAWA db2bp.exe
MOHKAWA db2jcc_applica
69
Appl.
Handle
---------344
311
323
Application Id
DB
# of
Name
Agents
---------------------------------------- -------- ----*LOCAL.DB2.120911234210
SAMPLE
1
*LOCAL.DB2.120911232102
SAMPLE
1
127.0.0.1.50469.120911232312
SAMPLE
1
© 2013 IBM Corporation
PL/SQL: ブロック内での型宣言
 DB2 10 で対応されたので変換の必要なし
(DB2 9.7 までは PL/SQL のパッケージ定義で宣言)
例:
– Oracle & DB2
create or replace function func1(i in number) return varchar2
is
type type1 is record (
c1 number,
c2 varchar2(10));
type arr_type1 is table of type1 index by binary_integer;
type arr_type2 is varray(5) of varchar(10);
t1_arr arr_type1;
t2_arr arr_type2;
begin
t1_arr(1).c1 := i;
t1_arr(1).c2 := 'hello';
t1_arr(2).c1 := i + 1;
t1_arr(2).c2 := 'ciao';
t2_arr(1) := 'cava';
t2_arr(2) := 'ola';
return t1_arr(1).c2 || t1_arr(1).c1 || ', ' || t1_arr(2).c2
|| t1_arr(2).c1 || ', ' || t2_arr(1) || ', ' || t2_arr(2);
end;
70
© 2013 IBM Corporation
PL/SQL: ブロック内でのFUNCTION宣言
 ブロック内でのFUNCTION宣言は、PROCEDURE宣言に書き換える
(DB2 10で対応。DB2 9.7 までは PL/SQL のパッケージに変換)
例:
– Oracle
create or replace function func1(i in number) return number is
function sub1 (j in number) return number is
begin
return j + 100;
end;
begin
return sub1(i);
end;
– DB2
create or replace function func1(i in number) return number is
i2 number;
procedure sub1 (j in number, j2 out number) is
begin
j2 := j + 100;
end;
begin
sub1(i, i2);
return i2;
end;
71
© 2013 IBM Corporation
PL/SQL: CURSORの宣言
 Oracleでは、CURSOR定義内で、そのFUNCTION/PROCEDUREで宣言したパラメータが
使用可能
FUNCTION xxx(…) RETURN xxx IS
p1 VARCHAR2;
…
CURSOR c1(a1 VARCHAR2, a2 VARCHAR2) IS
SELECT … FROM … WHERE xxx = p1 and yyy = a1 and zzz = a2;
…
 DB2
– DB2の場合、CURSOR定義内で使用できる変数は、そこに渡された引数のみ
– 上記の場合、p1 変数を使用することはできない。以下のようなエラーとなる
• SQL0206N 使用されているコンテキストで、"P1"は無効です。
– p1 変数も使用する場合、以下のように、引数として渡す
FUNCTION xxx(…) RETURN xxx IS
p1 VARCHAR2;
…
CURSOR c1(a1 VARCHAR2, a2 VARCHAR2, p1 VARCHAR2) IS
SELECT … FROM … WHERE xxx = p1 and yyy = a1 and zzz = a2;
…
72
© 2013 IBM Corporation
PL/SQL: RETURNING INTOにおけるBULK COLLECTの利用
 RETURNING INTO は、DELETE/INSERT/UPDATEにより削除/挿入/更新された行を戻す
 Oracleでは、BULK COLLECTと組み合わせることで複数行を得ることができる
 DB2では、NEW TABLE関数(※)(INSERT/UPDATE時)、OLD TABLE関数(DELETE時)を利用
※ トリガー使用時、トリガー処理後のデータを得る場合、FINAL TABLE関数を利用
– Oracle
– DB2
73
declare
type t1row is record ( n number,
c varchar2(10) );
type t1row_array is varray(10) of t1row;
rows t1row_array;
begin
update t1 set c2='hello' where c1>=100
returning c1,c2 bulk collect into rows;
...
end;
declare
type t1row is record ( n number,
c varchar2(10) );
type t1row_array is varray(10) of t1row;
rows t1row_array;
begin
select c1,c2 bulk collect into rows from
new table(update t1 set c2='hello' where c1>=100);
...
end;
© 2013 IBM Corporation
PL/SQL: ROLLBACK時のCURSORの保持
 DB2ではROLLBACKするとCURSORはクローズされる(COMMITでは保持される)
 ROLLBACK後もCURSORを保持したい場合は、以下のようにSAVEPOINTを利用する
Oracle
<<cur1_loop>>
loop
fetch cur1 into x1, x2
exit when cur1%notfound;
…
rc := 0;
begin
…
exception
when … then
rc := -1;
end;
if rc != 0 then
rollback;
goto cur1_loop;
end if;
commit;
end loop cur1_loop;
close cur1;
74
DB2
<<cur1_loop>>
loop
fetch cur1 into x1, x2;
exit when cur1%notfound;
savepoint sp1 on rollback retain cursors;
…
rc := 0;
begin
…
exception
when … then
rc := -1;
end;
if rc != 0 then
rollback to savepoint sp1;
goto cur1_loop;
end if;
commit;
end loop cur1_loop;
close cur1;
© 2013 IBM Corporation
PL/SQL: DBMS_SQLパッケージ
 DEFINE_COLUMN / COLUMN_VALUE プロシージャー
– 使用するデータタイプに応じたプロシージャーに書き換える
• 例:
DBMS_SQL.DEFINE_COLUMN_VARCHAR(cur, 1, c1, 16);
DBMS_SQL.COLUMN_VALUE_VARCHAR(cur, 1, c1);
 DBMS_SQL.xxx_TABLE タイプ (例: DBMS_SQL.VARCHAR2_TABLE)
– DB2では、暗黙的に定義されていないので、使用前に以下のような定義を行う
TYPE VARCHAR2_TABLE IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
75
© 2013 IBM Corporation
JDBCの移行
 DB2 JDBCドライバーが含まれる JAR ファイルをCLASSPATH環境変数に追加
– sqllib/java ディレクトリー下にある以下のファイルのうち、1つを追加
– db2jcc4.jar(JDBC 4.0 以降の機能、および、JDBC 3.0 以前の機能をサポート)
– db2jcc.jar (JDBC 3.0 以前の機能のみサポート)
 JDBCドライバー・クラス名および接続URLの変更
– Oracle
• JDBCドライバー・クラス名: oracle.jdbc.OracleDriver
• 接続URLフォーマット(ユーザー名/パスワードなし)
jdbc:oracle:thin:@[ホスト名]:[ポート番号]:[SID]
• 接続URLフォーマット(ユーザー名/パスワード付)
jdbc:oracle:thin:[ユーザー名]/[パスワード]@[ホスト名]:[ポート番号]:[SID]
– DB2
• JDBCドライバー・クラス名: com.ibm.db2.jcc.DB2Driver
• 接続URLフォーマット(ユーザー名/パスワードなし)
jdbc:db2://[ホスト名]:[ポート番号]/[DB名]
• 接続URLフォーマット(ユーザー名/パスワード付)
jdbc:db2://[ホスト名]:[ポート番号]/[DB名]:user=[ユーザー名];password=[パス
ワード];
76
© 2013 IBM Corporation
Pro*Cの移行
 SQL文をプログラムに埋め込む
 プリコンパイラーを使用して、C言語に変換
プログラム例
EXEC SQL BEGIN DECLARE SECTION;
char user[20], password[20], dbname[9];
int c1;
char c2[11];
EXEC SQL END DECLARE SECTION;
strcpy(user, "scott"); strcpy(password, "xxx"); strcpy(dbname, "orcl");
/* データベースへの接続 */
EXEC SQL CONNECT :user IDENTIFIED BY :password USING :dbname;
/* カーソル宣言 */
EXEC SQL DECLARE cur CURSOR FOR SELECT C1, C2 FROM T1;
/* カーソルのオープン */
EXEC SQL OPEN cur;
for (;;) {
/* レコードの取得(フェッチ) */
EXEC SQL FETCH cur INTO :c1, :c2;
if (sqlca.sqlcode == 1403)
break;
printf("%d %s¥n", c1, c2);
}
/* カーソルのクローズ */
EXEC SQL CLOSE cur;
/* コミットして切断 */
EXEC SQL COMMIT WORK RELEASE;
77
© 2013 IBM Corporation
Pro*Cの移行(組み込みSQL)
 DB2では組み込みSQLが、OracleのPro*Cに相当
 SQL文の実行形式
– DB2とOracleともに、1つの静的SQL(※)実行方法と、4つの動的SQL実行方法がある
(※) 静的SQLについては次ページ参照
 組み込みSQLの仕様(Pro*Cとの違い)
– データベースに接続して、プリコンパイルを行う(埋め込まれたSQL文の検証)
– プログラム実行前に、そのパッケージ(※)をデータベースにバインドしておく
– パッケージ(※)のバインド
• 埋め込まれた静的SQL文の実行計画(アクセス・プラン)の生成と保持
• プログラム実行時は、保持されたアクセス・プランに基づいて実行
(バインド時のオプションにより、動的SQLのように扱うこともできる)
※ Oracleのパッケージとは意味が違うので要注意
 互換フィーチャー
– プリコンパイル・オプション COMPATIBILITY_MODE ORA をセットする
 典型的なプリコンパイル・シンタックス
prep prog1.sqc bindfile package using prog1 compatibility_mode ora
 参照URL: 移行の互換フィーチャーの使用可能化
– http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.apdv.embed.doc/doc/c0059083.html
78
© 2013 IBM Corporation
組み込みSQLプログラムと静的SQL
 静的SQLはSQL文を直接プログラムに書く(動的SQLは変数にSQL文をセットする)
 DB2の静的SQL
– バインド、またはリバインドした時に、SQL文の実行計画(アクセス・プラン)が生成
され、データベースに作成されたパッケージ・オブジェクトに保持される
– 実行時は、パッケージに保存されているアクセス・プランに従って実行される
• アクセス・プランを動的に作成する必要なし
 組み込みSQLプログラム開発・実行の流れ(C言語用の場合)
組み込みSQLプログラム(xxx.sqc)
プリコンパイル(DB2 PRECOMIILE …)
C言語用プログラム(xxx.c)
バインド・ファイル(xxx.bnd)
コンパイル
バインド
リバインド
静的SQLのアクセス・プランの生成・再生成
実行形式プログラム
パッケージ
(静的SQLのアクセス・
プランを含む)
79
© 2013 IBM Corporation
組み込みSQLプログラムにおけるマクロ
 マクロの使用(例: #ifdefの使用, 配列の要素数をラベルで定義)
– DB2もOracleもサポート
– DB2は別のコンパイラのプリプロセッサを利用(オプションで指定)
prep prog1.sqc bindfile package using prog1
preprocessor "xlC -P -DDB2=1" COMPATIBILITY_MODE ORA
※ AIXのコンパイラ xlC を使用した場合の例
マクロ使用例(含エラーメッセージ取得APIの違い)
#ifdef ORA
sqlglm(emsg, &buf_len, &emsg_len);
printf("%.*s¥n", emsg_len, emsg);
#elif DB2
sqlaintp(emsg, sizeof(emsg), 0, &sqlca);
printf("%s¥n", emsg);
#endif
80
© 2013 IBM Corporation
Pro*Cプログラム
 DB2の組み込みSQLプログラムに移行
 SQLの実行形式
– 静的SQL:DB2とOracleでほぼ同じ
 例



EXEC SQL DECLARE cur CURSOR FOR SELECT C1, C2 FROM T1;
EXEC SQL OPEN cur;
EXEC SQL FETCH cur INTO :c1, :c2;

EXEC SQL EXECUTE IMMEDIATE :sql;


EXEC SQL PREPARE stmt FROM :sql;
EXEC SQL EXECUTE stmt USING :p1, :p2;




EXEC SQL PREPARE stmt FROM :sql;
EXEC SQL DECLARE cur CURSOR FOR stmt;
EXEC SQL OPEN cur USING :p1, :p2;
EXEC SQL FETCH cur INTO :c1, :c2;
– 動的SQL
• 方法1: DB2とOracleでほぼ同じ
 SQL文の実行
• 方法2: DB2とOracleでほぼ同じ
 SQL文の実行(入力ホスト変数をセット可能)
• 方法3: DB2とOracleでほぼ同じ
 SQL文の実行(入力ホスト変数をセット可能、結果列の値を取得可能)
• 方法4:
 入力ホスト変数の数、結果の列数等が動的に構成可能
 指定はSQLDA構造体を使用。SQLDA構造体がDB2とOracleで違う
81
© 2013 IBM Corporation
Pro*C: プログラムの変換例
プリコンパイラーオプション COMPATIBILITY_MODE ORA で対応
プログラム例
…
/* データベースへの接続 */
EXEC SQL CONNECT :user IDENTIFIED BY :password USING :dbname;
/* カーソル宣言 */
EXEC SQL DECLARE cur CURSOR FOR SELECT C1, C2 FROM T1;
/* カーソルのオープン */
DB2本来のシンタックスは、
EXEC SQL OPEN cur;
EXEC SQL CONNECT TO :dbname USER :user USING :password;
for (;;) {
/* レコードの取得(フェッチ) */
EXEC SQL FETCH cur INTO :c1, :c2;
#ifdef ORA
if (sqlca.sqlcode == 1403) {
#elif DB2
if (sqlca.sqlcode == 100) {
#endif
break;
}
printf("%d %s¥n", c1, c2);
}
この例では、2箇所の書き換えが必要
/* カーソルのクローズ */
EXEC SQL CLOSE cur;
/* コミットして切断 */
#ifdef ORA
EXEC SQL COMMIT WORK RELEASE;
#elif DB2
EXEC SQL COMMIT;
EXEC SQL CONNECT RESET;
#endif
82
© 2013 IBM Corporation
Pro*C: VARCHAR構造体について(char型の利用との違い)(1/2)
 VARCHAR param[x] は、Oracle互換モードで、以下の構造体に変換され、OracleのPro*Cプログラムが
そのまま利用できる
struct {
short len;
char arr[x];
} param;
 VARCHAR型でDB2サーバーとデータをやり取りする場合
– この変数を使用してSQL文で戻されるデータを受けると、arrに文字列の値(NULLターミネーターな
し)、lenにその長さがセットされる。
– この変数に値をセットしてDB2サーバーとやり取りする場合も、上記のようにセットする。
 char型でDB2サーバーとデータをやり取りする場合
– char型の変数を使用してSQL文で戻されるデータを受けると、文字列の値をNULLターミネーター付
きでセットする。
• NULLターミネーターがセットされるため、1バイト余計に変数の領域を確保する
 例(T1表の定義: create table t1 (c1 int, c2 varchar2(10)))
83
int c1;
VARCHAR c2_1[10];
char c2_2[10+1];
…
EXEC SQL DECLARE cur CURSOR FOR SELECT C1, C2, C2 FROM T1;
…
EXEC SQL FETCH cur INTO :c1, :c2_1, :c2_2;
NULLターミネートされない
printf("c2_1=%.*s¥n", c2_1.len, c2_1.arr);
printf("c2_2=%s¥n", c2_2);
© 2013 IBM Corporation
NULLターミネートされる
Pro*C: VARCHAR構造体について(char型の利用との違い)(2/2)
 Oracleの場合、列のデータ・タイプがVARCHAR2であっても、C言語のchar型でデータを
受信すると、値は固定長となり、足りない文字はスペースが入り、NULLターミネーターが
付く(必ず文字列の長さが列のデータ・タイプの長さとなり、NULLターミネーターが付
く)
OracleのPro*Cプログラム
char型でデータを取得すると
"hello˽˽˽˽˽"
"ciao˽˽˽˽˽˽"
Oracle
VARCHAR2(10)
'hello'
'ciao˽˽'
 DB2の場合、列のデータ・タイプがVARCHAR(VARCHAR2)なら、C言語のchar型でデータ
を受信すると、その値がそのままセットされ、NULLターミネーターが付く
DB2の組み込みSQLプログラム
char型でデータを取得すると
"hello"
"ciao˽˽"
84
DB2
VARCHAR2(10)
'hello'
'ciao˽˽'
© 2013 IBM Corporation
Pro*C: 構造体を用いたデータ取得(NULLチェック方法)
 Oracle, DB2ともに、複数の列のデータをC言語の構造体で取得することが可能
 NULLかどうかチェックするためのインジケータの指定方法が異なる
85
Oracle
DB2
EXEC SQL BEGIN DECLARE SECTION;
char user[20], password[20], dbname[9];
typedef struct {
int c1;
char c2[11];
} T1;
T1 t1;
typedef struct {
short c1;
short c2;
} T1_IND;
T1_IND t1_ind;
EXEC SQL END DECLARE SECTION;
…
EXEC SQL DECLARE cur CURSOR FOR
SELECT C1, C2 FROM T1;
…
EXEC SQL FETCH cur INTO :t1 :t1_ind;
…
if (t1_ind.c1 == -1) {
/* C1がNULLの場合の処理 */
…
}
if (t1_ind.c2 == -1) {
/* C2がNULLの場合の処理 */
…
}
EXEC SQL BEGIN DECLARE SECTION;
char user[20], password[20], dbname[9];
typedef struct {
int c1;
char c2[11];
} T1;
T1 t1;
short t1_ind[2];
EXEC SQL END DECLARE SECTION;
…
EXEC SQL DECLARE cur CURSOR FOR
SELECT C1, C2 FROM T1;
…
EXEC SQL FETCH cur INTO :t1 :t1_ind;
…
if (t1_ind[0] == -1) {
/* C1がNULLの場合の処理 */
…
}
if (t1_ind[1] == -1) {
/* C2がNULLの場合の処理 */
…
}
© 2013 IBM Corporation
Pro*C: FETCH … INTO のデータなし処理
 データなしのエラー番号が違う(Oracleの場合:1403, DB2の場合:100)
– DB2では以下のようなプログラムになる
while (1) {
EXEC SQL FETCH …;
if (sqlca.sqlcode == 100) {
break;
}
sqlca.sqlcode は SQLCODE と置き換えること
…
も可能
例:
if (SQLCODE == 100) {
 EXEC SQL WHENEVER NOT FOUND DO BREAK文で抜けることも可能
– 終了したら EXEC SQL WHENEVER NOT FOUND CONTINUE を発行する
EXEC SQL WHENEVER SQLERROR GOTO SqlErrorTerminate;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1) {
EXEC SQL FETCH …;
…
}
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL WHENEVER SQLERROR CONTINUE;
86
© 2013 IBM Corporation
Pro*C: ストアード・プロシージャー呼び出し
 DB2では、EXEC SQL CALL文で対応
 無名ブロック(begin … end) を使用する場合、動的SQLにする
 Oracleの例
– 以下のようにプロシージャーの第1,3引数を入力, 第2,4引数を出力とする
EXEC SQL EXECUTE
begin
proc1(:in1, :out1, :in2, :out2);
end;
END-EXEC;
 DB2: EXEC SQL CALL文で対応する場合
EXEC SQL CALL proc1(:in1, :out1, :in2, :out2);
 DB2: 無名ブロックを使用する場合
動的SQL内の:変数は、? としてもよい
例:
begin proc1(?, ?, ?, ?); end;
char stmt[256];
…
strcpy(stmt, "begin proc1(:in1, :out1, :in2, :out2); end;");
EXEC SQL PREPARE sql FROM :stmt;
EXEC SQL EXECUTE sql into :in1, :out1, :in2, :out2 using :in1,
:out1, :in2, out2;
引数が入力か出力かに関係なく、順に定義する
87
© 2013 IBM Corporation
© IBM Corporation 2013. All Rights Reserved.
ワークショップ、セッション、および資料は、IBMまたはセッション発表者によって準備され、それぞれ独自の見解を反映したものです。
それらは情報提供の目的のみで提供されており、いかなる参加者に対しても法律的またはその他の指導や助言を意図したものではなく、ま
たそのような結果を生むものでもありません。本プレゼンテーションに含まれている情報については、完全性と正確性を帰するよう努力し
ましたが、「現状のまま」提供され、明示または暗示にかかわらずいかなる保証も伴わないものとします。本プレゼンテーションまたはそ
の他の資料の使用によって、あるいはその他の関連によって、いかなる損害が生じた場合も、IBMは責任を負わないものとします。 本プレ
ゼンテーションに含まれている内容は、IBMまたはそのサプライヤーやライセンス交付者からいかなる保証または表明を引きだすことを意
図したものでも、IBMソフトウェアの使用を規定する適用ライセンス契約の条項を変更することを意図したものでもなく、またそのような
結果を生むものでもありません。
本プレゼンテーションでIBM製品、プログラム、またはサービスに言及していても、IBMが営業活動を行っているすべての国でそれらが使
用可能であることを暗示するものではありません。本プレゼンテーションで言及している製品リリース日付や製品機能は、市場機会または
その他の要因に基づいてIBM独自の決定権をもっていつでも変更できるものとし、いかなる方法においても将来の製品または機能が使用可
能になると確約することを意図したものではありません。本資料に含まれている内容は、参加者が開始する活動によって特定の販売、売上
高の向上、またはその他の結果が生じると述べる、または暗示することを意図したものでも、またそのような結果を生むものでもありませ
ん。
パフォーマンスは、管理された環境において標準的なIBMベンチマークを使用した測定と予測に基づいています。ユーザーが経験する実際
のスループットやパフォーマンスは、ユーザーのジョブ・ストリームにおけるマルチプログラミングの量、入出力構成、ストレージ構成、
および処理されるワークロードなどの考慮事項を含む、数多くの要因に応じて変化します。したがって、個々のユーザーがここで述べられ
ているものと同様の結果を得られると確約するものではありません。
記述されているすべてのお客様事例は、それらのお客様がどのようにIBM製品を使用したか、またそれらのお客様が達成した結果の実例と
して示されたものです。実際の環境コストおよびパフォーマンス特性は、お客様ごとに異なる場合があります。
以下は、International Business Machines Corporationの米国およびその他の国における商標。IBMの全商標のリストについては、
www.ibm.com/legal/copytrade.shtmlをご覧ください。
AIX, CICS, CICSPlex, DB2, DB2 Universal Database, i5/OS, IBM, the IBM logo, IMS, iSeries, Lotus, OMEGAMON, OS/390, Parallel Sysplex,
pureXML, Rational, RCAF, Redbooks, Sametime, Smart SOA, System i, System i5, System z , Tivoli, WebSphere, z/OS.
JavaおよびすべてのJava関連の商標およびロゴは Sun Microsystems, Inc.の米国およびその他の国における商標。
Microsoft, Windows, Windows NT および Windowsロゴは Microsoft Corporationの米国およびその他の国における商標。
Intel, Intelロゴ, Intel Inside, Intel Insideロゴ, Intel Centrino, Intel Centrinoロゴ, Celeron, Intel Xeon, Intel SpeedStep, Itanium, Pentium は
Intel Corporationまたは子会社の米国およびその他の国における商標または登録商標。
UNIXはThe Open Groupの米国およびその他の国における登録商標。
Linuxは、Linus Torvaldsの米国およびその他の国における商標。
その他の会社名、製品名およびサービス名等はそれぞれ各社の商標。
88
© 2013 IBM Corporation
Fly UP