埋込みSQL文およびPL/SQLブロックの構文および意味を検査することで、Pro*C/C++プリコンパイラはコーディングの誤りをすみやかに発見し修正できるように支援します。この付録では、プリコンパイラ・オプションSQLCHECKを使用して検査の種類および範囲を制御する方法を説明します。この付録の項目は、次のとおりです。
構文規則は、言語構造を並べて正しい文を作成する基準を示します。つまり、構文検査はキーワード、オブジェクト名、演算子、デリミタなどがSQL文に正しく配置されているかどうかを検証します。たとえば、次の埋込みSQL文には構文上のエラーがあります。
EXEC SQL DELETE FROM EMP WHER DEPTNO = 20; -- misspelled keyword WHERE EXEC SQL INSERT INTO EMP COMM, SAL VALUES (NULL, 1500); -- missing parentheses around column names COMM and SAL
意味上の規則は、有効な外部参照を行う方法を示しています。つまり、意味検査はデータベース・オブジェクトおよびホスト変数への参照が正しいかどうか、さらにホスト変数のデータ型が正しいかどうかを検証します。たとえば、次の埋込みSQL文には意味上のエラーがあります。
EXEC SQL DELETE FROM empp WHERE deptno = 20;
-- nonexistent table, EMPP
EXEC SQL SELECT * FROM emp WHERE ename = :emp_name;
-- undeclared host variable, emp_name
SQL構文と意味に関する規則は、『Oracle Database SQL言語リファレンス』に定義されています。
コマンドラインでプリコンパイラ・オプションのSQLCHECKを指定して、検査の種類および範囲を制御します。SQLCHECKでは、検査の種類には、構文、意味、その両方の3種類があります。検査の範囲には、次の要素を含めることができます。
データ定義文(CREATEおよびGRANTなど)
DML文(SELECTおよびINSERTなど)
PL/SQLブロック
ただし、動的SQL文は実行時まで完全に定義されないため、SQLCHECKでは動的SQL文を検査できません。
SQLCHECKについて次の値を指定できます。
SEMANTICSまたはFULL
SYNTAX
デフォルト値はSYNTAXです。
SQLCHECK=SEMANTICSの場合、プリコンパイラは次の内容について構文および意味の検査を行います。
DML文(INSERT、UPDATEなど)
PL/SQLブロック
ホスト変数のデータ型
次の構文も同様です。
データ定義文(CREATE、ALTERなど)
ただし、AT db_name句を使用するDML文に対しては構文検査のみを行います。
SQLCHECK=SEMANTICSの場合、プリコンパイラは、埋め込まれたDECLARE TABLE文を使用して、意味検査に必要な情報を入手します。ただし、コマンドラインでUSERIDオプションを指定した場合は、Oracleサーバーに接続し、そのデータ・ディクショナリにアクセスしてこの情報を入手します。データ操作文またはPL/SQLブロックで参照される表がすべてDECLARE TABLE文で定義されている場合は、Oracleサーバーに接続する必要はありません。
Oracleサーバーに接続したときに、データ・ディクショナリに一部の必要な情報が見つからない場合は、DECLARE TABLE文を使用して、欠落している情報を補充する必要があります。DECLARE TABLE文とデータ・ディクショナリの定義が矛盾する場合は、DECLARE TABLEの定義が使用されます。
ホスト・プログラム内にPL/SQLブロックを埋め込むときは、必ずSQLCHECK=SEMANTICSを指定してください。
データ操作文を検査するときに、プリコンパイラは『Oracle Database SQL言語リファレンス』に記述されている構文規則を使用しますが、意味検査にはより厳密な規則を使用します。特に、データ型のチェックは厳密に行います。その結果、SQLCHECK=SEMANTICSのときは、Oracleの以前のバージョン用に作成した既存のアプリケーションを正常にプリコンパイルできない場合があります。
新規のプログラムをプリコンパイルする場合、またはデータ型のチェックを厳密に行う場合は、SQLCHECK=SEMANTICSと指定してください。
SQLCHECK=SEMANTICSを指定すると、プリコンパイラは意味検査に必要な情報を次のどちらかの方法で入手できます。
Oracleサーバーに接続してデータ・ディクショナリにアクセスします。
埋め込まれたDECLARE TABLE文とDECLARE TYPE文を使用します。
意味検査を行うには、表、データ型、ホスト・プログラムで参照されるビューをメンテナンスするOracleデータベースにプリコンパイラを接続します。
Oracleサーバーに接続した後、プリコンパイラはデータ・ディクショナリにアクセスして必要な情報を検索します。データ・ディクショナリには、表と列の名前、表と列の制約、列の長さおよび列のデータ型などが格納されています。
プログラムが、まだ作成されていない表を参照しているなどの理由により、必要な情報の一部がデータ・ディクショナリ内で見つからない場合は、DECLARE TABLE文(この付録で後述されています)を使用して足りない情報を指定する必要があります。
Oracleサーバーに接続するには、次の構文を使用してコマンドラインでUSERIDオプションを指定します。
USERID=username/password
usernameおよびpasswordは、有効なOracleユーザーIDを構成します。パスワードを省略すると、パスワードの入力が求められます。
ユーザー名とパスワードのかわりに、次のように指定したとします。
USERID=/
プリコンパイラによりOracleサーバーへの接続が自動的に試行されます。この自動接続が成功するのは、既存のOracleユーザー名がオペレーティング・システムのIDの前に「CLUSTER$」を付けたもの、またはINIT.ORAファイル内のOS_AUTHENT_PREFIXパラメータの設定値と一致する場合のみです。たとえば、使用しているオペレーティング・システムのIDがMBLAKEであるときに、自動的に接続が成功するのはCLUSTER$MBLAKEが有効なOracleユーザー名である場合のみです。
USERIDオプションを省略した場合、プリコンパイラは埋込みDECLARE TABLE文から必要な情報を取得する必要があります。
データベースが使用不能であるなどの理由により、Oracleサーバーへの接続を試みて失敗した場合は、エラー・メッセージが発行され、プログラムはプリコンパイルされません。
プリコンパイラはOracleサーバーに接続せずに意味検査を実行できます。この検査を行うには、プリコンパイラは表およびビューに関する情報を埋込みDECLARE TABLE文から取得する必要があります。つまり、DML文またはPL/SQLブロック内で参照する表をすべてDECLARE TABLE文内で定義する必要があります。
DECLARE TABLE文の構文は、次のとおりです。
EXEC SQL DECLARE table_name TABLE (col_name col_datatype [DEFAULT expr] [NULL|NOT NULL], ...);
exprは、CREATE TABLE文で列のデフォルト値として使用できる整数です。
ユーザー定義のオブジェクト・データ型の場合、サイズは使用されないためオプションです。
DECLARE TABLEを使用して既存のデータベースの表を定義した場合、プリコンパイラはその定義に従います。このときデータ・ディクショナリの定義は無視されます。
同様に、TYPEの場合は、次の構文によるDECLARE TYPE文があります。
EXEC SQL DECLARE type TYPE [AS OBJECT (col_name col_datatype, ...)] | [AS VARRAY(size) OF element_type ]| [AS TABLE OF object_type ] ;
この文を使用すると、プリコンパイル時にSQLCHECK=SEMANTICSと指定した場合に、ユーザー定義型のより適切なタイプ・チェックを実行できます。SQLCHECK=SYNTAXと指定すると、DECLARE TYPE文はドキュメントとしてのみ動作し、コメント・アウトされて無視されます。
SQLCHECK=SYNTAXを指定すると、プリコンパイラでSQL文の構文がチェックされます。構文については、『Oracle Database SQL言語リファレンス』を参照してください。
DML文
ホスト変数表現
意味検査が実行されないため、次の制限事項が適用されます。
Oracleサーバーへの接続は行われず、USERIDは無効なオプションとなります。USERIDを指定すると、警告メッセージが発行されます。
DECLARE TABLE文とDECLARE TYPE文は無視され、ドキュメントとしてのみ機能します。
PL/SQLブロックの埋込みはできません。プリコンパイラがPL/SQLブロックを検出すると、エラー・メッセージが発行されます。
DML文をチェックする場合、プリコンパイラはOracleの構文規則を使用します。これらの規則には下位互換性があるため、プリコンパイルしたプログラムを移行するときにはSQLCHECK=SYNTAXを指定してください。
SQLCHECKオプションは、インラインまたはコマンドラインで入力できます。ただし、インラインで指定するチェックのレベルを、コマンドラインで指定する(またはデフォルトによって受け入れる)レベルよりも高くすることはできません。たとえば、SQLCHECK=SYNTAXをコマンドラインで指定した場合、インラインではSQLCHECK=SEMANTICSを指定できません。