12
[Lab 5d] DB2 でのアプリケーション 開発(組み込み SQL) 2011 年 06 月 日本アイ・ビー・エム株式会社

[Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

  • Upload
    lethu

  • View
    236

  • Download
    4

Embed Size (px)

Citation preview

Page 1: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

[Lab 5d]

DB2 でのアプリケーション

開発(組み込み SQL) 2011 年 06 月

日本アイ・ビー・エム株式会社

Page 2: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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

Page 3: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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 で稼動するように書き換え、実際に稼

動することを確認します。

Page 4: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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

Page 5: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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);

Page 6: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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'"

_作成されたパッケージのコンパイル

Page 7: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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)の変更

Page 8: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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. フェッチで、データがない場合の処理の変更

Page 9: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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 を使用します。バイン

ド・ファイルは、パッケージを削除後に再度登録する際に利用できるので、バインド・ファイルも

生成しておきます。

Page 10: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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

エラーや警告が表示されないことを確認します。

Page 11: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

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)

Page 12: [Lab 5d] DB2でのアプリケーション 開発(組み込みSQL)®Ÿ行すると10件の社員情報がリストされます。その後、EMPNOの入力が求められますので、

12

© Copyright IBM Corporation 2009 All Rights Reserved. 本書に含まれている情報は、正式なIBMのテストを受けていません。また、明記にしろ、暗黙的にしろ、なんらの保証もなしに配布され

るものです。 この情報の使用またはこれらの技術の実施は、いずれも、使用先の責任において行われるべきものであり、それらを評価し、実際に使用

する環境に統合する使用先の判断に依存しています。それぞれの項目は、ある特定の状態において正確であることがIBMによって調べら

れていますが、他のところで同じまたは同様の結果が得られる保証はありません。これらの技術を自身の環境に適用することを試みる使

用先は、自己の責任において行う必要があります。