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 ROLE

○※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 ROLE

○※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記述領域」を参照してください。