CHAPTER 5: ダイナミック SQL




5.1 はじめに

多くのデータベースアプリケーションでは、データベース上で 実行する処理は前もって知らされています。また、アプリケーションを 作成する場合は、おそらくあらかじめテーブルの名前や各テーブルの アトリビュート名およびその数は知っているはずです。 これらを知っていることは、アプリケーションに必要である正確なSQL文を書く ことが可能であり、そのSQL はアプリケーションの実行中では変更する必要がありません。 このようなアプリケーションは、スタティック(静的)SQLステートメント (つまり、ステートメントは変更できない)をアプリケーションに埋め込み、 プリコンパイラによって C のルーチンに変換し、実現します。

しかし、ある環境下ではプリコンパイルする前にSQLステートメントの正確な 構成を知ることができない場合があります。 このようなアプリケーションでは、 実行時に SQL ステートメントを作成し、処理することができなければなりません。 このようなステートメントは、 アプリケーションの実行中に変更することができるため、 ダイナミック(動的な)SQLステートメントといえます。 また、これらのステートメントは C のルーチンにプリコンパイルすることができないため、 アプリケーション実行中に構文解析され、実行されます。

コマンドについては、前の章のスタテック SQL コマンドにおいて記述しましたが、 ダイナミック SQL コマンドは、 別の章として"ダイナミック SQL コマンドリファレンス"で記述されています。

5.1.1 ダイナミック vs スタテック SQL

スタテック SQL ステートメントの構成は、 プリコンパイラがステートメントを解析し、C ルーチンに置き換えることにより、 プリコンパイルする時点でわかっています。 ステートメントの構造は、実行時に変更はできませんが、 テーブル(またはビュー)やアトリビュートの名前は変更することは可能です。 また、埋め込み SQL ステートメントが テーブルやアトリビュート名をプログラム中に埋め込む(ハードコーディング)代わりに 変数を使用する場合、 WHERE句中の実行時に比較するためのアトリビュートとその値 にも変数を使用することができます。 この場合は、実行時にSQLの解析は行われません。

以下の例ではスタテック SQL を使用し、変数を埋め込むことができます。 (変数名の前には":"が付けられます。)

   SELECT :att1, :att2 FROM :tab1 WHERE :att1 = :val1;

しかし、例えば、 アクセスするためにアトリビュートの数や また、ジョインをするためのテーブル数を知らない場合は ダイナミック SQL ステートメントを使用する必要があります。

ダイナミック SQL を使用したアプリケーションは、 スタテックSQL を使用したものに比べ、さらに用途は広く利用できます。 実行時にダイナミック SQL ステートメントは作成されるため、 アプリケーションの稼動中にそれを変更することができます。

ダイナミック SQL は実行時に文字列からステートメントを作成します。 例えば、 検索するアトリビュートやWHERE句を指定することをユーザーに行わせる場合に、 ユーザーによってキーボードから入力される一部のステートメント含む 文字列からSELECTステートメントを作成することができます。

ダイナミック SQL は、柔軟性を提供しますが、それに対し、 SQLステートメントを作成することは複雑なコーディングが 必要な場合があります。 ダイナミック SQL ステートメントは実行時にSQL の構文解析が行われるため 通常、スタティク SQL ステートメントに比べ処理時間が多少かかります。

以下のすべての条件に適合した場合、スタティク SQL を使用してください。

上記の条件に適合しない場合は、ダイナミックSQLを使用してください。

アプリケーションはスタティクおよびダイナミックコマンドの両方を 混ぜて使用することができます。



5.2 ダイナミックSQLの変数

スタティク SQL では、 埋め込み変数のC のデータタイプは Empressのデータタイプと対応されています。 不正なデータタイプを使用した場合、間違った結果を得ます。 例えば、C の 4 バイトのinteger 変数を使用して、 EmpressINTEGER値(2バイトからなる)を読む場合、 呼んだ値は正しくありません。

ダイナミック SQL では、 Empressは、要求されたどのようなデータタイプの変換も実行します。 例えば、 EmpressDECIMALデータタイプのアトリビュート値に C の float 変数を割り当てるために使用することができ、 Empress は、floatの値の変換を試みます。 この値がアトリビュートの有効な範囲以外の値である場合は 変換は失敗します。 ただし、制御変数のデータタイプは、常に C の short integer である必要があります。

任意のEmpressデータタイプを取得や値を割り当てるために 文字列を使用することができます。 この場合、Empressはデータとして外部フォーマットを使用します。



5.3 予約キーワード

以下のキーワード(大文字と小文字のどのような組み合わせでもよい) は埋め込み SQL 変数の名前として使用することはできませんが、 これらは、他の目的では使用することができます。(例えば通常の C 変数、関数名など)

- * +
= ? ADD
ADMIN AFTER AGGREGATE
ALIAS ALL ALLOCATE
ALTER AND ANY
AS ASC ASCENDING
AT ATTR ATTRIBUTE
BEFORE BEGIN BETWEEN
BODY BTREE BY
BYPASS BYPASS_LOCK CALL
CASCADE CHANGE CHECK
CHECKSUM COMMENT COMPARISON
CONSTRAINT CONVERT CORRESPONDING
COUNT CREATE CROSS
CURRENT DATABASE DB
DBA DECLARE DELETE
DESC DESCENDING DIRECT_FROM
DIRECT_INTO DIRECT_ONTO DISABLE
DISPLAY DISTINCT DOUBLE
DROP DUMP EACH
EDIT EMPTY ENABLE
END EQUALITY ESCAPE
EXCEPT EXCL EXCLUSIVE
EXECUTE EXISTS EXIT
EXPRESSION FOR FOREIGN
FROM FULL FUNCTION
GENERAL GENERIC GRANT
GROUP HAVING IN
INCL INCLUSIVE INDEX
INFIX INNER INOUT
INSERT INTERSECT INTO
IS JOIN LANGUAGE
LEFT LEVEL LIKE
LIST LOCATE LOCK
MASTER MASTERS MINUS
MODE MODULE NATURAL
NOT NULL OF
OJ ON ONTO
OPERATOR OPTION OR
ORDER OUT OUTER
PARAMETER POSTFIX PREFIX
PRIMARY PRINT PRIORITY
PRIV PRIVILEGE PROCEDURE
RANGE REFER REFERENCES
REFERENTIAL RENAME REPLICATE
REPLICATES REPLICATION REPORT
RESTRICT RETURNS REVOKE
RIGHT ROLE ROUTINE
ROW RUN SELECT
SET SOME SORT
SQL STOP STYLE
SUBSET TABLE TIMESERIES
TO TRIGGER TRIGGERS
UNION UNIQUE UNSET
UPDATE USER USING
VALUES VIEW WHEN
WHERE WIDTH WITH
WORKSPACE WRAPMARGIN {
{D {TS }

加えて、開発者は以下の標準 SQL キーワードを使用しないことを強く推奨します。

type
indicator
length
name
data

これらは現在のEmpress埋め込み SQLでの予約キーワードではありませんが、 将来、キーワードとなる可能性があります。