Comments
Transcript
[5]クライアント/サーバー アドバンストSQL編 [5] クライアント/サーバー 5-1 SQLJ
DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー アドバンストSQL編 [5]クライアント/サーバー お断り:当資料は、DB2 UDB V7.1(AIX,NT,OS2) をベースに作成されています。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 [5] クライアント/サーバー 5-1 SQLJ 5-2 SQLプロシージャー言語(PSM) (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 1-2 ) <第1.00版>2001年2月 DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー [5] クライアント/サーバー 5-1.SQLJ (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 内容 1. SQJとは 2. SQLJの位置づけ 3. SQLJの特徴 4. SQLJとJDBC 5. SQLの記述方法 6. SQLJがサポートするもの 7. SQLJ vs. JDBC 8. イテレータの使用 当章ではSQLJとSQLJでのプログラム開発手順の概要を紹 介します。 なお、プログラミングに関する詳細情報として以下の資料が 非常に有効ですので、当資料の最後に参考資料として添付 してあります。 8-1. 列位置指定バインド・イテレータ 8-2. 列名指定バインド・イテレータ 1998年10月開催 DB2 Update W/S #2 「DB2 UDB V5.2 新機能より SQLJ 」 のセッション用資料 9. SQLJプログラムの開発手順 10. UDB SQLJサポート 10-1. UDBでのSQLJプログラム開発と実行 10-2. UDBでのSQLJプログラム開発手順例 10-2-1. UDBでのSQLJプログラム開発手順例 - Step.1- 10-2-2. UDBでのSQLJプログラム開発手順例 - Step.2- 10-2-3. UDBでのSQLJプログラム開発手順例 - Step.3- 10-3. UDBでのプロファイルのカスタマイズ 10-3-1. プロファイルの内容(カスタマイズ前) 10-3-2. プロファイルの内容(カスタマイズ後) 10-4. SQLJプログラムの実行 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 3-4 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 1.SQLJとは DB2 の Java 使用可能性 JDBC を使用して DB2 にアクセス Java で作成されたクライアント・アプリケーションおよびアプレットのサポート SQLJ を使用して DB2 にアクセス Java で作成されたクライアント・アプリケーションおよびアプレットのプリコンパイルおよびバインド・サポート サーバー上の Java UDF およびストアード・プロシージャーのサポート (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 1.SQLJとは DB2 ユニバーサル・データベースは、2 つの標準ベースの Java プログラミング API をインプリメントします。 Java データベース・ コネクティビティー (JDBC) および組み込み SQL for Java (SQLJ) です。 SQLJ と JDBC の比較 JDBC API を使用すると、データベースに対する動的 SQL 呼び出しを行う Java プログラムを作成することができます。 SQLJ アプリケーションは、JDBC を基礎として使用してデータベースへの接続や SQL エラー処理などのタスクを実行します が、SQLJ ソース・ファイルに組み込み静的 SQL ステートメントを含めることもできます。 またサーバー上のUDFやストアドプロシージャをJDBCやSQLJを使用して作成することもできます。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 5-6 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 1.SQLJとは .. JAVAプログラムから静的埋め込み型SQLを使用するための仕様およ びコンポーネント トランスレーター、カスタマイザー、ランタイムクラス... SQLJコンソーシアムによって仕様を定義、検討 SQLJコンソーシアムとは、SQLJの実用的標準の作成を目指すインフォーマルな集まり IBM,Oracle,Tandem,Sybase,JavaSoft,Microsoft,XDBが参加 SQLJのテクノロジー 3つのパートとして構成されている Part 0:SQLJ 埋め込み型SQL Part 1:SQLJ ストアド・プロシージャ & UDF Part 2:SQLJ データ型 SQLJの標準化の動向 ANSIとして認められ、国際標準(ISO)として発行すべく、現在作業中 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 1.SQLJとは .. SQLJはJavaプログラムから静的埋め込みSQLを使用するためのメソドロジーと仕様です。 SQLJが提供するコンポーネントには、SQLJのシンタックスを含むのソースコードを標準的なJAVAのソースコードに変換するト ランスレーターや、プロファイルカスタマイザーと呼ばれるデータベース内にパッケージを作成するためのツール(つまりプリコ ンパイラーのようなもの)、実行時に必要となるJavaのクラスなどが含まれています。 SQLJはANSI/ISOの埋め込み型SQLの標準に非常に近い仕様を持つように、IBM,Oracle,Tandem,Sybase,JavaSoft他が共同で仕 様を作成しました。 SQLJの仕様は、3つのパートとして構成されています。 Part 0:SQLJ 埋め込み型SQL Part 1:SQLJ ストアド・プロシージャ & UDF Part 2:SQLJ データ型 SQLJは国際標準として制定しようと、現在 AMSI/ISOにて、その作業を行なっています。 なお、現在ISOにて検討中であるのは、上記 Part 0とPart 1です。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 7-8 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 2.SQLJの位置づけークライアント・サーバー環境におけるデータベースアクセスの発展ー クライアント ① SQL プログラム C言語など サーバー 製品固有 分散アク セス機能 動的または 静的SQL 製品固有プロトコル DBMS または RDA クライアン ト機能 プラットフォームに依存したC/Sアクセスの形態 SQLの実行は動的でも静的でもよい ただしRDAの標準プロトコルの場合は、動的SQLのみでり、 またこれを実装した製品はまだ存在しない また静的SQLを実行できる代表的なプロトコルとしてDRDAがある RDA サーバー 機能 標準プロトコル 動的SQL サーバー クライアント ② 流通性の向上 CLIまたはODBC APIの使用 いまだプラットフォームに依存したアクセスの形態 ではあるが、DBMSに依存しないプログラムが可能 SQLの実行は動的のみのため、SQL処理の性能 には限界がある しかし、アプリケションごとのバインドが不要 であるので、プログラムの流通性が向上 動的SQL プログラム または ODBC アプリケー ション ODBC/ CLI ドライバー 製品固有プロトコル DBMS アプリケーションごと のバインド不要 プラットフォームに 依存 サーバー クライアント ③ 移植性の向上 Java言語の使用 プラットフォームに依存しないコードの 作成が可能となり、プログラムの移植性 が向上 SQLの実行は動的のみ 動的SQL JDBC/ CLI ドライバー Java プログラム 製品固有プロトコル DBMS アプリケーションごと のバインド不要 プラットフォームに依 存しない サーバー クライアント ④ 静的SQL SQL処理 性能の向上 SQLJ プログラム プラットフォームに依 存しない JDBC/ CLI ドライバー 製品固有プロトコル プロファイ ル DBMS SQLJの使用 プラットフォームに依存しない コードの作成が可能なうえに、 静的SQLが実行できSQL処理 の性能が向上 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 2.SQLJの位置づけ 上図はクライアント/サーバー環境における、これまでのデータベース アクセスの形態の変化を示したものです。 初期段階①では、プラットフォームやDBMSに依存した形態でしたが、②ではODBCの登場により、DBMSに依存しないアプリケー ション開発が可能となりました。またODBC経由のSQL処理はすべて動的SQLで実行されるため、アプリケーションごとにパッケー ジを作成する必要がなく、これにより各ベンダーはODBC製品を開発することによって、ソースコードを公開することなくアプリケー ション(ツール)を広く配布することが可能となったのです。(流通性の向上) しかしこの段階ではプログラム言語はとしてC言語が主流でしたが、C言語はプラットフォームをまたがった移植性に乏しいため、 作成した実行モジュールを他のプラットフォームで実行することは困難でした。 そこで登場してきたのが③のJava言語を使用した形態です。さらにODBCのJava版とも言えるJDBCが誕生したことにより、アプリ ケーションの移植性が向上しました。 しかしJDBCもCLIをベースにしたインターフェースであるため、全て動的SQLとしで実行され、大量トランザクションを処理する形態 としては、SQL処理の性能に限界があると言えます。 そこで誕生したのが、④のSQLJなのです。SQLJは静的埋め込みSQLの実行を提供するので、サーバーでの負荷が軽減し、Java プログラムによる大量のクライアント処理やトランザクション処理の実現を可能にするという意味で、非常に重要性が高いと言える でしょう。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 9-10 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 3.SQLJの特徴 簡易な記述方法 JDBCのようにメソッド呼び出しをコーディングする必要はない SQLJ固有の文節が用意されている 開発が容易で、読みやすい 静的SQLを実行可能 SQL文のシンタックスチェック、特権チェック、アクセスパスの決定、SQL<->JAVA間のデータ タイプ変換の決定等を開発段階で行うことが可能 実行時のパフォーマンス向上 セキュリティーの強化 アプリ実行者には、パッケージのEXECUTE特権のみ与えておけばよい JDBCのレイヤーの上に成り立つ データベースへの処理はJDBCのレイヤーを使用する SQLJはJDBCに置き換わるものではない 静的SQLのみをサポート 動的SQLを実行したい場合はJDBCを使用する (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 3.SQLJの特徴 簡易な記述方法 JAVAは非常にオブジェクト指向的な要素の強い言語です。そのため、リレーショナルデータベースにアクセスするためのAPI であるJDBCも、この影響を強く受けています。つまり、オブジェクトを生成し、そのリファレンスを経由してオブジェクトが持つメ ソッドを実行するというスタイルをとります。 そのため、アプリケーションを作成する開発者は、SQLだけでなく、オブジェクトの 生成、呼び出すメソッドの種類、メソッドの引数などに注意を払う必要があります。 一方、SQLJでは、実行したいSQLをSQLJの仕様に基づいたSQLJ文節にのなかに記述するというスタイルをとります。従来 からの埋め込み型SQLでは、“EXEC SQL”の後に実行したいSQLステートメントを記述するというスタイルをとっていましたが、 SQLJでも、SQLJ節と呼ばれる、似たような記述方法でSQLステートメントを記述することが可能です。そのため、従来からの 埋め込み型SQLの知識を生かすこともできます。またJDBCのようにメソッド呼び出しをコーディングする必要はありません。そ のため、開発工数を少なくし、読みやすいコードを書くことも可能と言えます。 静的SQLを実行可能 SQLJの最も注目すべき点は、やはり静的SQLによるパフォー マンスの向上と言えます。 右図は動的SQLと静的SQLの実行時のプロセスの差を示した ものです。動的SQLの場合は、実行時にSQL文や権限の チェック、アクセスパスの決定を行うばかりでなく、JavaとSQL のデータ型の変換が必要です。それに比べ静的SQLの場合 は、上記の各プロセスの殆どを省くことができます。 ただし、SQLJはJDBCを全て置き換えるものではありません。 SQLJは静的SQLの記述のために使用するものであり、動的 SQLを記述したい場合は従来どおりJDBCを使用します。また SQLJとJDBCは同じデータベースへの接続コンテキストを共 有可能であり、1つのプログラムの中で共存可能です。 動的SQL パッケージの権限のチェック 静的SQL パッケージの権限のチェック SQLステートメントの検査 表や視点に対する権限のチェック アクセスパスの決定 ステートメントの実行 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 11-12 ) ステートメントの実行 DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 3.SQLJの特徴.. プログラムの移植性の向上 プリコンパイルされたプログラム(Java バイトコードと呼ばれる)は、どのDBMSに対しても実 行可能 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 3. SQLJの特徴.. プログラムの移植性の向上 SQLJの第3の特徴はプログラムの移植性(ポータビリティ)です。ただし、この静的SQLプログラムのポータビリティという概念 は特に新しいものではありません。我々はそれをC言語において追求してきました。しかしC言語であっても完全なポータビリ ティはなく、各プラットフォームでの特有な言語フィーチャーがあったり、また各DBMSベンダーは固有の実行時コードを必要と する実装になっているため、それらがポータビリティを阻害する要因となっているのです。 しかしSQLJでは実行時に各DBMS用のカスタム・プロファイルをロードするようなプリコンパイラのフレームワークを提供するこ とにより、これらの問題を解決したのです。つまり、プリコンパイルされたプログラム(Java バイトコードと呼ばれる)はどの DBMSに対しても実行可能なのです。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 13-14 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 4.SQLJとJDBC DB2 の Java アプリケーションのインプリメンテーション SQLJ アプリケーション SQLJ 実行時クラス JAVA アプリケーション JDBC DB2 クライアント リモート データベース (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 4.SQLJとJDBC DB2 JDBC アプリケーションが動作する方法を示しています。 DB2 JDBC アプリケーションは、DB2 CLI アプリケーションと考える ことができます。そのアプリケーションを Java 言語を使って作成するだけです。 Java のネイティブな方式で、JDBC の呼び出しは DB2 CLI の呼び出しに変換されます。 JDBC は、DB2 クライアントから DB2 CLI を介して DB2 サーバーに至る流れを要求しま す。 SQLJ アプリケーションはこの JDBC サポートを使用します。それに加えて、SQLJ 実行時クラスが、プリコンパイルおよびバイン ド段階でデータベースにバインドされる任意の SQL パッケージを認証および実行する必要があります。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 15-16 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 5.SQLJの記述方法 SQLJでの静的SQLステートメントは、SQLJ節で記述 SQLJ節はJavaプログラム内のSQLステートメントがデータベースと通信するための機構 SQLJ節 トークン #sql で始まり、セミコロン ; で終了する 例 (1) #sql {delete from TABA} ; (2) void m (int x, String y, float z) throw SQLException { #sql {insert into TABA values (:x, :y, :z) } ; } (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 5.SQLJの記述方法 従来までのプログラム言語で使用していた"EXEC SQL" 節と同様、SQLJでの静的SQLステートメントは、SQLJ節で記述します。 SQLJ節はJavaプログラム内のSQLステートメントがデータベースと通信するための機構であり、SQLJ変換プログラムがSQLJ節 およびSQLステートメントを認識します。 SQLJ節 トークン #sql で始まり、セミコロン ; で終了する 例 (1) 最も単純な例で、#sqlの後ろに括弧で囲まれたSQLステートメントが続いた形 (2) ホスト変数を使用した例 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 17-18 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 6. SQLJがサポートするもの 静的SQL 照会; たとえば、SELECT ステートメントおよび式。 SQL データ変更ステートメント (DML); たとえば、INSERT、UPDATE、DELETE。 データ・ステートメント; たとえば、FETCH、SELECT..INTO。 トランザクション制御; たとえば、COMMIT、ROLLBACK など。 データ定義言語 (DDL、スキーマ操作言語とも呼ばれる); たとえば、CREATE、DROP、 ALTER。 ストアード・プロシージャーへの呼び出し; たとえば、CALL MYPROC(:x, :y, :z) ストアード関数の呼び出し; たとえば、VALUES( MYFUN(:x) ) Javaのストアド・プロシジャー用の仕様 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 6. SQLJがサポートするもの SQLJの仕様では、insert,update,delete, selectなどを静的SQL文で発行するためのシンタックスを定義しています。 selectでは単一行の結果が返るものと、カーサー操作によって複数行結果を返すものを含みます。 ストアド・プロシジャーから返された結果をフェッチするためのインターフェースの仕様も含まれています。 またJavaで可搬なストアド・プロシジャーを書くためには、どのようにすればよいかなどの仕様も含まれています。 パラメータの受け渡し方法 コールしたプログラムへの結果の受け渡し なお、SQLJは動的SQLとのインターフェースは定義していないので、その部分はJDBCで記述します。 一つのプログラムの中でのSQLJとJDBCの併用は問題ありません。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 19-20 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 7. SQLJ vs. JDBC 単一行SELECT文 SQLJ #sql [con] { SELECT 住所 INTO :addr FROM 社員表 WHERE 名前=:name }; JDBC java.sql.PreparedStatement ps = con.prepareStatement("SELECT 住所 FROM 社員表 WHERE 名前=?"); ps.setString(1, name); java.sql.ResultSet names = ps.executeQuery(); names.next(); name = names.getString(1); names.close(); (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 7. SQLJ vs. JDBC 単一行のSELECT文の例 JDBCではPREPARE,OPEN,FETCH,CLOSEの4ステップが必要となる処理を、SQLJではたった1行で記述できます。 また結果の値もgetStringのようなメソッドを使用せず、直接ホスト変数(:addr)に得ることが可能です。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 21-22 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 7. SQLJ vs. JDBC .. 単一行INSERT文 SQLJ #sql [con] {INSERT INTO 社員表 VALUES( :hv1, :hv2, :hv3) }; JDBC CallableStatement mystmt = con.prepareCall("INSERT INTO 社員表 VALUES(?,?,?)"); mystmt.setString(1,hv1); mystmt.setString(2,hv2); mystmt.setInt(3,hv3); mystmt.executeUpdate(); (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 7. SQLJ vs. JDBC .. 単一行のINSERT文の例 INSERTステートメントで与えるvalueも、パラメータマーカーでなく、ホスト変数を使用します。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 23-24 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 8. イテレータの使用 複数行の結果が返ってくる場合、SQLJでは結果集合イテレータ (Result Set Iterator)を使用する イテレータとは検索の結果セットを表すオブジェクト 定義方法 #sql iterator イテレータ名 (列定義) イテレータ名で指定した名前を持つクラスが生成される 列定義の部分には、結果セットの列を受け取るための変数のデータ型 の指定またはデータ型と列名の指定を行なう イテレータの種類 列位置指定バインド・イテレータ (Bound-by-position Iterator) 列定義では、変数のデータ型を指定 列名指定バインド・イテレータ (Bound-by-name Iterator) 列定義では、データ型と列名を指定 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 8. イテレータの使用 前の例では、単一行SELECT文の例を紹介しましたが、複数行の結果が返ってくる場合はSQLJでは結果集合イテレータ(Result Set Iterator)と呼ばれる特殊なJavaオブジェクトを使用します。 イテレータとはJDBCのResultSetまたはSQL92での埋め込み型SQLでのカーソルのようなものと考えれば分かりやすいでしょう。 しかしカーソルと異なるのは、イテレータは第一クラスオブジェクトであるので、パラメータとして他のメソッドに渡したり、そのイテ レータを作成したSQLJトランスレーションの単位以外でも使用可能である点です。 イテレータには列位置指定バインド・イテレータと列名指定バインド・イテレータの2種類があり、それぞれ定義の仕方が異なりま す。 列位置指定バインド・イテレータ 結果セットのデータ型のみ指定 列名指定バインド・イテレータ 結果セットのデータ型と列名を指定 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 25-26 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 8-1. 列位置指定バインド・イテレータ 列位置指定バインド・イテレータ(Bound-by-position Iterator)の使用例 ポジションに基づいて結果の値をホスト変数に入れるために、FETCH文を使用する #sql iterator Honors ( String, float ); Honors honor; String name; name float grade; grade #sql [recs] honor = { SELECT 学生氏名, 得点 FROM 成績レポート表 WHERE 得点 >= :limit AND 出席日数 >= :days AND デメリット <= :offences ORDER BY 得点 DESCENDING }; while (true) { #sql {FETCH :honor INTO :name, :name :grade }; if (honor.endFetch()) break; System.out.println( name + " の成績は " + grade ); } (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 8-1. 列位置指定バインド・イテレータ 位置づけイテレータの場合はイテレータの定義部分ではデータ型のみを記述し、結果セットの列のデータにアクセスするために は、FETCHステートメントとホスト変数を使用します。 またフェッチごとに自動的にカーソルが進みます。 なお、ここで注意すべきことは、イテレータの定義部分でのデータ型の順番と、結果セットの列の順番を一致させるということで す。ただし従来の埋め込み型SQLのプログラミングでも、SELECTリストの順序とホスト変数の順序を一致させる必要があったた め、これに関しては特に違和感はなく、従来方式のプログラミングに慣れている人にとっては、非常に親しみやすい方式と言えま す。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 27-28 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 8-2. 列名指定バインド・イテレータ 列名指定バインド・イテレータ(Bound-by-name Iterator)の使用例 生成されたイテレータ クラスは、各結果列ごとのアクセス メソッドを持つ 結果列名 #sql iterator Honors ( String name, float grade ); Honors honor; #sql [recs] honor = { SELECT 得点 AS "grade", 学生氏名 AS "name" FROM 成績レポート表 WHERE 得点 >= :limit AND 出席日数 >= :days AND デメリット <= :offences ORDER BY 得点 DESCENDING }; while (honor.next()) { System.out.println( honor.name() + " の成績は " + honor.grade() ); } 生成されたメソッド (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 8-2. 列名指定バインド・イテレータ 名前付きイテレータの場合はイテレータの定義部分でデータ型と結果列名を記述し、結果セットの列のデータにアクセスするため に、各結果列用に生成されたメソッドを使用します。 この方式では、各結果列の値をホスト変数で受け取ることなしに、直接メソッドによってアクセスできるので、イテレータの定義部 分でのデータ型および結果列名の順序とSELECTリストの列の順序は異なっていてもよく、またSELECTリストが非常に多い場合 などにおけるプログラミングの煩雑さを解消することができます。 なお、この方式の場合、カーソルを進めるためにはnext()を使用します。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 29-30 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 9. SQLJ プログラムの開発手順 SQL JAR ファイル Java ③ ソースコード Java コンパイラー ( App.java ) Java バイトコード javac App.java ① SQLJ ソースコード ( App.sqlj ) ② SQLJ トランスレー タ (App.class) sqlj App.sqlj 製品独自の実装 製品固有 ④ カスタマイザー SQL文の抽出 プロファイル (Profilex .ser) x = 0,1,2,... プロファイル (Profilex .ser) カスタマイズ済 db2profc .... 内が、製品独自のカスタマイズ処理 それ以外は、標準 SQLパッケージ の格納 内は、UDBでの使用コマンド DataBase (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 9. SQLJ プログラムの開発手順 従来の埋め込み型SQLプログラムを作成する場合もプリコンパイル、コンパイル/リンク、バインドという複数のステップが必要で すが、SQLJでもいくつかのステップがあります。 ① SQLJソースコードの作成 まずSQLJ節(後述)を含むSQLJのソースコードを作成します。 上記図にもあるように、SQLJのソースコードを含むファイルは.sqljという拡張子をつけます。ここの例ではApp.sqlです。 ② トランスレーション トランスレーションは、従来のプリコンパイル機能に類似したトランスレートという作業です。トランスレータはSQLJソースコード をJavaソースコードに変換するのと同時に、SQL文部分を抽出したプロファイルというのもを作成します。もしSQLJプログラム が複数のデータベース接続コンテキストを含んでいる場合は、そのコンテキストの数だけプロファイルも作成します。 トランスレーションのコマンド sqlj SQLJのソースコード名 ③ Java ソースコードのコンパイル 通常のJavaのコンパイル・ステップと同じであり、②で書き出されたJavaソースコードをJavaのバイトコードに変換します。 javac Javaソースコード名 ④ プロファイルのカスタマイズ ②で作成されたプロファイルをデータベースに対してバインド(カスタマイズ)するステップです。ここで各DBMS毎にSQL文を実 行するためのJavaバイトコードを含む、カスタマイズされたSQLJプロファイルが作成されます。 つまりステップ③まではプラットフォームや製品を問わない標準で規定された仕様に基づいた処理ですが、④のカスタマイ ザーは各製品固有の仕様に任されているため、カスタマイズ後のプロファイルの内容や実行時における静的パッケージの呼 び出し方法は、製品固有の実装となっています。 UDBでのカスタマイズ用コマンド db2profc (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 31-32 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10. UDB SQLJサポート UDBのSQLJ サポートは、DB2 ソフトウェア開発者キット (DB2 SDK) で 提供される DB2 SDK が提供する SQLJ サポート SQLJ 変換プログラム、 SQLJ SQLJ 実行時クラス sqllib/java/runtime.zip DB2 SQLJ プロファイル・カスタマイザー db2profc DB2 SQLJ プロファイル・プリンター db2profp SQLJ プロファイル・プリンター profp SQLJ プロファイル監査プログラム・インストーラー profdb SQLJ プロファイル変換ツール profconv (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10. UDB SQLJサポート UDBのSQLJ サポートは、DB2 ソフトウェア開発者キット (DB2 SDK) で提供されます。 DB2 クライアントが提供する JDBC サポー トとともに DB2 SQLJ サポートを使用すると、組み込み SQL for Java アプリケーション、アプレット、ストアード・プロシージャー、 およびユーザー定義関数 (UDF) を作成、構築、および実行できるようにします。これらには静的 SQL が含まれ、DB2 データベー スにバインドされている組み込み SQL を使用します。 DB2 SDK が提供する SQLJ サポートには、以下のものが含まれます。 SQLJ 変換プログラム、 SQLJ SQLJ プログラムにある組み込み SQL を Java ソース・ステートメントで置換し、SQLJ プログラムで見つかった SQL 操作に ついての情報を含む直列化プロファイルを生成します。 SQLJ 変換プログラムは、sqllib/java/sqlj.zip ファイルを使用します。 SQLJ 実行時クラス sqllib/java/runtime.zip で使用可能です。 DB2 SQLJ プロファイル・カスタマイザー db2profc 生成されたプロファイルに保管される SQL ステートメントをプリコンパイルし、DB2 データベースにパッケージを生成します。 DB2 SQLJ プロファイル・プリンター db2profp カスタマイズ済みの DB2 プロファイルの目次を平文で印刷します。 SQLJ プロファイル・プリンター profp カスタマイズ前のプロファイルの目次を平文で印刷します。 SQLJ プロファイル監査プログラム・インストーラー profdb デバッグするクラス監査プログラムを 2 進プロファイルの既存のセットにインストール (またはアンインストール) します。 SQLJ プロファイル変換ツール profconv 直列化プロファイルのインスタンスをクラス・バイトコード書式に変換する。ブラウザーの中には、アプレットに関連するリソー ス・ファイルから直列化オブジェクトをロードするためのサポートがないものもあります。対処方法として、このユーティリティー を実行して変換を実行する必要があります。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 33-34 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-1. UDBでの SQLJプログラム 開発と実行 開発に必要なコンポーネント 必要なコマンド類 SQLJ DB2PROFC DB2PROFP PROFP PROFDB PROFCONV トランスレーション、カスタマイズに必要なクラスを含むZIPファイル sqlj.zip これら開発に必要なコンポーネントはSDKに含まれる SDKに含まれる 実行時に必要になるコンポーネント 実行時に必要なクラスを含むZIPファイル runtime.zip DB2 JDBCドライバーをはじめとするJDBC用のクラスを含むZIPファイル db2java.zip これらは、UDB、CAEまたはSDKに含まれる UDB、CAEまたはSDKに含まれる (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-1. UDBでの SQLJプログラム 開発と実行 開発には、以下のコマンドを使用します。 SQLJ PROFP PROFDB PROFCONV DB2PROFC DB2PROFP トランスレーション、カスタマイズに必要なクラスを含むZIPファイル sqlj.zip これら開発に必要なコンポーネントはSDKに含まれる SDKに含まれる 実行時に必要になるコンポーネント 実行時に必要なクラスを含むZIPファイル runtime.zip DB2 JDBCドライバーをはじめとするJDBC用のクラスを含むZIPファイル db2java.zip これらは、UDB、CAEまたはSDKに含まれる UDB、CAEまたはSDKに含まれる (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 35-36 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-1. UDBでの SQLJプログラム 開発と実行.. 環境設定 開発時 sqlj.zipとカレントディレクトリーがCLASSPATHに含まれていること 前頁の開発に必要なコマンドをPATHの通ったディレクトリーに置く( 通常はSQLLIB\BINに存在するため特に作業は不要 JDKのディレクトリーをPATHに追加 実行時 runtime.zip,db2java.zipをCLASSPATHに含まれていること JDK 1.1.4以上 ただし UDB V6からはSDKを導入すると、\SQLLIB\javaの下にJDKが導入されるので、別途 の導入は不要 環境変数設定例 set classpath = %classpath%;.;D:\SQLLIB\java\db2java.zip;D:\SQLLIB\java\runtime.zip;D:\SQLLIB\java\sqlj.zip ピリオド(カレントディレクトリーを意味する) set path=%PATH%;D:\SQLLIB\java\jdk\bin (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-1. UDBでの SQLJプログラム 開発と実行.. SQLJのプログラムを開発/実行する場合、以下のような環境が設定されている必要があります。 開発時 sqlj.zipとカレントディレクトリーがCLASSPATHに含まれていること カレントディレクトリーがCLASSPATHに含まれていないと、カスタマイズ・プロセス(db2profc)でエラーになります。 開発に必要なコマンド(SQLJ,DB2PROFCなど)をPATHの通ったディレクトリーに置く 通常はSQLLIB\BINに存在するため特に作業は不要です JDKのディレクトリーをPATHに追加 実行時 runtime.zip,db2java.zipをCLASSPATHに含まれていること JDK 1.1.4以上 ただし UDB V6からはSDKを導入すると、\SQLLIB\javaの下にJDKが導入されるので、別途の導入は不要です :\SQLLIB\java\jdk JDK 1.1.7が導入されます。(PTF#2 レベル) (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 37-38 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-2. UDBでの SQLJプログラム 開発手順例 Step 1 : SQLJソースコードの作成 サンプル・プログラム として提供されている App.sqlj を例 とする サンプル・プログラムは \sqlilb\sapmles\javaサブディレクトリーに存在 Step 2 : トランスレーションおよびJava ソースコードのコンパイル UDBでは \sqllib\bin\sqlj.exeが提供され、SQLJ標準で定義されているトランスレーション処理 (sqljによる)とJava ソースコードのコンパイル処理( javacによる)を同時に実行することができ る 実行方法: sqlj SQLJのソースコードファイル名 ( .sqlj を含める) Step 3 : プロファイルのカスタマイズ UDBでのカスタマイズ用コマンド 実行方法: db2profc オプション -url=JDBC-url プロファイル名 [参考 参考] 参考 bildsqlj UDBでは\sqllib\samples\java\bldsqlj.bat bldsqlj.batによって、上記のStep 2 と 3を同時に連続して同時に bldsqlj.bat 行なうことが可能 実行方法 : bldsqlj <プログラム名> [ <データベース名> [ <ユーザーID> <パスワード> ]] (プログラム名 .sqlj はつけない) (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-2. UDBでの SQLJプログラム 開発手順例 ここではアプリケーションの開発手順を、サンプル・プログラム として提供されている App.sqlj を例 として解説します。 サンプル・プログラムは \sqlilb\sapmles\javaサブディレクトリーに存在 SQLJプログラム開発は大きく分けて3つのステップがあります。 Step 1 : SQLJソースコードの作成 プログラムのソースコードを XXX.sqlj として作成します。 Step 2 : トランスレーションおよびJava ソースコードのコンパイル UDBでは \sqllib\bin\sqlj.exeが提供され、SQLJ標準で定義されているトランスレーション処理(sqljによる)とJava ソースコード のコンパイル処理( javacによる)を同時に実行することができます 実行方法: sqlj SQLJのソースコード名 (.sqlj まで含める) Step 3 : プロファイルのカスタマイズ プロファイルのカスタマイズ処理は、各データベース製品固有のプログラム実行環境をに合わせる処理ですので、ここでUDB 固有のでのカスタマイズ用コマンドを使用します。 実行方法 : db2profc オプション プロファイル名 [参考 参考] 参考 bildsqlj UDBでは\sqllib\samples\java\bldsqlj.bat bldsqlj.batによって、上記のStep 2 と 3を同時に連続して同時に行なうことができます。 bldsqlj.bat 実行方法 : bldsqlj プログラム名 ( .sqlj はつけない) (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 39-40 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-2-1. UDB SQLJプログラム 開発手順例 -Step.1 - Step.1 ソースプログラムの作成 App.sqlj (UDB提供サンプル・プログラム) // Source File Name: App.sqlj %I% -- 中略 -// For more information on the SQL language, refer to the SQL Reference. import java.sql.*; import sqlj.runtime.*; import sqlj.runtime.ref.*; #sql iterator App_Cursor1 (String empno, String firstnme) ; #sql iterator App_Cursor2 (String) ; ① /***************** ** Main ** *****************/ public static void main(String argv[]) { try { App_Cursor1 cursor1; App_Cursor2 cursor2; String str1 = null; String str2 = null; int count1; Connection con = null; class App { // URL is jdbc:db2:dbname String url = "jdbc:db2:sample"; static { try { // register the driver with DriverManager // The newInstance() call is needed for the sample to work with // JDK 1.1.1 on OS/2, where the Class.forName() method does not // run the static initializer. For other JDKs, the newInstance // call can be omitted. Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance(); } catch (Exception e) { e.printStackTrace(); } } DefaultContext ctx = DefaultContext.getDefaultContext(); if (ctx == null) { try { if (argv.length == 0) { // connect with default id/password con = DriverManager.getConnection(url); } else if (argv.length == 2) { String userid = argv[0]; String passwd = argv[1]; // connect with user-provided username and password con = DriverManager.getConnection(url, userid, passwd); } (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-2-1. UDB SQLJプログラム 開発手順例 -Step.1- ① イテレーターを宣言 このプログラムでは、次の 2 つのタイプのイテレーターを宣言しています。 App_Cursor1 列データ・タイプおよび名前を宣言し、列名に従って列の値を戻します (列名指定バインド)。 App_Cursor2 列データ・タイプおよび名前を宣言し、列位置ごとに列の値を戻します (列位置指定バインド)。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 41-42 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-2-1. UDB SQLJプログラム 開発手順例 -Step.1 - .. つづき else { System.out.println("\nUsage: java App [username password]\n"); System.exit(0); } con.setAutoCommit(false); ctx = new DefaultContext(con); } catch (SQLException e) { System.out.println("Error: could not get a default context"); System.err.println(e) ; System.exit(1); } DefaultContext.setDefaultContext(ctx); } // retrieve data from the database System.out.println("Retrieve some data from the database..."); #sql cursor1 = { SELECT empno, firstnme from employee }; ② // display the result set // cursor1.next() returns false when there are no more rows System.out.println("Received results:"); while (cursor1.next()) { str1 = cursor1.empno(); str2 = cursor1.firstnme(); ③ ④ System.out.print (" empno= " + str1); System.out.print (" firstname= " + str2); System.out.print ("\n"); } cursor1.close(); // retrieve number of employee from the database System.out.println("\nRetrieve the number of rows in employee table..."); #sql { SELECT count(*) into :count1 from employee }; if (1 == count1) System.out.println ("There is " + count1 + " row in employee table."); else System.out.println ("There are " + count1 + " rows in employee table."); ⑤ // update the database System.out.println("\n\nUpdate the database... "); #sql { UPDATE employee set firstnme = 'SHILI' where empno = '000010' }; // retrieve the updated data from the database System.out.println("\nRetrieve the updated data from the database..."); str1 = "000010"; #sql cursor2 = { SELECT firstnme from employee where empno = :str1 }; // display the result set // cursor2.next() returns false when there are no more rows System.out.println("Received results:"); while (true) { #sql { FETCH :cursor2 INTO :str2 }; if (cursor2.endFetch()) break; System.out.print (" empno= " + str1); System.out.print (" firstname= " + str2); System.out.print ("\n"); } cursor2.close(); ⑥ ⑦ ⑧ ⑨ -- 以下 省略 -- ⑨ (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-2-1. UDB SQLJプログラム 開発手順例 -Step.1- .. ② イテレーターを初期化 イテレーター・オブジェクト cursor1 は、照会の結果を使用して初期化されます。 照会の結果は、cursor1 に保管されます。 ③ イテレーターを次の行に拡張 cursor1.next() メソッドは、検索する行がなくなると、ブール false を戻します。 ④ データを移動 指定されたアクセス機構メソッド empno() は、現在の行に empno という列の値を戻します。 指定されたアクセス機構メソッド firstnme() は、現在の行に firstnme という列の値を戻します。 ⑤ ホスト変数に渡すデータを SELECT SELECT ステートメントは、表の行数をホスト変数 count1 に渡します。 ⑥ イテレーターを初期化 イテレーター・オブジェクト cursor2 は、照会の結果を使用して初期化されます。 照会の結果は、cursor2 に保管されます。 ⑦ データを取り出す FETCH ステートメントは、ByPos カーソルで宣言された最初の列の現行の値を結果テーブルからホスト変数 str2 に戻しま す。 ⑧ FETCH..INTO ステートメントが正常に実行されたことを検査 イテレーターが行に位置指定されない場合、つまり行の取り出しの最後の試みが失敗した場合、endFetch() メソッドはブール true を戻します。 行の取り出しの最後の試みが成功した場合には、endFetch() メソッドは false を戻します。 next() メソッドが呼び出されると、DB2 は行を取り出そうとします。 FETCH...INTO ステートメントは、暗黙的に next() メソッドを呼び出します。 ⑨ イテレーターをクローズ close() メソッドは、イテレーターによって保留にされているリソースを解放します。 システム・リソースが適宜解放されるようにするためには、イテレーターを明示的にクローズする必要があります。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 43-44 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-2-2. UDB SQLJプログラム 開発手順例-Step.2- Step 2 : トランスレーションおよびJava ソースコードのコンパイル 実行方法: sqlj App.sqlj sqlj App.sqlj 実行後作成されるもの app_SJProfile0.ser App_Cursor1.class App_Cursor2.class App.class app_SJProfileKeys.class App.java UDB SQLJ 変換プログラムは変換されたソース・コードをクラス・ファイ ルに自動的にコンパイル 自動的コンパイルが不要な場合は、-compile=false 節でコンパイル・オプションの設定を明示 的にオフにしする (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-2-2. UDB SQLJプログラム 開発手順例-Step.2- SQLJのソースを作成したら、 トランスレーションおよびJava ソースコードのコンパイルを行ないます。 実行方法は、sqlj App.sqlj です。 SQLJの使用方法は、以下のとおりです。 使用法: sqlj [options] file1.sqlj [file2.java] ... または sqlj [options] file1.ser [file2.jar] ... オプションは以下のとおりです。 -d=<directory> 生成されたバイナリー・ファイルのルート・ディレクトリー -encoding=<encoding> ソース・ファイルの Java コード化 -user=<user>/<password> オンライン検査を使用可能にする -url=<url> オンライン検査の URL を指定する -status 変換中の状況を表示する -compile=false 生成された Java ファイルをコンパイルしない -linemap コンパイルされたクラス・ファイルを sqlj ソースから計測する -profile=false 生成された *.ser プロファイル・ファイルをカスタマイズしない -ser2class 生成された *.ser ファイルを *.class ファイルに変換する -P-<option> -C-<option> -<option> をプロファイル・カスタマイザーまたはコンパイラーに渡す -P-help -C-help プロファイル・カスタマイザーまたはコンパイラーについてのヘルプを表示する -J-<option> SQLJ を実行している JavaVM に -<option> を渡す -version SQLJ バージョンを表示する -help-alias コマンド行別名についてのヘルプを表示する -help-long すべてのフロントエンド・オプションについての全ヘルプを表示する sqlj App.sqlj 実行後作成されるもの app_SJProfile0.ser ------ プロファイル App_Cursor1.class ------ イテレータ App_Cursor2.class ------ 同上 App.class ------------- 実行時クラス app_SJProfileKeys.class - プロファイルキー App.java -------------- Javaソースコード SQLJ 変換プログラムは変換されたソース・コードをクラス・ファイルに自動的にコンパイルします 自動的コンパイルが不要な場合は、-compile=false 節でコンパイル・オプションの設定を明示的にオフにしてください。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 45-46 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-2-3. UDB SQLJプログラム 開発手順例-Step.3- Step 3 : プロファイルのカスタマイズ 実行方法:db2profc -user=ユーザー名 -password=パスワード 実行方法: -prepoptions="BINDFILE USING APP00.BND PACKAGE USING APP00" -url=jdbc:db2:sample App_SJProfile0.ser プロファイル中のSQLをバインドする プロファイル中のSQLを元にパッケージを作成する バインドファイルを作成する(.bnd) パッケージの情報をプロファイルに追加する パッケージを呼び出すステートメントをプロファイルに追加する プロファイル バインド・ファイル App_SJprofile0.ser APP00.BND バインド・ファイ ルの作成 SQLパッケージ の格納 パッケージ呼び 出し情報の追加 パッケージ APP00 SAMPLE DataBase (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-2-3. UDB SQLJプログラム 開発手順例-Step.3- トランスレーションを実行後、トランスレータが作成したプロファイルから、各DBMS独自のカスタマイズプロセスによって、各製品 固有の実行可能モジュールとパッケージを作成します。 このステップでは、生成されたプロファイルに DB2 SQLJ カスタマイザーをインストールし、DB2 データベース に DB2 パッケージ を作成します。 UDBでは、db2profcコマンドでカスタマイズを行ないます db2profcによって、バインド・ファイルの作成と、それを元にデータベースに対するパッケージの作成を一度に行ないます ここの例では、APP00.BNDというバインドファイルを作成し、それを元にAPP00というパッケージをデータベースの中に作成すると いう指定になっています。 db2profcでは、バインドファイル名、パッケージ名以外にもプリコンパイル・オプションを指定することができます。(次頁参照) なお、ISOLATIONレベルのデフォルトはCSになります。 パッケージが作成されると、そのパッケージを呼び出す情報をプロファイルに追加し、元のプロファイルはカスタマイズ済みとなり ます。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 47-48 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-3. UDBでのプロファイルのカスタマイズ C:\ \SQLLB\ \BIN>db2profc [オプション オプション] オプション -url=JDBC-url プロファイル名[.ser] プロファイル名 指定できるオプション -user=ユーザーid -password=パスワード -prepoptions="プリコンパイル オプション" プリコンパイル オプション PROCOMPILE PROGRAMコマンドで指定できるオプション 但し以下の変換プログラム・オプションは適用できない CONNECT DISCONNECT DYNAMICBIND NOLINEMACRO OPTLEVEL OUTPUT SQLCA SQLFLAG SQLRULES SYNCPOINT TARGET WCHARTYPE (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-3. UDBでのプロファイルのカスタマイズ 生成されたプロファイルに DB2 SQLJ カスタマイザーをインストールし、DB2 データベース に DB2 パッケージを作成します。 プリコンパイル オプションの例 BINDFILE BLOCKING COLLECTION EXPLAIN ISOLATION OWNER PACKAGE QUALIFIER QUERYOPT SQLWARN など (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 49-50 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-3-1. プロファイルの内容(カスタマイズ前) App_SJProfile0.ser =================================================== プロファイル app_SJProfile0 項目 2 #sql { UPDATE employee set firstnme = 'SHILI' where empno = '000010' }; 行番号: 127 PREPARED_STATEMENT が EXECUTE_UPDATE によって実行されました ロールは STATEMENT です 記述子は null です プロファイル app_SJProfile0 の内容を印刷しています 948966618797 (00/01/27 18:50) を作成しました 関連するコンテキストは sqlj.runtime.ref.DefaultContext です プロファイル・ローダーは sqlj.runtime.profile.DefaultLoader@18a1bf です オリジナル・ソース・ファイル: app.sqlj 5 個の項目を含んでいます =================================================== プロファイル app_SJProfile0 項目 0 #sql { SELECT empno, firstnme from employee }; 行番号: 102 PREPARED_STATEMENT が EXECUTE_QUERY によって実行されました ロールは QUERY です 記述子は null です 結果セット・タイプは NAMED_RESULT です 結果セット名は App_Cursor1 です 2 個の結果列を含んでいます 1。モード: OUT、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: empno、マーカー索引: -1 2。モード: OUT、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: firstnme、マーカー索引: -1 =================================================== プロファイル app_SJProfile0 項目 1 #sql { SELECT count(*) from employee }; 行番号: 119 PREPARED_STATEMENT が EXECUTE_QUERY によって実行されました ロールは SINGLE_ROW_QUERY です 記述子は null です 結果セット・タイプは POSITIONED_RESULT です 結果セット名は null です 1。モード: OUT、java タイプ: int (int)、 sql タイプ: INTEGER、名前: count1、マーカー索引: -1 =================================================== 結果セット・タイプは NO_RESULT です 結果セット名は null です =================================================== プロファイル app_SJProfile0 項目 3 #sql { SELECT firstnme from employee where empno = ? }; 行番号: 132 PREPARED_STATEMENT が EXECUTE_QUERY によって実行されました ロールは QUERY です 記述子は null です 1。モード: IN、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: str1、マーカー索引: 45 結果セット・タイプは POSITIONED_RESULT です 結果セット名は App_Cursor2 です 1。モード: OUT、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: getCol1、マーカー索引: -1 =================================================== プロファイル app_SJProfile0 項目 4 #sql { ROLLBACK work }; 行番号: 148 PREPARED_STATEMENT が EXECUTE_UPDATE によって実行されました ロールは ROLLBACK です 記述子は null です 結果セット・タイプは NO_RESULT です 結果セット名は null です =================================================== (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-3-1. プロファイルの内容(カスタマイズ前) 上記はカスタマイズ前のプロファイルの内容です。 カスタマイズ前のプロファイルの印刷にはprofpコマンドを使用します。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 51-52 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-3-2. プロファイルの内容(カスタマイズ後) App_SJProfile0.ser =================================================== プロファイル app_SJProfile0 の内容を印刷しています 948966618797 (00/01/27 18:50) を作成しました 関連するコンテキストは sqlj.runtime.ref.DefaultContext です プロファイル・ローダーは sqlj.runtime.profile.DefaultLoader@18bc30 です オリジナル・ソース・ファイル: app.sqlj 5 個の項目を含んでいます =================================================== プロファイル app_SJProfile0 項目 0 #sql { #2,5,8,EMPNOFIRSTNME,0,{ call db2jrt ('111,65,65,66,65,74,65,71,77,65 ,78,65,32,32,32,32,65,80,80,48,48,32,32,32,81,66,51,80,84,98,66,81,48,49,49,49 ,49,50,32,32,',26,2,'','',0,0,'','0','','','')} }; 行番号: 102 PREPARED_STATEMENT が EXECUTE_QUERY によって実行されました ロールは QUERY です 記述子は null です 結果セット・タイプは NAMED_RESULT です 結果セット名は App_Cursor1 です 2 個の結果列を含んでいます 1。モード: OUT、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: empno、マーカー索引: -1 2。モード: OUT、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: firstnme、マーカー索引: -1 =================================================== プロファイル app_SJProfile0 項目 1 #sql { #0,0,{call db2jrt('111,65,65,66,65,74,65,71,77,65,78,65,32,32,32,32,65,80,80,48,48 ,32,32,32,81,66,51,80,84,98,66,81,48,49,49,49,49,50,32,32,',26,3,'','',0,0,'','0','','','')} }; 行番号: 119 PREPARED_STATEMENT が EXECUTE_QUERY によって実行されました ロールは SINGLE_ROW_QUERY です 記述子は null です 結果セット・タイプは POSITIONED_RESULT です 結果セット名は null です 1。モード: OUT、java タイプ: int (int)、 sql タイプ: INTEGER、名前: count1、マーカー索引: -1 =================================================== プロファイル app_SJProfile0 項目 2 #sql { #0,0,{call db2jrt('111,65,65,66,65,74,65,71,77,65,78,65,32,32,32,32,65,80,80,48,48 ,32,32,32,81,66,51,80,84,98,66,81,48,49,49,49,49,50,32,32,',24,4,'','',0,0,'','0','','','')} }; 行番号: 127 PREPARED_STATEMENT が EXECUTE_UPDATE によって実行されました ロールは STATEMENT です 記述子は null です 結果セット・タイプは NO_RESULT です 結果セット名は null です =================================================== プロファイル app_SJProfile0 項目 3 #sql { #0,0,{call db2jrt(?,'111,65,65,66,65,74,65,71,77,65,78,65,32,32,32,32,65,80,80,48,48 ,32,32,32,81,66,51,80,84,98,66,81,48,49,49,49,49,50,32,32,',26,5,'0','0',0,0,'1,','0','','','')} }; 行番号: 132 PREPARED_STATEMENT が EXECUTE_QUERY によって実行されました ロールは QUERY です 記述子は null です 1。モード: IN、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: str1、マーカー索引: 45 結果セット・タイプは POSITIONED_RESULT です 結果セット名は App_Cursor2 です 1。モード: OUT、java タイプ: java.lang.String (java.lang.String)、 sql タイプ: VARCHAR、名前: getCol1、マーカー索引: -1 =================================================== プロファイル app_SJProfile0 項目 4 #sql { #0,0,{call db2jrt('111,65,65,66,65,74,65,71,77,65,78,65,32,32,32,32,65,80,80,48 ,48,32,32,32,81,66,51,80,84,98,66,81,48,49,49,49,49,50,32,32,',28,0,'','',0,0,'','0','','','')} }; 行番号: 148 PREPARED_STATEMENT が EXECUTE_UPDATE によって実行されました ロールは ROLLBACK です 記述子は null です 結果セット・タイプは NO_RESULT です 結果セット名は null です =================================================== (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10-3-2. プロファイルの内容(カスタマイズ後) カスタマイズ後のプロファイルでは、SQLJ節で記述されていたSQL文が、db2jrtをcallするように変換されています。 db2jrtはUDB CAE(V5.2以降)に付属しているDLLです。 カスタマイズ後のプロファイルの印刷はdb2profpコマンドを使用します。 db2profp実行時は、データベース接続を確立します。 コマンド構文 >>-db2profp----+-----------------------------------------+------> '--user=--username---password=--password--' .----------------. V | >-----url=--JDBC-url-------profilename---+--------------------->< コマンド・パラメーター -user= username カスタマイズ済みプロファイルを印刷するためにデータベースに接続するときに使用する名前を指定します。 -password= password ユーザー名のパスワードを指定します。 -url= JDBC-url データベース接続の設定に使用する JDBC URL を指定します。 profilename SQL ステートメントが保管される 1 つまたは複数のプロファイルを指定します。 SQLJ ファイルが Java ファイルに変換さ れるとき、ファイルに入っている SQL 操作に関する情報は、プロファイルと呼ばれる、 SQLJ が生成した資源ファイルに保 管されます。プロファイルは、元の入力ファイル名に接尾部 _SJProfileN (N は整数) が付いた名前によって識別されま す。拡張子は .ser です。プロファイル名を指定するとき、.ser 拡張子はあってもなくてもかまいません。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 53-54 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10-4. SQLJプログラムの実行 SQLJプログラムの実行 javaプログラムの実行と同様 例 java App 実行結果 D:sqlj>java App Retrieve some data from the database... Received results: empno= 000010 firstname= CHRISTINE empno= 000020 firstname= MICHAEL empno= 000030 firstname= SALLY empno= 000050 firstname= JOHN empno= 000060 firstname= IRVING empno= 000070 firstname= EVA empno= 000090 firstname= EILEEN empno= 000100 firstname= THEODORE empno= 000110 firstname= VINCENZO empno= 000120 firstname= SEAN empno= 000130 firstname= DOLORES empno= 000140 firstname= HEATHER empno= 000150 firstname= BRUCE empno= 000160 firstname= ELIZABETH empno= 000170 firstname= MASATOSHI empno= 000180 firstname= MARILYN empno= 000190 firstname= JAMES empno= 000200 firstname= DAVID empno= 000210 firstname= WILLIAM empno= 000220 firstname= JENNIFER empno= 000230 firstname= JAMES empno= 000240 firstname= SALVATORE empno= 000250 firstname= DANIEL empno= 000260 firstname= SYBIL empno= 000270 firstname= MARIA empno= 000280 firstname= ETHEL empno= 000290 firstname= JOHN empno= 000300 firstname= PHILIP empno= 000310 firstname= MAUDE Retrieve the number of rows in employee table... There are 32 rows in employee table. Update the database... Retrieve the updated data from the database... Received results: empno= 000010 firstname= SHILI Rollback the update... Rollback done. (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 ブランク・ページです AdvSQL-5 ( 55-56 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー [5]. クライアント・サーバー 5-2. SQLプロシージャー言語 (PSM) お断り:当資料は、DB2 UDB V7.1(AIX,NT,OS2) をベースに作成されています。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 内容 1. ストアドプロシージャーの概念と効果 2. SQLプロシージャー言語の発展 3. SQLプロシージャー言語を使用すると 4. SQLルーチンの呼び出し 5. SQL99でのSQLプロシージャー言語の拡張 6. UDBでのSQLプロシージャー言語サポート 7.UDB V7のSQLプロシージャー 8.SQLプロシージャー構造 9.SQLプロシージャー ステートメント 10. コンパウンドステートメント 11.SQLプロシージャー作成と実行 12.SQLプロシージャー条件ハンドラー 13.ネストされたSQLプロシージャー 14.SQLプロシージャーからの結果セット 15.結果セットの戻り 16.プロシージャー内でのCommit/Rollback 17.SP内で使用されるその他V7新機能 18.SQLプロシージャー環境のセットアップ 19.SQLプロシージャー作成時の内部処理 20.SQLプロシージャーの格納 21.SQLプロシージャーの移動 22.V7.2でのSQLプロシージャー言語サポートの拡張予定 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 57-58 ) <第1.00版>2001年2月 DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 1. ストアドプロシージャーの概念と効果 ストアドプロシージャー クライアント/サーバー環境のクライアントがサーバーに存在するデータベースを効率よくアク セスするための技術 アプリケーション・ロジックの中のデータベース アクセスの部分をプロシージャとして取り出し てモジュール化し、サーバー側に存在させる 効果 クライアントとサーバー間での通信回数、通信データ量が減少 アプリケーション・プログラムの部品化 データベース アクセス処理の共有化と一元管理 すでに多くのデータベース製品で実装済み (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 1. ストアドプロシージャーの概念と効果 ストアドプロシージャーは、クライアント/サーバー環境のクライアントがサーバーに存在するデータベースを効率よくアクセス するための技術です。 アプリケーション・ロジックの中のデータベース アクセスの部分をプロシージャとして取り出してモジュール化し、サーバー側に 存在させることにより、クライアントとサーバー間での通信回数、通信データ量を減少させることを目的とします。 またデータベース アクセスの部分をプロシージャとすることにより、異なるアプリケーション間で重複して記述していたデータ ベース アクセス処理を共有することができ、さらにそれを一元管理することが可能です。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 59-60 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 1. ストアドプロシージャーの概念と効果.. ストアドプロシージャを 使用しない場合 SELECT 給与額 FROM 社員表 ORDER BY 給与額; 社員表から給与額 をすべて取り出す。 OPEN ...; FETCH ..;; 全行を1行づつ フェッチする。 FETCH ...; CLOSE ...; ストアドプロシージャを 使用した場合 データベースに格納 SELECT 給与額 されているストアドプ FROM 社員表 ロシージャを呼び出 ORDER BY 給与額; す。 CALL ...; すべてのデータをク ライアントに返却す る。 OPEN ...; FETCH ..;; 社員表から給与額をす べて取り出す。 FETCH ...; CLOSE ...; 得た結果から給与額 の中央値を計算する。 クライアントに計算結 果を返却する。 得た結果から給与 額の中央値を計算 する。 クライアント クライアント サーバ 通信回数・通信データ 量が多い。 通信回数・通信データ 量が少ない。 サーバ サーバで一元管理 しやすい。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 1. ストアドプロシージャーの概念と効果.. 上図に示したように、クライアントプログラム中に業務ロジックとSQL文がある場合、SQL文を実行するたびにその要求と結果応 答が通信回線を往復します。それに対してストアドプロシージャを使用した場合は、クライアントプログラムからはストアドプロシー ジャの呼び出しだけになるので、次のような性能上の効果があります。 通信回数が減る。 通信データ量が減る。 これらの効果によってクライアントプログラムの経過時間が短縮し、通信プロトコル変換処理にかかるプロセッサ負荷の削減がで きるのです。 またストアドプロシージャは、データベースサーバ側に格納されるので一元管理に適し、アプリケーションプログラムの部品化と 流通を促進する技術としても注目されました。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 61-62 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 2.SQLプロシージャー言語の発展 当初ストアドプロシージャーの実装は、製品固有の機能として開発 ベンダ間の移植が事実上困難であった 1996年、ストアドプロシージャーの内部に記述する構文を、SQLプロ シージャー言語として標準化 SQL/PSM (Persistent Stored Module)として規定 SQL99 PSM CREATE PROCEDURE文のサポート ストアドプロシージャーを定義 CALL文のサポート クライアント プログラムからストアドプロシージャーを呼び出す SQLプロシージャー言語の拡張 手続き言語としての機能拡張 コンパウンド ステートメント SQL変数宣言 If 文 など PSMは以下の3種のSQLルーチン専用のプロシージャー言語 ストアドプロシージャー ユーザー定義関数 ユーザー定義メソッド (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 2.SQLプロシージャー言語の発展 従来のSQL92では、埋め込みSQL文を含んだアプリケーションプログラムの構造は、アプリケーションロジックとデータベースを アクセスするSQL文とを明確に分離することを主な目的とし、下図のような構造を想定していました。 SQL文を含むプログラム(図の右側)の中に記述する構文を特に、モジュール言語と呼んでいて、モジュール言語を実際にどのよ うに既存のプログラミング言語に対応させるかは実装に任されていました。またモジュール言語で記述したプロシージャを内部プ ロシージャとして呼び出すか外部プロシージャとして呼び出すかも、実装に任されていました。 このプログラム構造の特徴は、プロシージャの開発および呼び出し方が使用するC言語やCOBOL言語などのプログラミング言 語の構文に従うので、結果としてそれらのプログラミング言語の稼動環境や言語仕様に依存することになり、特にクライアント/ サーバ環境では、標準が目指すSQLアプリケーションの移植性に欠けるという問題がありました。 そこでSQL標準はこの問題を解決するために、1996年にストアドプロシージャの内部に書ける構文をプロシージャ言語として標 準化し、これを永続格納モジュール(PSM、Persistent Stored Module)と呼ばれる規格にまとめました。そしてSQL99でストアドプ ロシージャを定義するCREATE PROCEDURE文とクライアントプログラムからストアドプロシージャを呼び出すCALL文を正式 にサポートすることにしました。 つまりPSMは、SQLルーチンと総称して呼ばれる次の3種類のプログラムを記述するためのSQLルーチン専用のプロシージャ言 語と言えます。 ストアドプロシージャ ユーザ定義関数 ユーザ定義メソッド アプリケーションプログラム main() { char SQLSTATE[6]; char emp_name[21]; emp_open (SQLSTATE, "123456" ) ; while ... { emp_fetch (SQLSTATE, emp_name); }; emp_close () ; module read Language C SQL標準の Authorization reader モジュール DECLARE emp_csr CURSOR FOR 言語 SELECT 社員名 FROM 社員表 WHERE 社員番号=:emp_no ; PROCEDURE emp_open (SQLSTATE, :emp_no CHAR(6) ) ; OPEN emp_csr ; PROCEDURE emp_fetch (SQLSTATE, :emp_name CHAR(20)); FETCH emp_csr INTO :emp_name ; PROCEDURE emp_close ; CLOSE emp_csr; SQLモジュールの呼び 出し構文はプログラム 言語仕様に依存する。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 63-64 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 2.SQLプロシージャー言語の発展.. 手続き型としての拡張 ローカル環境およびクライアント/サーバー環境ともにパフォーマンス改善を目指す 単一のEXEC SQLでの、複数 SQLステートメントの記述 複数ステートメント プロシージャ、関数、メソッド 新しい制御ステートメントのサポート(プロシージャ言語の拡張) begin/end block, assignment, call, case, if, loop, for, singal/resignal, variables, exception handling など SQL-onlyでの複雑なロジック記述の実装 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 2.SQLプロシージャー言語の発展.. 手続き型言語としての拡張として目指したのは以下の2点です。 単一のEXEC SQLでの、複数 SQLステートメントの記述 複数ステートメント プロシージャ、関数、メソッド この拡張はローカル環境およびクライアント/サーバー環境の双方のアプリケーションのパフォーマンスの向上を目的にしていま す。 また従来のSQL操作ステートメントだけでなく、新しくロジックを制御するステートメントのサポートを追加しました。 これにより、SQL文のみで、複雑なロジックをもつ手順を記述することができるようになりました。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 65-66 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 3. SQLプロシージャー言語を使用すると 従来形式 C言語、埋め込みSQLの場合: void main EXEC SQL INSERT INTO employee VALUES ( ...); EXEC SQL INSERT INTO department VALUES ( ...); } 96年に規定されたPSMの拡張機能: void main { EXEC SQL BEGIN INSERT INTO employee VALUES ( ...); INSERT INTO department VALUES ( ...); END; } (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 3. SQLプロシージャー言語を使用すると ここで上記のような簡単なC言語の埋込み型SQLプログラムがあったとします。 このプログラムでは各INSERT処理ごとに EXEC SQLで記述しています。 次に上記のプログラムを96年に規定されたPSMのルールで記述すると、1つのEXEC SQLで複数のSQL文を記述することができ、 アプリケーションからは、サーバーに対して1回のSQL要求によって複数のSQL処理を要求することができるようになります。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 67-68 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 3. SQLプロシージャー言語を使用すると.. SQL99 PSM(SQLプロシージャー言語)では 先にSQLプロシージャを作成: CREATE PROCEDURE proc1 () { BEGIN INSERT INTO employee VALUES ( ...); INSERT INTO department VALUES ( ...); END; } 先の埋込みSQLプログラムは以下のようになる void main { EXEC SQL CALL proc1(); } (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 3. SQLプロシージャー言語を使用すると.. 前頁では、1回のEXEC SQLで複数のSQL処理をブロック化して送付する例を挙げましたが、そしてこのブロック化された処理の 部分をプロシージャとして作成することが可能になりました。 そのためもとの埋込みSQLプログラムには、もはやSQL処理を記述する必要はなく、プロシージャのコールのみ記述すればよいこ とになります。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 69-70 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 4. SQLルーチンの呼び出し ストアドプロシージャの呼び出し EXEC SQL CALL プロシージャ名 (パラメタ名, ...) ; CREATE PROCEDURE プロシージャ名 (IN 入力パラメタ名 データ型,,... OUT 出力パラメタ名 データ型.... IN OUT 入出力パラメタ名 データ型,...) LANGUAGE ... ... <ルーチンボディ> ;. ルーチンボディ 外部ルーチンを参照するか、プロシージャ言語 プロシージャ言語を使用して記述する プロシージャ言語 外部ルーチン(CやCOBOL言語などで作成されたもの)を呼び出す場合は、LANGUAGE句で の言語の指定と、EXTERNAL句による外部ルーチン名の指定をする CREATE PROCEDURE ... ... EXTERNAL NAME 外部ルーチン名 LANGUAGE C プロシージャ言語を使用する場合は、LANGUAGE句でSQLを指定する (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 4. SQLルーチンの呼び出し ストアドプロシージャーの呼び出し CRATE PROCEDUREステートメントによってストアドプロシージャーを作成します。 ストアドプロシージャーをコールするプログラムは EXEC SQL の中で CALL を発行します。 ストアドプロシージャーのルーチンボディの部分は、外部ルーチンを参照するようにするかプロシージャ言語を使用して記述しま す。 参考 ユーザー定義関数の呼び出し EXEC SQL SELECT ユーザ定義関数名(パラメタ名) FROM 表名 WEHRE ...; CREATE FUNCTION ユーザ定義関数名 (IN 入力パラメタ名 データ型,...) RETURNS 戻り値のデータ型 LANGUAGE ... ... <ルーチンボディ> ; ユーザー定義関数も外部ルーチンを参照するか、プロシージャ言語を使用して記述可能です。 またストアドプロシージャと、ユーザ定義関数およびユーザ定義メソッドとの主な相違点は、出力パラメタの個数で、ストアドプロ シージャは任意の個数の出力パラメタを定義できるのに対して後者は、関数あるいはメソッドの戻り値としてはただ1個を指定しま す。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 71-72 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 5. SQL99でのSQLプロシージャ言語の拡張 ルーチンボディに記述できる文が追加 ロジック制御文が強化される 複合文 BEGIN ...END; 変数宣言 DECLARE 変数 CHAR(6); IF文 IF 変数<>'SQL’ THEN ... ELSE ... END IF; CASE文 LOOP文 CASE 変数 WHEN ’SQL’ THEN ... ELSE .... END CASE; LOOP <SQL文のリスト> END LOOP; WHILE文 WHILE i<100 DO ... END WHILE; REPEAT文 REPEAT ... UNTIL i<100 END REPEAT; FOR文 FOR 結果 AS ... DO ... END; LEAVE文 LEAVE ラベル名 ; RETURN文 RETURN 戻り値; CALL文 CALL プロシージャ名(引数1,引数2,引数3); SET文 SET 変数=’abc’; SIGNAL文 SIGNAL 条件名 ; (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 5. SQL99でのSQLプロシージャ言語の拡張 上記は新しく追加されたSQL99でのSQLプロシージャ言語です。 これらは主に、プログラミング言語としてロジックを制御するステートメントです。このようにSQLプロシージャ言語は、内部にプログ ラムロジックおよびSQL処理を記述できるようになったため、クライアントのアプリケーションプログラム言語に依存しないプロシー ジャの作成が可能となります。 したがってこれまで困難だったストアードプロシージャのベンダー間での移植も可能となることを示唆しています。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 73-74 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 5. SQL99でのSQLプロシージャ言語の拡張.. プロシージャ言語で記述 したストアドプロシー ジャーの例 ③ボディを 記述する。 ⑦CASE 文 ⑨LOOP 文 CREATE PROCEDURE upd_interest ( IN kamoku INT, , OUT total_count INT ,total_bal DECIMAL(15,2)) LANGUAGE SQL BEGIN ATOMIC DECLARE kamoku INT DEFAULT 1; DECLARE total_count INT DEFAULT 0; DECLARE total_bal DECIMAL(15,2); DECLARE csr1 CURSOR FOR SELECT 当座残高 FROM 当座預金表; DECLARE csr2 CURSOR FOR SELECT 定期残高 FROM 定期預金表; SET total_bal=0;; CASE kamoku WHEN 1 THEN SET interest_rate=1.003; OPEN csr1; fetch_loop1: LOOP FETCH csr1 INTO bal; SET total_bal=total_bal+bal*interest_rate SET total_count=total_count+1 ; IF SQLSTATE='02000' THEN LEAVE fetch_loop1; END IF; END LOOP CLOSE csr1; WHEN 2 THEN SET interest_rate=1.005 ..... END CASE END ①ストアドプロシー ジャの入出力引数 は複数個指定可 能。 ②プロシージャ言 語を記述すること を指定する。 ④ホスト 変数宣言 ⑤カーソル 宣言 ⑥変数へ の割当て ⑧データ 操作文 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 5. SQL99でのSQLプロシージャ言語の拡張.. 上記の説明 ① ストアドプロシージャを定義します。1個の入力パラメタと2個の出力パラメタのデータ型を指定しています。 ②プロシージャ言語を使用することを指定しています。 ③ルーチンボディに複合文を記述しています。BEGIN文からEND文の間に実行したいSQL文やプロシージャ言語を記述しま す。複合文中に別の複合文が入れ子になっても構いません。 ④DECLARE文によって複合文内で参照するローカル変数を宣言しています。変数名が有効な範囲は複合文内です。DEFAUL Tオプションで既定値を設定することもできます。 ⑤発行したいSELECT文のためにカーソルを宣言しています。⑤と⑧は従来の埋め込みSQL文と同じです。 ⑥SET文を使用して値を変数に割り当てています。COBOL言語のMOVE文に相当します。 ⑦ここではCASE文を使用して入力パラメタkamokuの値によってロジックの流れを分岐させています。 ⑧宣言したカーソルを使ったOPEN文、FETCH文およびCLOSE文を使用して、表から結果行を読込みます。 ⑨ここではLOOP文を利用して、SQLSTATEが‘02000’(NOT FOUND)になるまでFETCH文を繰り返します。LOOP文の 代わりにWHILE文やFOR文を使用して表現することもできます。またここではIF文でSQLSTATEの値を検査しています。 このように、プロシージャ言語を利用すれば、データベースをアクセスするアプリケーションプログラムのプログラミング言語を標準 化することができ、移植性が向上し、製品の市場の流通性が増すことが期待できます。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 75-76 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 6. UDBでのSQLプロシ-ジャー言語サポート UDBは以下のコマンドまたは環境からSQLプロシージャー言語が使用 可能 CREATE PROCEDURE (V7.1 GAから) CREATE FUNCTION (V7.2予定) CREATE TRIGGER (V7.2予定) CLP (V7.2予定) 参考 他のDB2で プロシージャ言語での記述をサポートしているのは、AS/400, V4.2以上、DB2 for OS/390 V5,V6のみ。DB2/VM,VSEはV7からDRDAサーバーに対するCALLのみサポート DB2 for OS/390 V5,V6はPTFの適用必要 ただし使用できるのはストアドプロシージャーのみ ユーザー定義関数では使用できない (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 6. UDBでのSQLプロシ-ジャー言語サポート これまでSQL標準としてのストアドプロシージャの発展とSQLプロシ-ジャー言語(PSM)についてを説明してきました。 そこで、UDBとの関係はどうなるのかということですが、UDBでは以下のステートメントにより、プロシージャー及びユーザー定義 関数を作成することは可能ですが、V6では残念ながらまだルーチンボディでのSQLプロシージャ言語の使用はサポートされてお らず外部ルーチン参照タイプのみサポートでした。 UDB V7.1よりSQLプロシージャー言語を使用してCREATE PROCEDUREが作成可能になりました。 CREATE PROCEDURE....LANGUAGE SQL さらにV7.2より下記コマンドまたは環境からSQLプロシージャー言語が使用可能になる予定です(Macro PSMと呼ばれる) CREATE FUNCTION CREATE TRIGGER CLP 現時点で他PlatformのサポートとしてはDB2/400 V4.2 or LaterまたはDB2 for OS/390 V5,V6,V7でストアードプロシージャーに関 しSQLプロシージャ言語での記述をサポートしています。ただしDB2 for OS/390 V5,V6にそのためにはPTFの適用必要で、また使 用できるのはストアドプロシージャーのみとなっています。(ユーザー定義関数やトリーガーでは使用できません)。DB2 For OS/390 V7からは"標準装備”になっています。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 77-78 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 7. UDB V7のSQLプロシージャー UDB V7 SQLプロシージャー機能 create procedureステートメントでSQL文とコントロール文で記述されたプロシージャーで Sybase T/SQL,Oracle PL/SQLに相当 シンプル、高機能言語(SQLプロシージャー = SQL + CONTROL) 条件ハンドラーをサポート 静的、動的 SQL文をサポート Static DDL, Dynamic DDL, Static DML, Dynamic DML, and other statement パラメーターの引き渡し: IN,OUT,INOUT SQL/PSMのサブセット(SQL 99 ANSI/ISO標準) 標準の拡張: GOTO,RETURN,Result Sets,/* ... */ TEXTとBinaryでカタログに保管: backup,restoreで保管復元可能 DB2 Family(Unix,NT,AS/400,OS/390)上すべてサポート Stored Procedure Builderを使用して開発、実行可能 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 7. UDB V7のSQLプロシージャー ストアード・プロシージャーとは ストアード・プロシージャーを使用すると、クライアント / サーバー・アプリケーションのパフォーマンスを向上させることができ ます。ストアード・プロシージャー とは、データベース・サーバーでアクセス可能な共用ライブラリーの関数のことです。 ストアード・プロシージャーはデータベースをローカルにアクセスして、クライアント・アプリケーション に情報を戻します。スト アード・プロシージャーによって、リモート・アプリケーションがサーバーに複数の SQL ステートメントを渡すときに生じるオー バーヘッドを減らすことができます。クライアント・アプリケーションは、単一の CALL ステートメントを使用してストアード・プロ シージャーを呼び出し、データベースへのアクセス作業を実行します。そして、その結果をクライアント・アプリケーションに戻し ます。 SQLプロシージャー SQL プロシージャー という SQL を使用して、ストアード・プロシージャーを作成することができます。 C または Java などの言 語を使用してストアード・プロシージャーを作成することができます。ストアード・プロシージャーと同じ言語でクライアント・アプ リケーションを作成する必要はありません。クライアント・アプリケーションとストアード・プロシージャーの言語が異なる場合に は、クライアントとストアード・プロシージャー間の値の受け渡しは DB2 によって透過的に行われます。 DB2 ストアード・プロシージャー・ビルダー (SPB) DB2 ストアード・プロシージャー・ビルダー (SPB) を使用すると、 Java または SQL ストアード・プロシージャーを開発するのに 役立ちます。 SPB を一般的なアプリケーション開発ツール (Microsoft Visual Studio および IBM Visual Age forJava など) を 使って組み込むことができます。あるいは、独立したユーティリティーとして使用することもできます。ストアード・プロシー ジャーを作成する助けとして、 SPB では基本設計パターンの説明、SQL 照会の作成、ストアード・プロシージャーを呼び出す 際にかかるパフォーマンス上のコストの推定などを行う設計援助機能を備えています。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 79-80 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 8. SQLプロシージャー構造 CREATE PROCEDURE ... LANGUAGE SQL.... CREATE PROCEDURE <name> (<parameter>) LANGUAGE SQL <statement> Any statement ......................... 例:与えられた値を倍にする create procedure multiple (IN i INT,OUT o INT) LANGUAGE SQL /* multiply by 2 */ SET o=i*2 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 8. SQLプロシージャー構造 SQL プロシージャーは、 CREATE PROCEDURE ステートメントとプロシージャー本体から成り立っています。 SQL 制御ステートメ ントを SQL プロシージャー本体として指定すれば、 制御ステートメント内に複数のステートメントを指定することができます。 構文 >>-label:----+-| SQL-control-statement |-+--------------------->< '-| SQL-statement |---------' SQL-control-statement |---+-ALLOCATE CURSOR statement----+----------------------------| +-assignment statement---------+ +-ASSOCIATE LOCATORS statement-+ +-CASE statement---------------+ +-compound statement-----------+ +-FOR statement----------------+ +-GET DIAGNOSTICS statement----+ +-GOTO statement---------------+ +-IF statement-----------------+ +-ITERATE statement------------+ +-LEAVE statement--------------+ +-LOOP statement---------------+ +-REPEAT statement-------------+ +-RESIGNAL statement-----------+ +-RETURN statement-------------+ +-SIGNAL statement-------------+ '-WHILE statement--------------' label: SQL プロシージャー・ステートメントのラベルを指定します。 このラベルは、 SQL プロシージャー・ステートメント (リスト内でネ ストされているあらゆる複合ステートメントも含まれる) のリスト内で固有でなければなりません。 ネストされていない複合ス テートメントでは、同じラベルを使用できることに注意してください。 SQL プロシージャー・ステートメントのリストは、複数の SQL 制御ステートメントで使用できます。 SQL-statement SQL プロシージャー本体には、 実行可能なすべての SQL ステートメントを含めることができます。 ただし、以下 のものは含 めることができません。 CONNECT / CREATE (索引、表、または視点以外のあらゆるオブジェクトの) / DESCRIBE / DISCONNECT / DROP (索引、表、または視点以外のあらゆるオブジェクトの) / FLUSH EVENT MONITOR / REFRESH TABLE / RELEASE (接続のみ) / RENAME TABLE / RENAME TABLESPACE / REVOKE / SET CONNECTION / SET INTEGRITY (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 81-82 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 9. SQLプロシージャーステートメント 割り当て (SET a=b) コンパウンドステートメント (BEGIN ....END) 制御フロー (IF,WHILE,CASE,FOR,GOTO...etc) 条件ハンドリング(CONTINUE,EXIT,UNDO,SIGNAL) SQL DML(SELECT,DELETE,INSERT,UPDATE) SQL DDL([CREATE|DROP] [TABLE|INDEX|VIEW]) 動的 SQL (PREPARE,EXECUTE) カーサー操作 (OPEN,FETCH,CLOSE) トランザクション (COMMIT,ROLLBACK,SAVEPOINT) (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 9. SQLプロシージャーステートメント 制御フローで使用可能なコマンド CASE ステートメント 1 つまたは複数の条件の評価に基づいて、実行パスを選択します。このステートメントは、SQL 解説書に記述されているCASE 式と同様なものです。 FOR ステートメント 表の各行でステートメントまたはステートメント・グループを実行します。 GOTO ステートメント プログラム制御を SQL ルーチン内のユーザー定義のラベルに移します。 IF ステートメント 条件の評価に基づいて実行パスを選択します。 ITERATE ステートメント 制御の流れをラベル付けされたブロックまたはループに渡します。 LEAVE ステートメント プログラム制御をループまたはコード・ブロックの外へ移します。 LOOP ステートメント ステートメントまたはステートメント・グループを複数回実行します。 REPEAT ステートメント ステートメントまたはステートメント・グループを検索条件が真になるまで実行します。 RETURN ステートメント 制御を SQL プロシージャーから呼び出し元に戻します。さらに、整数値を呼び出し元に戻すこともできます。 WHILE ステートメント 指定された条件が真である間、ステートメントまたはステートメント・グループを繰り返し実行します。 割り当てステートメント (SET) 出力パラメーターまたは SQL 変数に値を割り当てます。 SQL 変数とは、プロシージャー本体内のみで定義されて使用される変数。IN パラメーターに値 を割り当てることはで きません。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 83-84 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 10. コンパウンドステートメント BEGIN .... END コンパウンド ステートメント BEGIN [NOT [NOT ATOMIC/ATOMIC] ATOMIC/ATOMIC] [<declare conditions>] [<decalre statements>] [<declare cursors/result sets>] [<declare handlers>] <statement list> END コンパウンドステートメントの例 create procedure p1() language sql lab1:begin declare a int default 1; begin declare a int default 0; set a=a+lab1.a; update test_source set test_data=test_data+100 where row_number=a; /* WARNING (who is "a" ???) */ commit; end; end lab1 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 10. コンパウンドステートメント 複合ステートメントは、SQL プロシージャー内の他のステートメントを 1 つにグループ化します。 複合ステートメントで宣言できる のは、SQL 変数、カーソル、および条件ハンドラーです。 Label コード・ブロックのラベルを定義します。 開始ラベルを指定した場合、そのラベルを使用して、 複合ステートメントで宣言する SQL 変数を修飾ることができます。また、開始ラベルは LEAVE ステートメントで指定することもできます。 終了ラベルを指定 する場合、開始ラベルと同じにしなければなりません。 ATOMIC または NOT ATOMIC ATOMIC は、複合ステートメントでエラーが発生したときに、 その複合ステートメント内のすべての SQL ステート メントをロー ルバックします。 NOT ATOMIC は、複合ステートメントでエラーが発生しても、 その複合ステートメントをロールバックしませ ん。 SQL-variable-declaration 複合ステートメントに対してローカルな変数を宣言します。 SQL-variable-name ローカル変数の名前を定義します。 SQL 変数は DB2 によって大文字に変換されます。 この名前は、同じ複合ステートメ ント内にある別のSQL 変数と同じにすることはできず、 パラメーター名と同じにすることもできません。 SQL 変数名は、列 名と同じにすることはできません。 SQL ステートメントに SQL 変数および列参照と同じ名前の識別子が含まれている場 合、 DB2 はその識別子を列と解釈します。 data-type 変数のデータ・タイプを指定します。 SQL データ・タイプの詳細については、データ・タイプを参照してください。 ユーザー定義データ・タイプ、漢字タイプ、および FOR BIT DATA はサポートされていません。 (GA時) DEFAULT constant または NULL SQL 変数のデフォルトを定義します。 SQL プロシージャーが呼び出された時点で、この変数は初期化されます。 デフォルト値が指定されていない場合、この変数は NULL に初期化されます。 RESULT_SET_LOCATOR VARYING 結果セット・ロケーター変数のデータ・タイプを指定します。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 85-86 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 11. SQLプロシージャー作成と実行 作成 db2 -td@ -f basecase.db2 実行 DB2CLP C:\>db2 call update_salary('000100',1) "UPDATE_SALARY" RETURN_STATUS: "0" CREATE PROCEDURE update_salary (IN employee_number CHAR(6), IN rating INT) LANGUAGE SQL BEGIN DECLARE SQLSTATE CHAR(5); DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE EXIT HANDLER FOR not_found SIGNAL SQLSTATE '02444'; CASE rating WHEN 1 THEN UPDATE employee SET salary = salary * 1.10, bonus = 1000 WHERE empno = employee_number; WHEN 2 THEN UPDATE employee SET salary = salary * 1.05, bonus = 500 WHERE empno = employee_number; ELSE UPDATE employee SET salary = salary * 1.03, bonus = 0 WHERE empno = employee_number; END CASE; END @ basecase.db2 UPDATE_SALARY プロシージャーは、 "sample" データベースの "staff" 表内 の "empno" のIN パラメーターによって識別される従業員の給料を上昇させま す。 このプロシージャーは、"rating" の IN パラメーターを使用する CASE ス テートメントによって上昇率を判別します。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 11. SQLプロシージャー作成と実行 従来の外部ストアード・プロシージャーの定義と同じように、 SQL プロシージャー定義には、以下のような情報が記載されていま す。 プロシージャーの名前。 パラメーター属性。 プロシージャーが作成された言語。 SQL プロシージャーの場合、この言語は SQL になります。 プロシージャーについてのその他の情報 (プロシージャーの固有名およびプロシージャーによって戻された結果セットの数) 外部ストアード・プロシージャーの CREATE PROCEDURE ステートメントとは異なり、 SQL プロシージャーの CREATEPROCEDURE ステートメントでは EXTERNAL 文節が指定されません。その代わり、 SQL プロシージャーにはそのスト アード・プロシージャーのソース・ステートメントを含むプロシージャー本体があります。 前の例では、簡単なストアード・プロシージャーの CREATE PROCEDURE ステートメントが示されています。プロシージャー名、プ ロシージャーから (またはプロシージャーへ) 受け渡されるパラメーターのリスト、および LANGUAGE パラメーターはストアード・プ ロシージャーすべてに共通するものです。ただし、SQL の LANGUAGE 値およびプロシージャー本体を形成する BEGIN...END ブ ロックは、 SQL プロシージャー特有のものです。 SQL プロシージャー本体では、 OUT パラメーターを式の値として使用することはできません。 OUT パラメーターへ値を割り当て るには、割り当てステートメントを使用するか、 SELECT、VALUES および FETCH ステートメントの INTO 文節のターゲット変数と するしか方法はありません。 IN パラメーターは、割り当てまたは INTO 文節のターゲットとして使用することはできません。 作成時、コマンドラインを使用する場合、ディフォルトのDB2 CLPスクリプトではセミコロン( ; )文字がSQLプロシジャー本体のSQL ステートメントの終了文字として使用される為、作成時にはアットマーク( @ )やドルマーク( $ )を終了文字として使用する db2 -td@ -f basecase.db2 実行はCなどのProgramからEXEC SQL CALL文を使用してCallableであるが、UDB V7からCLPからもCALL文が使用可能になっ ている。 CALL コマンドの構文は以下のように表記します: .-,-------------. V | >>-CALL--proc-name---(-----+---------+--+---)------------------>< '-引き数--' 引き数 パラメーターの記述は以下のように変更になりました: ストアード・プロシージャーに対して 1 つ以上の引き数を指定します。 入出力引き数はすべて、プロシージャーによって定義される順序で指定されなければなりません。 出力引き数は "?" 文字を使用して指定されます。たとえば、1 つの整数入力パラメーターと 1つの出力パラメーターを持つストアード・プロ シージャーfoo は、"call foo (4, ?)" として呼び出されます。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 87-88 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 12. SQLプロシージャー条件ハンドラー SQLステートメントの実行結果のレベルに応じた条件ハンドラー 条件ハンドラーのレベル 成功 : SQLSTATE '00000' Not Found : SQLSTATE '02000' WARNING : SQLSTATE '01XXX' Exception : その他のSQLSTATE値 成功しなかった場合、暗黙的に条件ハンドラーが呼ばれる Not Found,WARNINGの場合はもし宣言されていなかった場合には、終了せず次のステートメントを実行する Exception発生の場合に、もし宣言されていない場合にはCallerへ制御が帰る ハンドラー宣言の一般的な形式は、以下のようなものです。 DECLARE handler-type HANDLER FOR condition SQL-procedure-statement 例: DECLARE NO_TABLE CONDITION FOR SQLSTATE '42704'; DECLARE EXIT HANDLER FOR NO_TABLE BEGIN SET OUT_BUFFER='Table does not exist'; END EXIT ハンドラー: プロシージャーは、 NO_TABLE を SQLSTATE 42704 (name は未定義名) の条件名として宣言しま す。 NO_TABLE の条件ハンドラーは、 Table does not exist というストリングを OUT_BUFFER という出力パラメーターに 置きます。それから、そのハンドラーが宣言された複合ステートメントから SQL プロシージャーを終了させます。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 12. SQLプロシージャー条件ハンドラー 条件ハンドラーの宣言ステートメント 条件ハンドラー は、ある条件が発生する際の SQL プロシージャーの振る舞いを決定します。一般的な DB2 条件、特定のSQLSTATE 値の定義された 条件、または特定の SQLCODE 値の定義された条件に関して、 1 つまたは複数の条件ハンドラーを SQL プロシージャーで宣言することができます。一 般的な条件および独自の条件を定義するための方法についての詳細は、条件ハンドラーの宣言を参照してください。 SQL プロシージャー内のステートメントによって SQLWARNING または NOT FOUND 条件が発行され、それぞれの条件に対してハンドラーを宣言した場 合には、 DB2 によって制御が対応するハンドラーに渡されます。その特定の条件に対してハンドラーを宣言しなかった場合、 DB2 は SQLSTATE およ び SQLCODE 変数にその条件に対応する値を設定して、制御をプロシージャー本体の次のステートメントに渡します。 SQL プロシージャーのステートメントが SQLEXCEPTION 条件を起こしており、その特定の SQLSTATE または SQLEXCEPTION 条件に対してハンド ラーを宣言してある場合には、 DB2 によって制御がそのハンドラーに渡されます。 DB2 が正常にハンドラーを実行する場合には、 SQLSTATE および SQLCODE 値はそれぞれ '00000' と 0 を戻します。 SQL プロシージャーのステートメントが SQLEXCEPTION 条件を起こしており、その特定の SQLSTATE または SQLEXCEPTION 条件に対してハンド ラーを宣言していない場合、 DB2 は SQLプロシージャーを終了してからクライアントに戻ります。 条件ハンドラーの宣言 ハンドラー宣言の一般的な形式は、以下のようなものです。 DECLARE handler-type HANDLER FOR condition SQL-procedure-statement DB2 によって condition に合致する条件が起こされる場合には、 DB2 制御を条件ハンドラーに渡します。そして、条件ハンドラーは handler-type によって示 されているアクションを実行してから、 SQL-procedure-statement を実行します。 handler-type CONTINUE SQL-procedure-statement が完了した後に、エラーが起きた後のステートメントで実行が継続されることを指定します。 EXIT SQL-procedure-statement が完了した後に、ハンドラーが含まれる複合ステートメントの後から実行が継続されることを指定します。 UNDO SQL-procedure-statement が実行される前に、 DB2 によってハンドラーを含む複合ステートメントの SQL 操作がロールバックされることを指定し ます。 SQL-procedure-statement が完了した後に、ハンドラーが含まれる複合ステートメントの後から実行が継続されます。 注: UNDO ハン ドラーは ATOMIC 複合ステートメントのみで指定できます。 条件 DB2 には、以下のような 3 つの一般的条件があります。 NOT FOUND SQLCODE が +100 または SQLSTATE が '02000' になる条件を識別します。 SQLEXCEPTION SQLCODE が負の値になる条件を識別します。 SQLWARNING 警告条件 (SQLWARN0 が 'W') になる条件、または +100 以外の正の数の SQL 戻りコードになる条件を識別します。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 89-90 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 13. ネストされたSQLプロシージャー ストアド・プロシージャからストアド・プロシージャを呼び出すことが可能 両方のストアド・プロシージャはLANGUAGE CまたはLANGUAGE SQLで定義されていなけれ ばならない 呼び出し側と呼ばれる側のLANGUAGEは一致する必要がある LANGUAGE CとSQLは同等とみなされる より高いSQL DATAアクセスレベルを呼び出すことはできない NO SQL < CONTAINS SQL < READS SQL DATA < MODIFIES SQL DATA 例) Caller側のストアド・プロシージャがCONTAINS SQLでカタログされていた場合 NO SQLまたはCONTAINS SQLのストアド・プロシージャは呼び出し可能 READS SQL DATAまたはMODIFIES SQL DATAのストアド・プロシージャは呼び出し不可(SQL0577N) 16階層までのネストをサポート 呼び出し側と呼ばれる側のストアド・プロシージャはFENCEDでカタログされていなければなら ない(SQLストアド・プロシージャ以外の場合) LANGUAGE SQLのSQLストアド・プロシージャはResult SetsをCLIENTまたはCALLERへ返す ことができる DECLARE CURSOR WITH RETURN TO CLIENT/CALLER ASSOCIATE LOCATOR ALLOCATE CURSOR (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 13. ネストされたSQLプロシージャー SQL プロシージャーに CALL ステートメントを組み込んで他の SQL プロシージャーを呼び出すことができます。この機能はネスト された ストアード・プロシージャーと呼ばれています。この機能によって、既存の SQL プロシージャーを再使用してもっと複雑なア プリケーションを設計することが可能になります。 アプリケーション・アーキテクチャーを設計する際には、以下のような制約事項を念頭に置いてください。 LANGUAGE SQL プロシージャーは、 SQL または C で作成されたストアード・プロシージャーしか呼び出せません。 SQL プロシー ジャー内からは他のホスト言語のストアード・プロシージャーを呼び出すことはできません。 16 レベルのネスト SQL プロシージャーでは、最大 16 レベルのネストされた呼び出ししか含められません。 SQL プロシージャー Aが SQL プロシージャーBを呼び出し、 SQL プロシージャー B が SQL プロシージャー C を呼び出すシナリオは、3 レベルのネスト された呼び出しの例です。 再帰 再帰的に呼び出す SQL プロシージャーを作成することができます。再帰的 SQL プロシージャーは、前述の最大レベルの ネストについての制約事項に準拠する必要があります。 機密保護 SQL プロシージャーは、より高い SQL データ・アクセス・レベルでカタログ化されたターゲット SQL プロシージャーを呼び 出すことができません。たとえば、CONTAINS SQL 文節で作成された SQL プロシージャーは CONTAINS SQL 文節また は NO SQL 文節のいずれかで作成された SQL プロシージャーを呼び出せますが、 READS SQL DATA 文節または MODIFIES SQL DATA 文節のいずれかで作成されたSQL プロシージャーは呼び出せません。 NO SQL 文節で作成された SQL プロシージャーは CALL ステートメントを発行できません。 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 91-92 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 14. SQLプロシージャーからの結果セット 結果セット(Result Set) DECLARE CURSOR WITH RETURN TO CLIENT/CALLER & OPEN ASSOCIATE LOCATOR ALLOCATE CURSOR PROC2 PROC1 CALL PROC2 ASSOCIATE ALLOCATE FETCH CALL PROC1 OPEN C1 クライアント FETCH CURSOR 1 FETCH CURSOR 2 FETCH CURSOR 3 ALLOCATE CURSOR 1 RESULT SET LOCATOR 1 ALLOCATE CURSOR CURSOR2 RESULT SET LOCATOR 2 ALLOCATE CURSOR 3 RESULT SET LOCATOR 3 サーバー OPEN RESULT SET 1 OPEN RESULT SET 2 ASSOCIATE LOCATOR OPEN RESULT SET 3 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 14. SQLプロシージャーからの結果セット SQLプロシージャーからの結果セットの戻り SQL プロシージャーから結果セットを戻す方法は、外部ストアード・プロシージャーから結果セットを戻す方法に似ています。 SQL プロシージャーからの結果セットを受け入れるには、クライアント・アプリケーションは CLI、 JDBC、またはSQLJ アプリ ケーション・プログラミング・インターフェースを使用する必要があります。他の SQL プロシージャーを呼び出すSQL プロシー ジャーは、それらのプロシージャーからの結果セットを受け入れることができます。 SQL プロシージャーからの結果セットを戻 すには、以下のような SQL プロシージャーを作成します。 1.CREATE PROCEDURE ステートメントの DYNAMIC RESULT SETS 文節を使用して、SQL プロシージャーによって 戻される結果セットの数を宣言します。 2.DECLARE CURSOR ステートメントを使用してカーソルを宣言します。 3.OPEN CURSOR ステートメントを使用してカーソルをオープンします。 4.カーソルをクローズせずに SQL プロシージャーを終了します。 RSETC CALL RSETC RC=0 RSET create procedure rsetc () SPECIFIC RSETC LANGUAGE SQL BEGIN DECLARE LOC1 RESULT_SET_LOCATOR VARYING; DECLARE data1 int ; DECLARE data2 char(20); DECLARE RESULT_SET_END INT ; DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN SET RESULT_SET_END=1; SET data1=10; SET data2='DUMMY'; END; CALL RSET () ; ASSOCIATE RESULT SET LOCATOR(LOC1) WITH PROCEDURE RSET; ALLOCATE RES1 CURSOR FOR RESULT SET LOC1; SET RESULT_SET_END=0; DELETE FROM RESULT; WHILE(RESULT_SET_END=0) DO FETCH FROM RES1 INTO data1,data2; IF (RESULT_SET_END=0) THEN BEGIN insert into result values (data1,data2,current timestamp); END; END IF; END WHILE; CLOSE RES1; END$ (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 93-94 ) RESULT SET create procedure rset () RESULT SET 1 SPECIFIC RSET LANGUAGE SQL MODIFIES SQL DATA BEGIN DECLARE c1 CURSOR WITH RETURN TO CALLER FOR SELECT test_data,description FROM TEST_SOURCE ORDER BY TEST_DATA; open c1; END$ DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 15. 結果セットの戻り(caller vs client) CALLER vs CLIENT CREATE PROCEDURE CLIENT_SET() DYNAMIC RESULT SETS 1 LANGUAGE SQL BEGIN DECLARE clientcur CURSOR WITH RETURN TO CLIENT FOR SELECT name, dept, job FROM staff WHERE salary > 20000; OPEN clientcur; END SQLプロシージャーからの結果セットを Callerではなく、クライアント・アプリケー ションに戻す例 CLIENT Caller SQL SP 結果セット (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 15. 結果セットの戻り(caller vs client) 使用のアプリケーションがネストされた SQL プロシージャーから結果セットを戻す場合には、 DECLARE CURSOR ステートメント のWITH RETURN文節を使用して DB2 が適切な位置に結果セットを戻すようにする必要があります。ターゲットSQL プロシー ジャーが結果セットを呼び出し元SQLプロシージャーに戻す場合には、呼び出し元は ALLOCATE CURSOR および ASSOCIATE RESULT SET LOCATOR ステートメントを使用して結果セットにアクセスし、使用する必要があります。 クライアントへ結果セットを戻す SQL プロシージャーからの結果セットをクライアント・アプリケーションに必ず戻すようにするには、結果セットに関連した DECLARE CURSORステートメントの WITH RETURN TO CLIENT 文節を使用します。前の例では、 SQL プロシージャー "CLIENT_SET" は DECLARE CURSOR ステートメントのWITH RETURN TO CLIENT 文節を使用してクライアント・アプリケー ションに結果セットを戻します。これは、"CLIENT_SET" がネストされた SQL プロシージャーの CALL ステートメントであるとき も同様です。 クライアント側で 結果セットを受け入れるには、クライアント・アプリケーションは CLI、 JDBC、またはSQLJ アプリケーション・ プログラミング・インターフェースを使用する必要があります。C言語など埋め込み型では、ASSOCIATE,ALLOCATEコマンド C言語など埋め込み型では、ASSOCIATE,ALLOCATEコマンド はサポートされないので注意してください はサポートされない 呼び出し元へ結果セットを戻す 呼び出し元がクライアント・アプリケーションであるかまたは別の SQL プロシージャーであるかにかかわりなく SQL プロシー ジャーの直接の呼び出し元へ結果セットを戻すには、結果セットに関連した DECLARE CURSOR ステートメントのWITH RETURN TO CALLER 文節を使用します。次の例では、 SQL プロシージャー "CALLER_SET" は、 WITH RETURN TO CALLER 文節を使用して結果セットを CALLER_SET の呼び出し元に戻します。 CREATE PROCEDURE CALLER_SET() DYNAMIC RESULT SETS 1 LANGUAGE SQL BEGIN DECLARE clientcur CURSOR WITH RETURN TO CALLER FOR SELECT name, dept, job FROM staff WHERE salary > 15000; OPEN clientcur; END (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 95-96 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 16. プロシージャー内でのCommit/Rollback SP内のCommit, Rollbackはサポートされる DB2 Client DB2 Server UDB DB2 CALL Stored Procedure COMMIT V7以前 CALL Stored Procedure COMMIT DB2 Client CALL DB2 Server Stored Procedure New UDB DB2 COMMIT V7 CALL Stored Procedure COMMIT (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 16. プロシージャー内でのCommit/Rollback V7以前のストアードプロシージャーの実行とCOMMIT/Rollbackの制御 1.任意指定のデータ構造およびホスト変数の記憶域を宣言し、割り振り、そして初期化する。 2.CONNECT TO ステートメントを実行するか、または暗黙の接続を行うことによって、データベースに接続する。 3.SQL CALL ステートメントによりストアード・プロシージャーを呼び出す。 4.データベースに対し、COMMIT または ROLLBACK を発行する。 V7では、トアード・プロシージャーは COMMIT または ROLLBACK ステートメントを出すことができますが、クライア ント・アプリ ケーションが COMMIT または ROLLBACK を出すようにすることをお勧めします。これにより、クライアント・アプリケーションがスト アード・プロシージャーによって戻されるデータを評価できるようにし、トランザクションをコミットするかロールバックするかを決定で きます。 下記の例ではアプリケーションプログラム側でカーサーを宣言時にWITH HOLD句を使用しなかった為に、カーサーがCOMMITで 破壊されてFETCHができないケース アプリケーションプログラム SQLプロシージャ main() { CREATE PROCEDURE UPDTEST EXEC SQL DECLARE cr1 CURSOR FOR ( IN data1 INT ) SPECIFIC UPDTEST SELECT ROW_NUMBER,TEST_DATA,DESCRIPTION LANGUAGE SQL FROM TEST_SOURCE BEGIN FOR FETCH ONLY ; UPDATE TEST_SOURCE SET TEST_DATA=TEST_DATA + data1 ; EXEC SQL OPEN cr1; COMMIT; EXEC SQL CALL UPDTEST(:data1); END $ do { COMMIT EXEC SQL FETCH cr1 INTO :c1d, :c2d, :c3d; counter=counter+1; printf ("%ld %ld %s\n", c1d, c2d, c3d); SQL0501N The cursor specified in a FETCH or }while (1); CLOSE statement is not open. (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 97-98 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 17. SP内で使用できるその他V7新機能 SAVEPOINT SAVEPOINT RELEASE SAVEPOINT ROLLBACK TO SAVEPOINT 宣言済み一時表 No Catalog Contention No Locks No Logging IDENTITYカラム 例 create table ident_test (c1 int generated always as identity (start with 100, increment by 10), c2 smallint, c3 char(20)); 連合データベース(Federated DataBase) Nicknameの使用でDB2表とORACLE表の結合が可能 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 17. SP内で使用できるその他V7新機能 SAVEPOINT SQL文をいくつかの実行可能ブロックにグループ化できるようになりました。SAVEPOINT範囲内のブロック中のSQL文のどれ かが不充分なSQLコードを返してきた場合、アプリケーションはSAVEPOINTまでロールバックすることを選択できます。新しい SQLコマンドのSAVEPOINTおよびRELEASE SAVEPOINTはこの機能を提供します。これにより、作業単位を COMMIT/ROLLBACK単位より、より細かく制御できるようになりました。このステートメントは、 アプリケーション・プログラム (ストアード・プロシージャーを含む) に組み込むこともでき、 対話式に発行することもできます。このステートメントは、動的に 準備可能な実行可能ステートメントです 宣言済み一時表 宣言済み一時表 とは、一時表を作成したアプリケーションによって発行された SQL ステートメントにのみアクセス可能な一時 表を表します。宣言済み一時表は、アプリケーションがデータベースに接続している間しか有効ではありません。 宣言済み一時表を使用して、アプリケーションの潜在的パフォーマンスの向上を図ってください。宣言済み一時表を作成する 場合には、 DB2 はシステム・カタログ表に項目を挿入しないため、サーバーでカタログの競合による問題が起きることはあり ません。通常の表の場合とは異なり、DB2 は宣言済み一時表またはその行をロックせず、宣言済み一時表またはその表の 内容をログしません。現行のアプリケーションで多量のデータを処理するために表を作成し、アプリケーションによるデータの 操作が終了する際にそれらの表を除去する場合には、通常の表のかわりに宣言済み一時表を使用することを検討してくださ い。 識別列(Identityカラム) Identity列を使用すると表の行に確実な一意のシーケンス番号を自動生成することができます。 識別列(Indetity列 )は、DB2 が自動的に表の各行に固有の数値を生成する手段となります。表には、識別属性が定義され ている単一列を入れることができます。識別列の例には、オーダー番号、従業員番号、在庫番号、および問題番号などが想 定できます。 連合データベース DB2とは異なるデータソースへのアクセス(ORACLE)をDB2インターフェースを使用して可能1つのSQL文で複数データベース へのアクセス可能 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 99-100 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 18. SQLプロシージャー環境のセットアップ DB2アプリケーション開発クライアントの導入 C/C++コンパイラーの導入 コンパイル環境の構成 コンパイラーの環境をセットアップする実行可能ファイル DB2_SQLROUTINE_COMPIER_PATHレジストリー変数 カスタマイズした C または C++ コンパイラー・オプションを指定する DB2_SQLROUTINE_COMPILE_COMMAND 提供されたファイルの修正 中間ファイルの保管 DB2_SQLROUTINE_KEEP_FILES=1 プリコンパイルオプションおよびバインド・オプションのカスタマイズ DB2_SQLROUTINE_PREPOPTS BLOCKING {UNAMBIG | ALL | NO}など (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 18. SQLプロシージャー環境のセットアップ SQL プロシージャーを作成するためには、次のステップに従って、 サポートされている C または C++ コンパイラーをサーバー上 で使用できるように DB2 を構成します。 コンパイラーの環境をセットアップする実行可能ファイルを作成します。 OS/2 ではコマンド・ファイル、UNIX では スクリプト・ファイ ル、 Windows ではバッチ・ファイルがこれにあたります。 コンパイラーには、パス、組み込み、 およびライブラリーの環境変数が 必要な場合があります。 次のコマンドを使用して、 DB2_SQLROUTINE_COMPILER_PATH DB2 レジストリー変数を実行可能ファ イルとして設定します。 ここで、executable_file は、 C コンパイラーの環境ファイルへのフルパス名を表します db2set DB2_SQLROUTINE_COMPILER_PATH=executable_file DB2_SQLROUTINE_COMPILER_PATH DB2 レジストリー変数が設定されない場合、 DB2 は代わりにデフォルトのファイルを実行 可能ファイルとして設定します。 このデフォルト・ファイルのパスとファイル名は、 各オペレーティング・システムごとに、次のように なっています。 OS/2: %DB2PATH%\function\routine\sr_cpath.cmd UNIX: $HOME/sqllib/function/routine/sr_cpath Windows: %DB2PATH%\function\routine\sr_cpath.bat このデフォルト・ファイルを使用する場合は、これに変更を加えて、 ご使用になるサーバー・オペレーティング・システムと、 C およ び C++ コンパイラーに必要な設定を反映させる必要があります。 注: Windows NT と Windows 2000 では、コンパイラーの環境 変数を SYSTEM 変数として保管しておけば、DB2_SQLROUTINE_COMPILER_PATH DB2 レジストリー変数を設定する必要はあり ません。 中間ファイルの保存 CREATE PROCEDURE ステートメントが出されると、 DB2 はいくつもの中間ファイルを作成し、通常は、 ステートメントが正常に完 了されるとこれらを削除します。 SQL プロシージャーが期待した通りに実行されなかった場合には、 DB2 が作成した SQC、C、 PDB、およびメッセージ・ログ・ファイルを調べることができます。 CREATE PROCEDURE ステートメントが正常に実行された場合 にも DB2 が作成したファイルを保管したい場合は、 次のコマンドで、DB2_SQLROUTINE_KEEP_FILES DB2 レジストリー変数の値 を "1"、 "y"、または "yes" に設定してください。 db2set DB2_SQLROUTINE_KEEP_FILES=1 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 101-102 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 19. SQLプロシージャ作成時の内部処理 処理フロー CREATE PROCEDURE psmuno() LANGUAGE SQL label: BEGIN DECLARE cur1 CURSOR WITH RETURN FOR SELECT * FROM employee END label Input SQL Parsing & generation .SQC source with SQL and #line statements (1) SQL Precompilation C source (2) C Compile and Link (3) DB2 UDB catalog SYSCAT.PROCEDURES, SYSCAT.PROCPARMS C precompile listing with messages Package dll installed in ~/sqllib//function/routine... C言語変換、プリコンパイル、バインド、コンパイルが内部処理で行われる ->開発者は意識しなくてよい (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 19. SQLプロシージャ作成時の内部処理 SQLプロシージャ作成時の内部処理 1. DB2パーサーにてステートメントの解析 2. SYSCAT.PROCUDURES,SYSCAT.PROCPARMS表へのINSERT 3. Cストアードプロシジャの生成 SQLLIB/FUNCTION/ROUTINE/SQLPROC/$dbname/$schema/tmpに作成 4. 生成された.SQCファイルからのプリコンパイル DB2 Packageが作成される 5. プリコンパイル時のMESSAGEを.LOGへ記録 6. Compileの実行 shared library/DLLの生成 コンパイル時のMESSAGEを.LOGへ記録 7. packageの依存関係情報をSYSCAT.DEPENDENCIES表へINSERT 8. shared library/DLLの導入 SQLLIB/FUNCTION/ROUTINE/SQLPROC/$dbname/$schemaに置かれる 9. もしDB2_SQLROUTINE_KEEP_FILESレジストリー変数が1またはYであれば生成された.SQC,C,PDBとMESSAGE FILEを保管 10.中間ファイルのクリーンアップ SQLLIB/FUNCTION/ROUTINE/SQLPROC/$dbname/$schema/tmp上のFILEを消去 プリコンパイルが失敗した例) ==> db2 -td$ -f proc1.db2 SQL0901N 重大ではないシステム・エラーにより、SQL ステート メントが失敗しました。後続の SQL ステートメントは処理できます。 (理由 "Prepcompilation/Compilation failed") SQLSTATE=58004 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 103-104 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 20. SQLプロシージャーの格納 BACKUP/RESTOREに対応 SQLプロシージャーはDBの一部として格納される RESTORE後、最初の実行時FILEへ書きもどす 保存されるディレクトリーは、 各オペレーティング・システムごとに、次のようになっています。 UNIX $HOME/sqllib/function/routine/sqlproc/database_name/schema_name OS/2 および Windows %DB2PATH%\function\routine\sqlproc\database_name\schema_name ここで、database_name とschema_nameは、SQL プロシージャーの作成に使用されたデータベースとスキーマを表し ています。 CREATE PROCEDURE psmuno() LANGUAGE SQL label: BEGIN DECLARE cur1 CURSOR WITH RETURN FOR SELECT * FROM employee END label SQLプロ シージャー SYSIBM.SYSPROCEDURES DataBase (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 20. SQLプロシージャーの格納 Backup対象とならないケース SQL プロシージャーが作成されると、生成済み共用ライブラリー/DLL が 2 MB より小さい場合、これもカタログ表に保管され ます。 データベースがバックアップおよび復元されると、2 MB より小さいサイズの生成済み共用ライブラリー/DLL の ある SQL プロシージャーは、カタログ表に保存されたバージョンでバックアップおよび復元されます。 2 MB より大きい生成済み共 用ライブラリー/DLL のある SQL プロシージャーが ある場合、データベースのバックアップと復元を行うと共に、 ファイル・シ ステムのバックアップと復元も行ってください。 これを行わない場合、syscat.procedures カタログ表のソースを使用して、SQL プロシージャーの 生成済み共用ライブラリー/DLL を手動で再作成する必要があります。 注:データベースの回復時間には、 回復中のデータベースに属するファイル・シス テムに あるすべての SQL プロシージャー実行可能プログラムが削除されま す。 索引作成構成パラメーター (indexrec) が RESTART に設定されていると、 すべての SQL プロシージャー実行可能プロ グラムは、カタログ表から抽出され、 次の接続時にファイル・システムに書き戻されます。 設定されていないと、SQL 実行可 能プログラムは、SQL プロシージャーの最初の実行で抽出されます。 現実的にはCREATE PROCEDURE Statementが64KBの制約があるため、デバックオプションを使用しても2MBを越える共用 ライブラリー/DLL が作成されるケースは極めてまれと思われる。 CREATE PROCEDURE ...LANGUAGE SQL.....で格納例 CLPからSQL Procedureの作成 >DB2 -VTD$ -F UPDTEST.DB2 CREATE PROCEDURE UPDTEST ( IN data1 INT) SPECIFIC UPDTEST LANGUAGE SQL UPDATE AZUMA.TEST_SOURCE SET TEST_DATA=TEST_DATA + data1 DB20000I The SQL command completed successfully. 中間fileの確認 F:\SQLLIB\function\routine\sqlproc\V7DB\AZUMA (DataBase名/スキーマ名) 2001/01/05 09:14 28,672 P1356440.dll >DB2 SELECT SUBSTR(PROCSCHEMA,1,8),SUBSTR(PROCNAME,1,8),SUBSTR(DEFINER,1,8),LENGTH(PACKED_DESC) FROM SYSIBM.SYSPROCEDURES WHERE DEFINER='AZUMA' 1 2 3 4 -------- -------- -------- ----------AZUMA UPDTEST AZUMA 28688 <--*.DLLのサイズとほぼ同等、カタログにDLLが保管されている (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 105-106 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 21. SQLプロシージャーの移動 UDB V7 Fixpak 2から提供される新規CLPコマンド 2つのCLPコマンド GET ROUTINE データベースから.SARファイルへの抽出 PUT ROUTINE .SARファイルからデータベースへの格納 2つの"Built-in"ストアードプロシージャー SYSFUN.GET_ROUTINE_SAR SYSFUN.PUT_ROUTINE_SAR CLPコマンドは内部的にストアードプロシージャーをコールしている Fixpak2を適用後、下記コマンドを実行しなければ使用できない db2updv7 -d <database> -p Fixpak2以降(V7.1.3)からは上記コマンドを使用せずとも"標準装備”予定 実行後、select procname from sycat.proceduresにPROCNAMEとして GET_ROUTINE_SAR,PUT_ROUTINE_SARを確認可能 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 21. SQLプロシージャーの移動 現状 SQLストアードプロシージャーを作成する為には、サーバー側にCコンパイラーを導入しておかなくてはならない いままでの問題点 いったん作成されたSQLストアードプロシージャーを他のサーバーに移動するには移動する先のサーバーでSQLストアードプ ロシージャーを作成する(Cコンパイラーが必要) モバイル環境では個々の実行環境にはCコンパイラーは導入されていない(高価) 開発環境から本番環境への移行TOOLがDB2から提供されていない (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 107-108 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 21. SQLプロシージャーの移動... GET ROUTINE INTO <filename> FROM PROCEDURE <procname> <filename> ファイル名、パス/ファイル名 <procname> そのSQLプロシージャー名、修飾子がない場合はCURRENT SCHEMA名が使用 される PUT ROUTINE USING <filename> PUT ROUTINE USING <filename> OWNER <newowner> PUT ROUTINE USING <filename> OWNER <newowner> USE REGISTERS <filename> ファイル名、パス/ファイル名 <newowner> そのSQLプロシージャーの権限検査に使用される許可識別子を指定します。省 略した場合、オリジナルのDefinerが権限検査に使用される。 <USE REGISTERS> プロシージャーのスキーマ名としてCURRENT SCHEMA、CURRENT PATHの特殊レジシターを使用する。指定しない場合にはオリジナルのスキーマ名が使用さ れる (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: 21. SQLプロシージャーの移動... GET ROUTINE実行 >DB2 -VTF GET.SQL get routine into udtest.sar from procedure azuma.updtest DB20000I The GET ROUTINE command completed successfully. >DIR *.SAR 2001/01/05 09:57 34,328 udtest.sar SQLプロ シージャー SARファ イル DataBase PUT ROUTINEの内部的動き SARファイルの検査(OS,DB2のバージョンなど) SARファイルからのshared libraryとBINDファイルを取り出し、DISKへWRITE SARファイル内のプロシージャーに関するカタログ情報の抽出とDISKへWRITE Package BINDの為にsqlabnd APIの呼び出し 動的CREATE PROCEDUREの実行 SARファ イル .BNDファ イル SQLプロ シージャー DataBase .BNDファ イル (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 109-110 ) DB2 UDB(PC & Unix)デザインガイド 別冊 アドバンストSQL編 5.クライアント/サーバー 22. V7.2でのSQLプロシージャー言語サポートの拡張予定 下記のコマンドまたは環境からSQLプロシージャー言語が使用可能 CREATE FUNCTION (V7.2予定) CREATE TRIGGER (V7.2予定) CLP (V7.2予定) SQLストーアードプロシージャーのようにC言語には変換しない Merge: BEGIN ATOMIC DECLARE pk INT; FOR merge AS SELECT pk, c1 FROM input DO SET temp_pk = (SELECT pk FROM target WHERE merge.pk = target.pk); IF temp_pk IS NOT NULL THEN UPDATE target SET c1 = merge.c1 WHERE temp_pk = pk; ELSE INSERT INTO target VALUES (merge.pk, merge.c1); END IF; END FOR; END (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 解説: V7.2でのSQLプロシージャー言語サポートの拡張予定 V7.2ではSQLプロシージャー言語サポートが拡張され下記の環境またはコマンドで使用可能 CREATE FUNCTION CREATE TRIGGER コマンドラインプロセッサー(CLP) サポートされるコントロールステートメント Dynamic compound (BEGIN ... END) ATOMICのみサポート DECLARE local variables DECLARE conditions SET variables IF THEN ELSE conditions WHILE and FOR loops LEAVE and ITERATE GET DIAGNOSTICS ROW_COUNTのみサポート SIGNAL その他 (C)日本IBMシステムズ・エンジニアリング(株) データシステム部 AdvSQL-5 ( 111-112 )