Hitachi

ノンストップデータベース HiRDB Version 10 UAP開発ガイド


3.2.5 静的SQLと動的SQL

UAPを作成するとき,プログラム中にSQLを記述する方法を静的SQLといいます。これに対し,UAPを作成するとき,プログラム中にSQLを記述しないで,UAP実行時にSQLの文字列を組み立てる方法を動的SQLといいます。

静的SQLと動的SQLとでは,実行時の特徴が異なりますので,UAPを作成する前に十分検討する必要があります。

〈この項の構成〉

(1) 実行時の相違点

静的SQLと動的SQLの実行時の特徴を次の表に示します。

表3‒4 静的SQLと動的SQLの実行時の特徴

種 類

長  所

短 所

静的SQL

同一のUAPを繰り返し実行する場合,一度実行したSQL文は実行形式に変換され,共用メモリ上で再利用できるため,処理効率が良い。

UAP中にSQLを埋め込むので,探索条件の変更が限定される。

動的SQL

実行時にSQLの文字列を組み立てるため,探索条件を変更するときの自由度が大きい。

実行するたびにSQLを解析して実行形式に変換するため,処理効率が悪い。

注※

同じ文字列のSQLを複数回実行するようなケースでは,処理効率は良くなります。

(2) 実行時に指定できる値

静的SQLの実行では,実行時に挿入値,更新値,及び探索条件の値を変更できます。また,動的SQLの実行では,静的SQLの実行時に変更できる値以外に,表名,列名,条件式などSQLの任意の部位を変更できます。

静的SQLの場合と動的SQLの場合とで,各々実行時に変更できる値の例を次の図に示します。なお,枠で囲んである部分が値を変更できる箇所です。

図3‒2 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の実行形態を次の図に示します。

図3‒3 動的SQLの実行形態

[図データ]

注※

埋込み変数(:XCMND)は,埋込みSQL宣言節で宣言しておいてください。

埋込み変数については,マニュアル「HiRDB SQLリファレンス」を参照してください。

PREPARE文で前処理できるSQLとEXECUTE IMMEDIATE文で前処理と実行が一度にできるSQLを次の表に示します。

表3‒5 PREPARE文で前処理できるSQLとEXECUTE IMMEDIATE文で前処理と実行が一度に実行できるSQL

分類

SQL文

PREPARE

EXECUTE

IMMEDIATE

操作系 SQL

ASSIGN LIST文

※3

CALL

※3

DELETE※1

※3

準備可能動的DELETE文:位置付け

DROP LIST文

※3

INSERT

※3

PURGE TABLE

※3

1行SELECT※2

※3

動的SELECT

※4

×

UPDATE※1

※3

準備可能動的UPDATE文:位置付け

代入文

※3

×

制御系 SQL

CALL COMMAND

COMMIT

×

×

CONNECT

×

×

DISCONNECT

×

×

LOCK TABLE

※3

ROLLBACK

×

×

SET SESSION AUTHORIZATION文

※3

×

定義系 SQL

ALTER INDEX

※3

ALTER PROCEDURE

※3

ALTER ROUTINE

※3

ALTER TABLE

※3

ALTER TRIGGER

※3

COMMENT

※3

CREATE AUDIT

※3

CREATE CONNECTION SECURITY

※3

CREATE FUNCTION

※3

CREATE INDEX

※3

CREATE PROCEDURE

※3

CREATE SCHEMA

※3

CREATE SEQUENCE

※3

CREATE TABLE

※3

CREATE TRIGGER

※3

CREATE TYPE

※3

CREATE VIEW

※3

DROP AUDIT

DROP CONNECTION SECURITY

※3

DROP DATA TYPE

※3

DROP FUNCTION

※3

DROP INDEX

※3

DROP PROCEDURE

※3

DROP SCHEMA

※3

DROP SEQUENCE

※3

DROP TABLE

※3

DROP TRIGGER

※3

DROP VIEW

※3

GRANT

※3

REVOKE

※3

(凡例)

○:使用できます。 ×:使用できません。

埋込み変数を含むSQLは,動的に実行できないので,?パラメタを使用してください。?パラメタの詳細については,マニュアル「HiRDB SQLリファレンス」を参照してください。

注※1

カーソルを使用した操作はできません。

注※2

INTO句を含まないようにしてください。

注※3

EXECUTE文で実行してください。

注※4

OPEN文,FETCH文,及びCLOSE文で実行してください。

動的に指定された表にデータを挿入する場合の例を次の図に示します。

図3‒4 動的に指定された表にデータを挿入する例

[図データ]

(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文の場合の動的実行例を,次の図に示します。

図3‒5 前処理する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記述領域」を参照してください。