新しいRUNSQLコマンドを使用してSQLを自由にする
今までのプログラミング要件から自分を解放する
IBM i 6.1 および 7.1 の新しいコマンドである RUNSQL (RUNSQL) により、Start SQL Interactive Session-STRSQL を使用して対話型 SQL セッションを開始したり、Run SQL Statements-RUNSQLSTM を使用してコマンド・ストリングをソース・ファイル・メンバーに保存しなくても、どこでもコマンドを実行できる単一の SQL ステートメントを実行できます。もしあなたが、CL 内での SQL 使用というサポートを IBM が追加するように願ったことがあるなら、その願いはかないました。RUNSQL コマンドを CL プログラムまたは CL プロシージャー内で簡単に使用することができます。この機能は、CL パラメーター、検索値、計算値、ストリング処理組み込み関数 (連結およびサブストリングなど) を組み合わせて、CL コードに SQL ステートメントを構築できる点で特にパワフルになっています。
RUNSQLSTM の経験があるなら、RUNSQL はたやすく学習できます。この記事では、RUNSQL の主な機能を説明し、そのコマンドの使用例を見てゆきながら、RUNSQL に関する一般的な質問に回答し、RUNSQL の認証オプションおよび監査オプションについて説明します。また、なぜ IBM が「RUNSQL」という名前をコマンド名にしたのか、その理由についても説明し (その名前がすでに一般的に使用されているために、対処の必要性がありそうな問題についても検討します)。とても便利な新しい RUNSQLSTM パラメーターについて、おまけの情報も少しばかり説明します。
主な RUNSQL 機能
次に RUNSQL の注目すべき面の概要を説明します。新しいコマンドを採用する場合は、これらの点を意識しておく必要があります。
- RUNSQL は、ソース PF メンバーを構築したり、プログラムを作成することなく、単一の SQL ステートメントを実行できます。
- 他の SQL インターフェースでは、SQL ステートメントは 2MB に制限されています。このコマンドの制限は、パラメーター値について CL コマンドに制限があるため 5,000 バイトです。
- IBM は、有効にする PTF に RUNSQL のヘルプ・テキストを提供しませんでした。ただし、多くの RUNSQL パラメーターはRUNSQLSTM パラメーターと同じであるため、RUNSQLSTM のヘルプ・テキストを使用するか、IBM の developerWorks のIBM i Technology Updates ウィキを参照することができます。
- RUNSQL は、呼び出し側の活動化グループで SQL ステートメントを実行します。RUNSQL がコンパイル済みCLプログラムに含まれている場合、プログラムの活動化グループが使用されます。
- RUNSQLSTM と異なり、RUNSQL はスプール・ファイルを生成しません。コマンド実行中にエラーが発生すると、該当の SQL 失敗メッセージがエスケープ・メッセージとして呼び出し側に送信されます。構文エラーを返す複雑な SQL ステートメントの場合、データベース・モニターを起動し、RUNSQL コマンドを実行して、System i Navigator でデータベース・モニターを分析するのが、最も簡単な構文エラーの原因究明法です。この方法は、SQL ステートメントが CL プログラムまたはプロシージャーで式として構築されている場合には特に便利です。
- 終了時にステートメントを暗黙的にコミットする、またはロールバックし、コミットメント制御を使用する RUNSQLSTM と異なり、RUNSQL コマンドは、暗黙的にコミットまたはロールバックは行いません。それはユーザーのアプリケーションに任されています。この動作は、組み込み SQL ステートメントが RPG および COBOL など他のプログラミング言語で動作する様子に似ています。
- COMMIT コマンド・パラメーターのデフォルト値は、*CHG です。RUNSQL を「とにかく実行するだけ」の場合、COMMIT(*NONE) を使用します。
- RUNSQL コマンドはデータベース・ファイルを開き、開いたままにしておくことはできません。RUNSQL が開くファイルは制御が戻される前に閉じます。
- RUNSQL のソース・テキスト Coded Character Set Identifier (CCSID) は、起動側ジョブの CCSID から取られています。ジョブのCCSID が 65535 に設定されている場合、デフォルト CCSID はソース・テキスト CCSID として使用されます。
- RUNSQL では照会ステートメント (SELECT など) を入力できないものの、それを使用して CREATE TABLE AS または DECLARE GLOBAL TEMPORARY TABLE AS SQL ステートメント経由でクエリーを実行することができます。
- RUNSQL は OPNQRYE の代替コマンドではありません。RUNSQL は他のプログラムで使用できるデータベース・ファイルを開かないためです。
RUNSQL の例
では、この新しいコマンドが動作しているところにジャンプして見てみましょう。この記事での私の目標は、初級、中級、上級の CL プログラミングのトピックを説明するのではなく、RUNSQL 固有のトピックに集中することです。
お見せしたい最初の例は、基本的な SQL 構造のスキーマと表から始まります (図1)。これらのコマンドは、CL コマンドを実行できる場所ならどこでも実行できます。コミットメント制御トランザクションが開始しないように、*NONE が繰り返し使用されている点に注目してください。表作成後、ftp コマンドを使用して表から行をクリアまたは削除する方法の例を見てみましょう。もちろん、表にはクリアする行はありませんが、ftp 手法は、RUNSQL コマンドが必要なものすべてを完備しているため、いかに便利であるかを示しています。
DELETE コマンドの後ろに INSERT SQL ステートメントが 3つあります。それぞれ、Submit Job (SBMJOB) コマンドで開始しています。SBMJOB コマンドはサブシステム QBATCH で新しいジョブを開始し、新しいジョブでコマンドを実行します。例を多少興味深いものにするため、3つの異なるCCSID 値を指定した SBMJOB CCSID パラメーター (図1のボールド体)を使用しました。
この例の最後のステップは、表に対する照会です。図2にはクエリーからの出力が記載されており、ドル記号とセント記号が、各文字セットについて自動的に対応する文字に変換されているのがわかるでしょう。
RUNSQL の一般的な疑問
IBM はすでに、RUNSQL コマンドに関する良い質問をいくつか受けています。 皆さんのために、ここでそのいくつかをご紹介します。
Q: このコマンドがオプションの PTF にバンドルされていないのは何故ですか?
A: IBM-i 提供のシステム・コマンド、サービス、API は、常に存在することを期待されています。この場合、6.1 および 7.1 で指定のサービス・レベルに到達した後、RUNSQL コマンドが当然存在し、アプリケーションおよびスクリプト内で安心して利用できると考えることができます。
Q: RUNSQL コマンドを追加している PTF を特定してほしいのですが。
A: IBM は通常、顧客を DB2 PTF グループ・レベルにポイントしてイネーブルメントを管理しやすいようにしていますが、今回、ここで PTF の詳細をご紹介します。RUNSQL コマンドを追加している PTF は次のとおりです。
- IBM i 6.1 - SI46208 (および任意の置き換え PTF)
- IBM i 7.1 - SI46219 (および任意の置き換え PTF)
また、6.1 PTF SI46208 は、SI46477 に置き換えられました。これは、HIPER とマークされた PTF SI46809 とともに必要条件です。新しい RUNSQL コマンドがサポートされているという理由で、DB2 PTF グループ SF99601 レベル 26 の適用を差し控えていた場合、推奨する OS 6.1 HIPER PTF 、または 610 グループ HIPER SF99609 レベル 122 以降に、RUNSQL 機能拡張が含まれていることを認識する必要があります。
RUNSQLSTM の経験があるなら、RUNSQL はたやすく学習できます。
Q: コマンドの名前が同一であるという競合を緩和するため、どのようなオプションが利用できますか?
A: Memorandum to Users (MTU) が 7.1 (2012 年 4 月) および 6.1 (2012年7 月) について更新され、潜在的なコマンド競合に対処する方法を文書にしています。RUNSQL という名前で自分自身のコマンドを所有しており、そのコマンドがライブラリーを修飾せずに呼び出されている場合、新しい QSYS/RUNSQL コマンドが、呼び出されるコマンドになります。どちらの RUNSQL コマンドがマシンに存在するか判断するには、次のコマンドを使用します。
コマンド競合を解決するには、次のオプションを検討します。
- アプリケーションを、QSYS RUNSQL コマンド以外のライブラリー修飾を使用するよう変更します。
- IBM 提供の RUNSQL コマンド名を、RUNSQLIBM に変更します。
- ライブラリーに配置されたプロキシー・コマンドを、システム・ライブラリー・リストの QSYS の前に追加します。
図3の例は、プロキシー・コマンドを使用して既存の IBM 以外の RUNSQL コマンドが QSYS/RUNSQL の前に見つかるようにする方法を示しています。図3のコマンドでは、XXXLIB を、既存のIBM 以外が提供したコマンドのライブラリー名と置き換えます。
Q: IBM i にはすでに RUNSQLSTM コマンドがあります。なぜ、RUNSQL コマンドを作成したのでしょうか?
A: 良い質問です。次のセクションで回答しましょう。
RUNSQL 対 RUNSQLSTM
RUNSQL は、SQL コマンド・パラメーターで指定された単一の SQL ステートメントを実行します。対照するポイントとして、RUNSQLSTM は1つまたは多数の SQL ステートメントまたはコマンドを実行できます。実行入力はソースPFメンバー (SRCFILE パラメーターおよび SRCMBR パラメーター) または IFS ストリーム・ファイル (SRCSTMF パラメーター) です。
RUNSQLSTM と RUNSQL の他の重要な違いは、トランザクション管理の特性です。RUNSQLSTM では、スクリプトの完了時に暗黙的 COMMIT または ROLLBACK が自動的に行われます。RUNSQL コマンドには、自動トランザクション管理が組み込まれており、アプリケーションの仕事単位で参加するよう作業範囲を指定できます。
RUNSQL を使用する場合、コマンドが進行中のコミットメント制御トランザクションに参加するかどうか検討する必要があります。参加している場合、COMMIT パラメーターで同じコミットメント制御レベルを指定します。COMMIT パラメーターの重要性を図示した 2つのコマンドを見てみましょう。
次のコマンドは、バッチ・ジョブを開始するため実行中の SBMJOB コマンドを示しています。RUNSQL コマンドは、新しいバッチ・ジョブで実行され、新しいスキーマを作成しています。
システムは律儀にスキーマを作成しますが、デフォルトの COMMIT(*CHG) コマンドを使用します。トランザクションは User Default Activation Group で開始します。新しいコレクションが作成された後、コマンドが完了したためにバッチ・ジョブは終了します。ジョブ終了中、システムは中断しているトランザクションに気付き、ロールバックしてスキーマは削除されます。
COMMIT(*NONE) をコマンド呼び出しに追加すると、コマンド完了直後に操作が固まり、新しいスキーマは損なわれません。
許可および監査
RUNSQL コマンドは、*PUBLIC 権限が *USE に設定されて出荷されています。つまり、デフォルトでシステムにいる誰もがコマンドを呼び出せるということです。DB2 for i 許可要件は、実行中の特定の SQL ステートメントに基づいて実施されます。この許可のデフォルトは、RUNSQLSTM、STRSQL、RUNQRY など SQL ステートメントの実行に使用できる他のコマンドと似ています。ある特定のコマンドを使用するため、 *PUBLIC 権限を削除することでコマンドを「ロックダウン」する手順を実施した場合、RUNSQL にも同じことを実施するかどうか検討する必要があります。
現在、我々のほとんどがセキュリティーおよび監査に高い関心があります。しかし、そのほとんどが、権限のないユーザーが新しいインターフェースを通して悪事を働く可能性があるという点については十分な関心を抱いていません。DB2 for i オブジェクトレベルの権限は、害をもたらすような試行を停止させます。ほとんどの IBM 顧客にとってさらに興味深いのは、権限の高いユーザーのアクションを追跡する機能です。どのユーザーがいつ、何を変更したか記録を取ることで、説明責任を達成できます。
この目的を達成するために、RUNSQL コマンドを「監査する」場合に使用できる手法があります (監査という言葉を引用符で囲みました。理由は、この手法は監査ジャーナルまたはオブジェクト監査に基づいていないためです)。データベース・モニター (または、System i Navigator ユーザーについては、SQL Performance Monitor) を使用して、Filter by Client Special Register Program 名として「RUNSQL」を指定することで、RUNSQL コマンドの使用状況の詳細を収集することができます。Start Database Monitor (STRDBMON) コマンドのこのフィルター手法は付加的なものです。他のフィルター・パラメーターを指定する場合、収集されたデータをすべての条件が満たされた状況にさらに制限するようコマンドに指令を出しているでしょう。STRDBMON を使用して RUNSQL コマンド使用状況をフィルターしている 2 つの例 (6.1 および 7.1) は、次のとおりです。
IBM i 6.1:
IBM i 7.1:
RUNSQL 名の正当化と罪の意識
もしあなたが、RUNSQL コマンドの名前を選ぶ担当者を探しているなら、これ以上探さないでください。Mark Anderson (DB2 for i では IBM の著名なエンジニアであり、主任アーキテクト)、Guy Vig (IBM iC の導師)、そして私が、新しい RUNSQL コマンドを設計、実装、文書化しました。私たちは他のコマンド名も検討しましたが、多くの理由で RUNSQL に落ち着きました。意味があり、 IBM i のコマンド命名ガイドラインに沿った名前が必要だったため、コマンド名の選択肢は限られていました。
IBM i コマンドは、動詞-名詞 (動詞-修飾語-名詞) という命名規則を使用して命名されているため、見つけやすく、学習しやすいという傾向があります。この命名規則は、知識を転換するきっかけを作ってくれます。言い換えれば、コマンドについて学習し、使用するほど、新しいコマンドを学習し、使用しやすくなるということです。
IBM i PTF は問題なく修正、訂正、または機能強化を提供しなければなりません。しかし RUNSQL コマンドの場合、同じ名前のコマンドを使用し、ライブラリー修飾がないコマンドを呼び出すと、そのコマンドを提供する PTF を単に適用するだけで問題が発生するおそれがあります (破損のトピックについては、次のセクションで詳しく説明します)。コマンドの使用法を分析し、コマンド・アクセスを軽減するのに余分な時間を割いていた人には、心よりお詫びします。
ユーザーへのメモ
IBM では、顧客にマイナスの影響を与える方法で IBM i OS 動作を変更しないよう、あらゆる努力を払っています。顧客の運用を中断するおそれがあるようなOS 機能の動作を変更する必要に迫られた稀なケースでは、MTU 文書を使用して情報を顧客に伝えます。IBM i 6.1 および 7.1 の MTU 文書には、新しい RUNSQL コマンドに関連した潜在的な互換性の問題に対処するための最新情報が記載されています。
RUNSQL コマンドを追加すると、既存のアプリケーションまたはスクリプトが失敗するおそれがあります。RUNSQL という名前の自分のコマンドを構築した顧客もいれば、RUNSQL という名前のコマンドが入った製品を購入した顧客もいました。いずれのシナリオでも、RUNSQL コマンドを QSYS ライブラリーに追加すると問題が発生するおそれがあります。コマンドは通常、ライブラリー修飾を使用せずに呼び出すものであり、QSYS ライブラリーは通常、ライブラリー・リストのシステム部分の最初のライブラリーであるためです。それをすべて追加し、RUNSQL という新しい IBM コマンドがどのように既存のアプリケーションを失敗させるか十分に理解できます。
MTU 文書を定期購読することができます。この文書は、IBM が必要に応じて更新する生きた文書です。定期購読すると、文書に変更があるたびに電子メール通知を受け取ります。この定期購読(サブスクリプション)は特定の IBM i OS リリースに基づいているため、アップグレード時にサブスクリプションを最新の状態にします。
さらに、さらに: RUNSQLSTM の OPTION パラメーターのすべて
読者の方々、ここまでじっくりこの記事を読んでくださり感謝しています。ざっと読み流す記事ではなかったことへのご褒美として、IBM i 6.1 および 7.1 の RUNSQLSTM の新しい Source Listing Options (OPTION) パラメーターについてお話しましょう。このパラメーターは、コマンド出力ファイルを直接制御し、呼び出し元は不要なスプール・ファイルを積み上げなくてもすみます。(OPTION パラメーターを、プロシージャー、関数、トリガーが RUNSQLSTM コマンド実行内でどのように構築されているかのみを制御する、既存の OUTPUT パラメーターと混同しないでください。)
OPTION パラメーターのヘルプ・テキストは、IBM i 6.1 および 7.1 でコマンドをプロンプト表示しても表示されません。ただし、ヘルプ・テキストは要らないことがすぐにわかると思います。コマンドのデフォルト動作は変わらないのがその理由です。OPTION(*LIST) はデフォルトで、コマンドが完了すると完全なリストがスプール・ファイルとして生成されることを示します。
図4 が示すように、*NOSRC、*ERRLIST、*NOLIST は他のパラメーター値です。
- *NOLIST は、コマンド・スクリプトまたはスプール・ファイル出力が不要な環境で役立ちます。
- *ERRLIST も同様に便利です。コマンドが QPRINT ファイルが障害に役立つ情報を含んだものと気付くよう、自分の目を鍛え直すことができるからです。
- *NOSRC は、実行された SQL ステートメントから結果メッセージを常に確認するものの、SQL ステートメント自体は確認しない場合に便利です。
図5 は、コマンド自体をプロンプト表示している場合に、新しい OPTION パラメーターをどこで見つけるかを示しています。OPTION パラメーターは、Language ID (LANGID) パラメーターの後に続いています。OPTIONS パラメーターのオプションについて、少しここで詳しく説明します。
- *LIST (デフォルト) - ソースのコンテンツおよびすべてのエラーを記載した完全なリストが生成されます。
- *NOSRC - メッセージのみ記載のリストが生成されます。
- *ERRLIST - 処理中に ERRLVL パラメーターより大きなエラーに遭遇した場合のみ、完全なリストが生成されます。
- *NOLIST - リストは生成されません。処理中に ERRLVL パラメーターより大きなエラーに遭遇した場合、メッセージがジョブ・ログに送信されます。
SQL コマンドをもっと自由に
RUNSQL コマンドは、SQL を実行するための新しい方法です。SQL を CL プログラムまたはプロシージャーに組み込んだり、SQL ステートメント・テキストのソース PF メンバーを構築せずに SQL ステートメントを実行したりする必要がある設定をする場合に、このコマンドは実にその輝きを発揮します。