前回の復習
「第四回データベース – SQL(照会プログラム)」では、FFRPG のデータベース・プログラミングの手法として、データベース操作の共通言語 SQL を FFRPG に組み込んで実行する方法を解説しました。多くのサンプル・プログラムを通して、基本的な照会から、フィールドの多いテーブルに対するデータ構造を使用した効果的なアクセスまで、プログラムの作成を通して理解していただけたと思います。 データベース処理は照会の他に、更新、削除および追加も必要になります。今回は、これらの処理を SQL で行う方法を前回同様、実際のプログラムを作りながら理解していきます。この記事で FFRPG と SQL でのデータベースの基本操作は一通り解説する予定です。最初に、SELECT で複数レコードが対象になる場合の処理について解説し、その後レコードの変更および削除および追加を行う方法を解説したいと思います。 その前に、前回の演習問題の解説からはじめましょう!演習問題解説(icafe008)
前回の演習問題はいかがでしたか?解説の前に少し思い出しておきましょう。演習問題は、サブ・プロシージャー getCustomerName を作成し、main プロシージャーからそれを呼び出すという問題でしたね。 演習問題の main プロシージャーを見るとわかる通り、getCustomerName は引数として得意先コードを受け取り、得意先名を戻り値として返す必要があります。引数と戻り値の定義はサブ・プロシージャー内の dcl-pi ステートメントを使います。 では getCusotmerName サブ・プロシージャーの解答例を見てみましょう。 getCustomerName サブ・プロシージャーは、受け取った得意先コードに対応する得意先名を戻さなければいけません。引数として受け取る得意先コードは、dcl-pi ステートメント内で定義した customerCode 変数にセットされるので、これを select ステートメントで使用するために、where 内でホスト変数として指定しています。ホスト変数を使うことで getCustomerName サブ・プロシージャーは様々な得意先コードに対応した得意先名を戻すことができるようになります。 では演習問題全体の解答例を見てみましょう。皆さんが作成したコードと比べていかがですか?演習問題が終わっていない方は、ぜひこのコードを icafe008.sqlrpgle という名前で登録して、コンパイルおよび実行してみましょう。icafe009 プログラム(複数レコードの処理)
前回解説した SQL を組み込んだ FFRPG プログラムはすべて、SELECT 文の WHERE で対象レコードが 1 件になるような条件指定がされていました。では、条件設定で対象となるレコードが複数になった場合の処理はどうすれば良いのでしょうか?この方法を icafe009 プログラムを通して学習していきましょう。 複数レコードの処理を組込 SQL で行うには、いくつかの手順が必要になります。 まず、最初に行うのがカーソルの定義です。カーソルの定義は DECLARE CURSOR を使用します。カーソル内に含める複数レコードを選択する SELECT ステートメントをカーソル定義内に記述します。 この例における tecsmp_csr はカーソル名で、ユーザーが自由に記述します。このカーソル名を使用してこれ移行の操作が行われます。 次に定義したカーソルをオープンします。 オープンしたカーソルから 1 レコードずつ読み取るのが FETCH です。 FETCH は最初にレコードを読み取るカーソル名を指定し、読み取った値を INTO の後のホスト変数にセットします。tecsmp_csr は TECSMP テーブルの全フィールドを含んでいる(SELECT *)ので、ホスト変数も全てのフィールドを含むデータ構造を指定しています。 複数のレコードを含むカーソルから FETCH する場合は、FETCH の直後でレコードを取得できたかどうかを判断しなければなりません。SQL でこの判断を行うためには SQLSTATE フィールドを使用します。SQLSTATE には、SQL を実行するたびに正常、警告およびエラー状態を表す 5 桁の文字が自動的に保存されます。SQLSTATE フィールドは、プリコンパイラーが自動的に挿入する SQLCA データ構造内に定義済で、FFRPG プログラム内ではそのままの名称で参照することができます。SQLCA データ構造の詳細については以下を参照してください。https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rzajp/rzajpsqlcairpg.htm
SQLSTATE に設定される値で代表的なものは以下の通りです。
SQLSTATE に設定されるコードの詳細については以下を参照してください。- https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rzala/rzalaccl.htm
icafe010 プログラム(フィールド値の変更)
それでは次に、テーブルのフィールドの値を SQL で変更する方法を見ていきましょう。得意先コード ‘01010’ の得意先名「荒川薬局」を皆さんの名前に変えるプログラムを作ります。テーブルのレコードの値を更新するには UPDATE を使用します。 この SQL により、以下の更新が実行されます。- 更新対象テーブルは TECSMP(UPDATE 直後に記述)
- 検索条件は、CSCSCD(得意先コード)が ‘01010’ のもの(WHERE)
- 更新するフィールドは CSCSKJ
- 更新する値はCSCSKJ(ホスト変数)にセットされている値
- メニューのオプション 8「SQL プログラムの作成」を実行
- メニューのオプション 9「データの照会」を実行し、得意先コード ‘01010’ の得意先名を確認
- icafe010 をメニューのオプション2で実行
- メニューのオプション 9「データの照会」を実行し、得意先コード ‘01010’ の得意先名が変わったか確認
- 変わっていない場合はジョブ・ログで SQLSTATE を確認
icafe011 プログラム(レコードの削除)
今度はレコードを削除してみましょう。レコードを削除するには DELETE を使用します。 この SQL により、得意先コード ‘01010’ のレコードが削除されます。削除は永久的なもので、削除したレコードを復活させることはできないので注意しましょう。 また、UPDATE と同様、where による条件が指定されていなければすべてのレコードが削除対象となるので注意してください。万が一全レコード削除してしまった場合は、メニューのオプション 10「TECSMPデータの初期化」を実行してください(コマンドのプロンプトは表示されますが、すべての項目は指定済なので、そのまま実行してください)。 icafe011 のソース・コードは以下の通りです。 icafe010 同様にプログラムをコンパイルし、メニューのオプション 9 を使用して得意先コード ‘01010’ のレコードが削除されたことを確認してください。 削除されなかった場合は、ジョブ・ログの SQLSTATE を確認してみましょう。icafe012 プログラム(レコードの追加)
icafe010 でデータの変更、icafe011 でデータの削除を行いました。残るはデータの追加です。icafe012 プログラムを通して、先程削除したデータを再度追加してみましょう。 レコードの追加には INSERT を使用します。 この SQL の指定内容は以下の通りです。- レコードを追加するテーブルは TECSMP(INTO)
- レコードの全てのフィールドにセットする値をカンマで区切ったホスト変数で指定(VALUES)
- すでに存在する得意先コードのレコードを追加する
- 得意先カナに 2 バイト文字を指定する