Upload
lethu
View
236
Download
4
Embed Size (px)
Citation preview
[Lab 5d]
DB2 でのアプリケーション
開発(組み込み SQL) 2011 年 06 月
日本アイ・ビー・エム株式会社
2
Contents
CONTENTS ..........................................................................................................2
1. はじめに .........................................................................................................3
2. 内容 ...............................................................................................................3
3. DB2 組み込み SQL への移行 ..........................................................................3
3.1 準備 ..........................................................................................................4 3.2 エラー処理用プログラムに関する処理 ........................................................5 3.3 メインプログラムに関する処理 ....................................................................7 3.4 実行プログラムの生成 .............................................................................11 3.5 プログラムの実行 ....................................................................................11
3
1. はじめに
このハンズオンでは、Oracle 用組み込み SQL プログラムを DB2 で稼動するように書き換え、
実際に稼動することを確認します。
ファイルを編集する場合、vi や gedit が利用可能です。gedit は Windows のメモ帳やワードパッ
ドのように扱うことができます。
2. 内容
Oracle 用組み込み SQL プログラムは、以下の 2 つのソース・ファイルから構成されています。
lab5d_ora.pc (メインプログラム)
以下の 2 つの SQL 文を発行します。
社員情報の取得(静的 SQL)
select empno,firstnme,lastname,salary,deptname,location from
employee,department where employee.workdept=department.deptno and
rownum <= 10 order by salary desc
社員番号を入力し、該当する社員の名前と誕生日を取得(動的 SQL)
select firstnme, birthdate from employee where empno=xxx
lab5d_ora_err.pc (エラー処理用プログラム)
2 つの API が定義されています。
void SqlErrorTerminate()
エラー表示後、ロールバックし、プログラムを終了します。
void SqlErrorDisplay()
エラー表示を行います。
DB2 への変換後のソース・ファイル例として、以下の 2 つのファイルが提供されています。
lab5d_db2.sqc.hint
lab5d_db2_err.sqc.hint
3. DB2 組み込み SQL への移行
この章では、Oracle 用組み込み SQL プログラムを DB2 で稼動するように書き換え、実際に稼
動することを確認します。
4
3.1 準備
_環境の確認
このハンズオンは、db2inst1 ユーザーで行います。下記のコマンドを実行して、db2inst1 ユーザ
ーにスイッチし、DB2 インスタンスを起動してください。パスワードは「db2inst1」です。
su - db2inst1
db2start
DB2_COMPATIBILITAY_VECTOR がセットされていないことを確認してください。
db2set
存在していたら、下記のコマンドを発行して削除し、DB2 を再起動してください。
db2set DB2_COMPATIBILITY_VECTOR=
db2set
db2stop
db2start
SAMPLE データベースを使用しますので、SAMPLE データベースが作成されていることを確認
してください。
db2 list database directory
作成されていなかったら、作成してください。以下のコマンドを発行すると、SAMPLE データベー
スを作成し、サンプル用のテーブルの作成、サンプル用のデータのロードを行います。
db2sampl
_作業環境の準備
作業用ディレクトリを作成し、ソースコードをコピーします。
cd $HOME/sqllib
mkdir lab5d
cd lab5d
cp /workshop/lab5d/* . ← アスタリスク(*)とピリオド(.)の間にスペースが入ります
Oracle 用組み込み SQL プログラムを DB2 用にコピーします。
cp lab5d_ora.pc lab5d_db2.sqc
cp lab5d_ora_err.pc lab5d_db2_err.sqc
5
3.2 エラー処理用プログラムに関する処理
_エラー処理プログラムの書き換え
1. インクルード・ファイル等の書き換え
<sqlcpr.h> を <sql.h> に書き換えます。
#define SQLCA_STORAGE_CLASS extern を削除し、<sqlca.h>のインクルードの後に、
extern struct sqlca sqlca; を付加します(メインプログラムで宣言される sqlca を参照します)。
/* #include <sqlcpr.h> */
#include <sql.h>
/* #define SQLCA_STORAGE_CLASS extern */
#include <sqlca.h>
extern struct sqlca sqlca;
2. ロールバックして切断処理(EXEC SQL ROLLBACK WORK RELEASE)の変更
void SqlErrorTerminate()
{
…
/* 切断 */
/* EXEC SQL ROLLBACK WORK RELEASE; */
EXEC SQL ROLLBACK;
EXEC SQL CONNECT RESET;
…
}
3. エラーメッセージ取得処理の変更
Oracle の sqlglm() API に相当する DB2 の API は sqlaintp() ですが、ここでは、さらに
sqlogstt() をコールし、SQLSTATE メッセージも取得してみます。
void SqlErrorDisplay()
{
EXEC SQL WHENEVER SQLERROR CONTINUE;
char emsg[128]; /* エラーメッセージ */
int buf_len = sizeof(emsg);
int emsg_len;
/* エラーメッセージの取得 */
/*
* sqlglm(emsg, &buf_len, &emsg_len);
6
* printf("%.*s\n", emsg_len, emsg);
*/
sqlaintp(emsg, sizeof(emsg), 0, &sqlca);
printf("%s\n", emsg);
sqlogstt(emsg, sizeof(emsg), 0, sqlca.sqlstate);
printf("%s\n", emsg);
/* エラーコードの表示 */
printf("SQLCODE(%d)\n", sqlca.sqlcode);
return;
}
_エラー処理プログラムのプリコンパイル
プリコンパイルします。ファイル名が 8 文字より多いので、package using を使用します。バイン
ド・ファイルは、パッケージを削除後に再度登録する際に利用できるので、バインド・ファイルも
生成しておきます。
db2 connect to sample
db2 prep lab5d_db2_err.sqc bindfile package using lab5d_db2_err
プリコンパイルでは、以下のようにエラーや警告がないことを確認します。また、C 言語のソー
ス・ファイル lab5d_db2_err.c 、および、バインド・ファイル lab5d_db2_err.bnd が作成されたことを
確認します。
LINE MESSAGES FOR lab5d_db2_err.sqc
------ --------------------------------------------------------------------
SQL0060W "C" プリコンパイラーが 処理中です。
SQL0091W プリコンパイルまたはバインドが、
"0" エラーと "0" 警告で終了しました。
_作成されたパッケージの確認
以下のコマンドを発行して、作成されたパッケージを確認します。
db2 list packages
パッケージ名が 8 文字までしか表示されないので、以下の SQL 文で再度確認してみます。
db2 "select pkgname from syscat.packages where pkgschema='DB2INST1'"
_作成されたパッケージのコンパイル
7
以下のコマンドを発行して、プリコンパイルで生成された C 言語のソース・ファイルをコンパイル
します。
gcc -c lab5d_db2_err.c -I$HOME/sqllib/include
エラーや警告が表示されないことを確認します。
3.3 メインプログラムに関する処理
_メインプログラムの書き換え
1. インクルード・ファイルの書き換え
<sqlcpr.h> を <sql.h> に書き換えます。
/* #include <sqlcpr.h> */
#include <sql.h>
EXEC SQL INCLUDE SQLCA;
2. エラー処理用 API 呼び出しの変更
以下の Oracle 用シンタックスを変更します。
EXEC SQL WHENEVER SQLERROR DO SqlErrorTerminate();
DB2 では、GOTO 文を使用します。関数の最後にラベル SqlErrorTerminate: を定義し、そこ
から SqlErrorTerminate() をコールするようにします。
/* EXEC SQL WHENEVER SQLERROR DO SqlErrorTerminate(); */
EXEC SQL WHENEVER SQLERROR GOTO SqlErrorTerminate;
…
exit(0);
SqlErrorTerminate:
SqlErrorTerminate();
}
3. コミットして切断処理(EXEC SQL COMMIT WORK RELEASE)の変更
8
…
/* 切断 */
/* EXEC SQL COMMIT WORK RELEASE; */
EXEC SQL COMMIT;
EXEC SQL CONNECT RESET;
exit(0);
4. VARCHAR 型の変更
VARCHAR 型を以下のように変更します。
…
/* VARCHAR last_name[15]; */
struct {
short length;
char data[15];
} last_name;
上記の変更に伴い、printf()の該当する箇所を変更します。
…
/* printf("%s, %s, %.*s, ", empno, first_name, last_name.len, last_name.arr); */
printf("%s, %s, %.*s, ", empno, first_name, last_name.length, last_name.data);
5. DB 接続のロジックを変更します。
…
/* 接続準備 */
strcpy(user, "db2inst1");
strcpy(password, "db2inst1");
strcpy(dbname, "sample");
…
/* 接続 */
/* EXEC SQL CONNECT :user IDENTIFIED BY :password USING :dbname; */
EXEC SQL CONNECT TO :dbname USER :user USING :password;
6. フェッチで、データがない場合の処理の変更
9
Oracle の以下の処理は、DB2 で GOTO 文を指定することで実現可能ですが、ここでは、
SQL 文実行後の SQLCODE を直接チェックするロジックを挿入してみます。
EXEC SQL WHENEVER NOT FOUND DO break;
上記をコメントアウトし、SQL 文発行後に SQLCODE をチェックする以下のロジックを挿入し
ます。
…
/* EXEC SQL WHENEVER NOT FOUND DO break; */
for (;;) {
/* FETCH */
EXEC SQL FETCH cur INTO …;
if (SQLCODE == 100) {
break;
}
…
2 番目の SQL 文の実行後は、SQLCODE を直接チェックしています。Oracle では、デフォル
トでは、SQLCODE が 1403 の場合、データがないことを意味します。DB2 では、デフォルトで
は 100 となりますので、この値を変更します。
…
EXEC SQL FETCH cur2 INTO …;
/* if (sqlca.sqlcode == 1403) { */
if (sqlca.sqlcode == 100) {
…
7. パラメーター・マーカーの変更
…
/* strcpy(stmt, "select firstnme, birthdate from employee where empno=:p1"); */
strcpy(stmt, "select firstnme, birthdate from employee where empno=?");
…
_エラー処理プログラムのプリコンパイル
プリコンパイルします。ファイル名が 8 文字より多いので、package using を使用します。バイン
ド・ファイルは、パッケージを削除後に再度登録する際に利用できるので、バインド・ファイルも
生成しておきます。
10
db2 connect to sample
db2 prep lab5d_db2.sqc bindfile package using lab5d_db2
結果として、複数のエラーが表示されています。最初に表示されているエラーは以下になりま
す。
SQL0206N 使用されているコンテキストで、"ROWNUM" は無効です。 SQLSTATE=42703
これは、DB2 互換フィーチャーで、ROWNUM の使用が無効になっているためです。このように、
静的 SQL のシンタックスは、プリコンパイル時にチェックされます。
以下のコマンドを発行して、有効にします。
db2set DB2_COMPATIBILITY_VECTOR=ORA
db2set
db2 terminate
db2top
db2start
再度、プリコンパイルしてみます。プリコンパイルでは、エラーがなくなったことを確認します。ま
た、C 言語のソース・ファイル lab5d_db2.c 、および、バインド・ファイル lab5d_db2.bnd が作成さ
れたことを確認します。
_作成されたパッケージの確認
以下のコマンドを発行して、作成されたパッケージを確認します。
db2 list packages
上記のコマンドで登録されているパッケージが 1 つ増えたことがわかりますが、パッケージ名
が 8 文字までしか表示されないので、以下の SQL 文で再度確認してみます。
db2 "select pkgname from syscat.packages where pkgschema='DB2INST1'"
_作成されたパッケージのコンパイル
以下のコマンドを発行して、プリコンパイルで生成された C 言語のソース・ファイルをコンパイル
します。
gcc -c lab5d_db2.c -I$HOME/sqllib/include
エラーや警告が表示されないことを確認します。
11
3.4 実行プログラムの生成
_実行プログラムの生成
作成された 2 つのオブジェクト・ファイルをリンクして、実行プログラムを生成します。以下のコ
マンドを入力します。
gcc -o lab5d_db2 lab5d_db2.o lab5d_db2_err.o -L$HOME/sqllib/lib32 -ldb2
エラーや警告が表示されないことを確認します。
3.5 プログラムの実行
_プログラムの実行準備
プログラムの実行は、あらかじめ DB2 に接続しておく必要はありません。以下のコマンドを入
力し、DB との接続を切断します。
db2 terminate
_プログラムの実行
作成したプログラムを実行します。
./lab5d_db2
実行すると 10 件の社員情報がリストされます。その後、EMPNO の入力が求められますので、
上記のリストに存在する、最初の列に表示されている 6 桁の数字を入力してください。そうする
と、該当する社員の名前と誕生日が表示されます。
入力した EMPNO に該当するレコードがない場合(6 桁に満たない数字を入力したり、数字以
外の文字を入力するなど)、存在しないといったメッセージが表示されます。
_エラー処理の確認
DB2 を停止して、プログラムを実行します。
db2stop
./lab5d_db2
そうすると、以下のエラーメッセージが表示されます。
SQL1032N start database manager コマンドが発行されていません。 SQLSTATE=57019
SQLSTATE 57019: リソースに問題があるため、ステートメントが失敗しました。
SQLCODE(-1032)
12
© Copyright IBM Corporation 2009 All Rights Reserved. 本書に含まれている情報は、正式なIBMのテストを受けていません。また、明記にしろ、暗黙的にしろ、なんらの保証もなしに配布され
るものです。 この情報の使用またはこれらの技術の実施は、いずれも、使用先の責任において行われるべきものであり、それらを評価し、実際に使用
する環境に統合する使用先の判断に依存しています。それぞれの項目は、ある特定の状態において正確であることがIBMによって調べら
れていますが、他のところで同じまたは同様の結果が得られる保証はありません。これらの技術を自身の環境に適用することを試みる使
用先は、自己の責任において行う必要があります。