C 構文およびセマンティックのチェック

埋込みSQL文およびPL/SQLブロックの構文および意味を検査することで、Pro*C/C++プリコンパイラはコーディングの誤りをすみやかに発見し修正できるように支援します。この付録では、プリコンパイラ・オプションSQLCHECKを使用して検査の種類および範囲を制御する方法を説明します。この付録の内容は次のとおりです。

C.1 構文検査と意味検査

構文規則は、言語要素を並べて正しい文を作成する基準を示します。つまり、構文検査はキーワード、オブジェクト名、演算子、デリミタなどが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言語リファレンスに定義されています。

C.2 チェックの種類および範囲の制御について

コマンドラインでプリコンパイラ・オプションのSQLCHECKを指定すると、検査の種類および範囲を制御します。SQLCHECKでは、チェックの種類に構文、セマンティック、あるいはその両方のいずれかを指定できます。検査の範囲には、次の要素を含めることができます。

  • データ定義文(CREATEおよびGRANTなど)

  • DML文(SELECTおよびINSERTなど)

  • PL/SQLブロック

ただし、動的SQL文は実行時まで完全に定義されないため、SQLCHECKでは動的SQL文を検査できません。

SQLCHECKについて次の値を指定できます。

  • SEMANTICSまたはFULL

  • SYNTAX

デフォルト値はSYNTAXです。

SQLCHECKを使用しても、データ制御、カーソル制御、動的SQL文に対する通常の構文検査には影響しません。

C.3 SQLCHECK=SEMANTICSの指定について

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と指定してください。

C.3.1 意味検査の使用許可について

SQLCHECK=SEMANTICSを指定すると、プリコンパイラは意味検査に必要な情報を、次の方法のどれかで入手できます。

  • Oracleサーバーに接続してデータ・ディクショナリにアクセスします。

  • 埋め込まれたDECLARE TABLE文とDECLARE TYPE文を使用します。

C.3.1.1 Oracleサーバーへの接続について

意味検査を行うには、表、データ型、ホスト・プログラムで参照されるビューをメンテナンスする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サーバーへの接続を試みて失敗した場合は、エラー・メッセージが発行され、プログラムはプリコンパイルされません。

C.3.1.2 DECLARE TABLEの使用方法について

プリコンパイラは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を使用して既存のデータベースの表を定義した場合、プリコンパイラはその定義に従います。このときデータ・ディクショナリの定義は無視されます。

C.3.1.3 DECLARE TYPEの使用について

同様に、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文はドキュメントとしてのみ動作し、コメント・アウトされて無視されます。

C.4 SQLCHECK=SYNTAXの指定について

SQLCHECK=SYNTAXを指定すると、プリコンパイラでSQL文の構文がチェックされます。構文については、Oracle Database SQL言語リファレンスを参照してください。

  • DML文

  • ホスト変数表現

意味検査が実行されないため、次の制限事項が適用されます。

  • Oracleサーバーへの接続は行われず、USERIDは無効なオプションとなります。USERIDを指定すると、警告メッセージが発行されます。

  • DECLARE TABLE文とDECLARE TYPE文は無視され、ドキュメントとしてのみ機能します。

  • PL/SQLブロックの埋込みはできません。プリコンパイラがPL/SQLブロックを検出すると、エラー・メッセージが発行されます。

DML文をチェックする場合、プリコンパイラはOracleの構文規則を使用します。これらの規則には下位互換性があるため、プリコンパイルしたプログラムを移行するときにはSQLCHECK=SYNTAXを指定してください。

C.5 SQLCHECKオプションの入力について

SQLCHECKオプションは、インラインまたはコマンドラインで入力できます。ただし、インラインで指定するチェックのレベルを、コマンドラインで指定する(またはデフォルトによって受け入れる)レベルよりも高くすることはできません。たとえば、SQLCHECK=SYNTAXをコマンドラインで指定した場合、インラインではSQLCHECK=SEMANTICSを指定できません。