3.2.5 静的SQLと動的SQL
UAPを作成するとき,プログラム中にSQLを記述する方法を静的SQLといいます。これに対し,UAPを作成するとき,プログラム中にSQLを記述しないで,UAP実行時にSQLの文字列を組み立てる方法を動的SQLといいます。
静的SQLと動的SQLとでは,実行時の特徴が異なりますので,UAPを作成する前に十分検討する必要があります。
- 〈この項の構成〉
(1) 実行時の相違点
静的SQLと動的SQLの実行時の特徴を次の表に示します。
- 注※
-
同じ文字列のSQLを複数回実行するようなケースでは,処理効率は良くなります。
(2) 実行時に指定できる値
静的SQLの実行では,実行時に挿入値,更新値,及び探索条件の値を変更できます。また,動的SQLの実行では,静的SQLの実行時に変更できる値以外に,表名,列名,条件式などSQLの任意の部位を変更できます。
静的SQLの場合と動的SQLの場合とで,各々実行時に変更できる値の例を次の図に示します。なお,枠で囲んである部分が値を変更できる箇所です。
(3) 動的SQLの実行と留意点
動的SQLは,静的SQLと比較して探索条件を変更するときの自由度は大きいが,条件を変更するたびにSQLを実行しなければならないため,あらかじめ実行時の性能(処理効率)を考慮する必要があります。
(a) 動的SQLの前処理と実行
動的SQLでは,UAP実行時にPREPARE文で前処理してから実行します。実行は,前処理するSQLが動的SELECT文か動的SELECT文以外かで異なります。前処理するSQLが動的SELECT文の場合,OPEN文,FETCH文,及びCLOSE文で実行し,前処理するSQLが動的SELECT文以外の場合,EXECUTE文で実行します。また,EXECUTE IMMEDIATE文を使用すれば,前処理と実行を一度にできます。値を変えて同じSQLを動的に実行する場合,前処理を何度も実行するより,?パラメタを使用して,前処理を一度だけして,実行時に?パラメタに与える値を変えて実行する方が性能(処理効率)が向上します。?パラメタの詳細については,マニュアル「HiRDB SQLリファレンス」を参照してください。
動的SQLの実行形態を次の図に示します。
- 注※
-
埋込み変数(:XCMND)は,埋込みSQL宣言節で宣言しておいてください。
埋込み変数については,マニュアル「HiRDB SQLリファレンス」を参照してください。
PREPARE文で前処理できるSQLとEXECUTE IMMEDIATE文で前処理と実行が一度にできるSQLを次の表に示します。
- (凡例)
-
○:使用できます。 ×:使用できません。
- 注
-
埋込み変数を含むSQLは,動的に実行できないので,?パラメタを使用してください。?パラメタの詳細については,マニュアル「HiRDB SQLリファレンス」を参照してください。
- 注※1
-
カーソルを使用した操作はできません。
- 注※2
-
INTO句を含まないようにしてください。
- 注※3
-
EXECUTE文で実行してください。
- 注※4
-
OPEN文,FETCH文,及びCLOSE文で実行してください。
動的に指定された表にデータを挿入する場合の例を次の図に示します。
(b) EXECUTE文とEXECUTE IMMEDIATE文の使い分け
EXECUTE IMMEDIATE文は,PREPARE文とEXECUTE文を連続して実行するのと同じです。ただし,同じSQLを何度も繰り返して実行する場合,EXECUTE IMMEDIATE文でその都度前処理するより,PREPARE文で前処理してからEXECUTE文で繰り返して実行する方が性能(処理効率)が良くなります。
(c) 前処理するSQLが動的SELECT文の場合の動的実行
前処理するSQLが動的SELECT文か動的SELECT文以外かで異なります。前処理するSQLが動的SELECT文の場合,OPEN文,FETCH文,及びCLOSE文で実行し,前処理するSQLが動的SELECT文以外の場合,EXECUTE文で実行します。前処理するSQLが動的SELECT文の場合の動的実行例を,次の図に示します。
(d) 動的SELECT文に対する,カーソルを使用したSQLの動的実行
動的SELECT文を前処理し,その動的SELECT文に対するカーソルを使用したSQLを,動的に実行する場合,カーソル宣言で宣言したカーソルは使用しません。この場合,前処理した動的SQL文に対してALLOCATE CURSOR文で割り当てたカーソルを使用します。動的SELECT文に対して,カーソルを使用したSQLを動的に実行する場合の例を次に示します。
PREPARE GLOBAL :SEL FROM :XCMND; .................. 埋込み変数(:XCMND)に設定された 動的SELECT文に,拡張文名 (:SEL='SEL1')を付けます。 ALLOCATE GLOBAL :CR CURSOR FOR GLOBAL :SEL; ....... 拡張文名(:SEL='SEL1')が識別する 問合せに対して,カーソル (:CR='CR1')を割り当てます。 PREPARE UPD1 FROM 'UPDATE SET C1=? WHERE CURRENT OF GLOBAL CR1'; .. カーソル(CR1)を使用したUPDATE文 を前処理し,SQL文識別子(UPD1)を 付けます。 OPEN GLOBAL :CR; .................................. カーソル(:CR='CR1')を開きます。 FETCH GLOBAL :CR INTO :XKEKKA; .................... カーソル(:CR='CR1')を使用した 検索結果を埋込み変数(:XKEKKA)に 読み込みます。 EXECUTE UPD1 USING :XDATA; ........................ 前処理したSQL文識別子(UPD1)の UPDATE文を実行します。このとき, ?パラメタに対応する埋込み変数 (:XDATA)を指定します。 CLOSE GLOBAL :CR; ................................. カーソル(:CR='CR1')を閉じます。
(e) 動的SQLの実行時に決定した情報の受け取り
UAPで動的にSQLを実行した場合,実行時に決定した情報(データ受け渡し領域の個数,属性,番地など)をHiRDBに通知するための領域としてSQL記述領域が使用されます。また,SQL記述領域は,動的に実行するためにPREPARE文で前処理するSQLの検索項目の情報を,次のどちらかの方法で受け取れます。
-
DESCRIBE文を実行する。
-
PREPARE文実行時に,OUTPUT,及びINPUTを指定し実行する(この場合,DESCRIBE文を実行しなくても,PREPARE文実行時に情報の受け取りもできるため,通信回数を削減できます)。
DESCRIBE文については,マニュアル「HiRDB SQLリファレンス」を参照してください。また,SQL記述領域の使用例については,「SQL記述領域」を参照してください。