D 構文および意味検査
埋込みSQL文およびPL/SQLブロックの構文および意味を検査すると、Oracleプリコンパイラはコーディングの誤りをすみやかに発見し修正できるよう支援します。この付録では、プリコンパイラ・オプションのSQLCHECKを使用して検査の種類および範囲を制御する方法を説明します。
内容は次のとおりです。
D.1 構文および意味検査の基礎
構文規則は、言語要素を並べて正しい文を作成する基準を示します。つまり、構文検査はキーワード、オブジェクト名、演算子、デリミタなどがSQL文に正しく配置されていることを検証します。PL/SQLブロックからコールされたプロシージャおよび関数にも適用されます。たとえば、次の埋込みSQL文には構文上のエラーがあります。
* -- misspelled keyword WHERE EXEC SQL DELETE FROM EMP WERE DEPTNO = 20 END-EXEC. * -- missing parentheses around column names COMM and SAL EXEC SQL INSERT INTO EMP COMM, SAL VALUES (NULL, 1500) END-EXEC.
意味上の規則は、有効な外部参照を行う方法を示しています。つまり、意味検査では、データベース・オブジェクトおよびホスト変数への参照が正しいこととホスト変数のデータ型が正しいことを検証します。たとえば、次の埋込みSQL文には意味上のエラーがあります。
* -- nonexistent table, EMPP EXEC SQL DELETE FROM EMPP WHERE DEPTNO = 20 END-EXEC. * -- undeclared host variable, EMP-NAME EXEC SQL SELECT * FROM EMP WHERE ENAME = :EMP-NAME END-EXEC.
SQL構文および意味の規則の定義は、『Oracle Database SQL言語リファレンス』を参照してください。
D.2 検査の種類および範囲の制御
コマンドラインでプリコンパイラ・オプションのSQLCHECKを指定すると、検査の種類および範囲を制御します。SQLCHECKでは、検査の種類は、構文、または構文および意味の2種類があります。検査の範囲には、DML文とPL/SQLブロックを含めることができます。ただし、動的SQL文は実行時まで完全に定義されないため、SQLCHECKで動的SQL文はチェックできません。
SQLCHECKについて次の値を指定できます。
-
SEMANTICS | FULL
-
SYNTAX | LIMITED
値SEMANTICSとFULLは等価で、SYNTAXとLIMITEDも等価です。デフォルト値はSYNTAXです。
D.3 SQLCHECK=SEMANTICSの指定
SQLCHECK=SEMANTICSの場合、プリコンパイラは次の内容について構文および意味の検査を行います。
-
INSERT文やUPDATE文などのDML文。
-
PL/SQLブロック。
ただし、AT db_name句を使用するDML文については、意味検査のみが行われます。
プリコンパイラは、意味検査に必要な情報を、埋め込まれたDECLARE TABLE文から取得します。また、オプションUSERIDが指定されている場合は、データベースに接続してデータ・ディクショナリにアクセスするとこの情報を取得します。
データベースに接続し、データ・ディクショナリで表情報が検出されない場合は、DECLARE TABLE文を使用し、不足している情報を提供する必要があります。DECLARE TABLE文とデータ・ディクショナリの定義が矛盾する場合は、DECLARE TABLEの定義が使用されます。
DML文を検査する場合、プリコンパイラは『Oracle Database SQL言語リファレンス』 に掲載されているOracleの構文規則を使用しますが、意味検査にはさらに厳密な規則を使用します。その結果、SQLCHECK=SEMANTICSのときは、Oracleの以前のバージョン用に作成した既存のアプリケーションを正常にプリコンパイルできない場合があります。
新しいプログラムをプリコンパイルするときは、SQLCHECK=SEMANTICSを指定してください。ホスト・プログラム内にPL/SQLブロックを埋め込むときは、必ずSQLCHECK=SEMANTICSを指定してください。
D.3.1 意味検査の有効化
-
Oracleに接続し、そのデータ・ディクショナリにアクセス
-
埋込みDECLARE TABLE文を使用
D.3.1.1 Oracleへの接続
意味検査を行うために、プリコンパイラはホスト・プログラム内で参照される表およびビューの定義が保存されているデータベースに接続できます。接続した後、プリコンパイラはデータ・ディクショナリにアクセスして必要な情報を探します。データ・ディクショナリには、表および列の名前、表および列の制約、列の長さ、列のデータ型などが格納されています。
必要な情報の一部をデータ・ディクショナリ内で検出できない場合(たとえば、プログラムが未作成の表を参照するときなど)は、DECLARE TABLE文を使用して足りない情報を指定する必要があります。
データベースに接続するには、次の構文を使用して、コマンドラインでUSERIDオプションを指定します。
USERID=username/password
usernameおよびpasswordは有効なOracleユーザーIDを構成します。パスワードを省略すると、パスワードの入力が求められます。仮に、ユーザー名とパスワードのかわりに、次のように指定したとします。
USERID=/
プリコンパイラは、自動的に次のユーザーIDを使用してデータベースに接続しようとします。
<prefix><username>
prefixは初期化パラメータOS_AUTHENT_PREFIXの値(デフォルト値はOPS$)、usernameはオペレーティング・システムのユーザー名またはタスク名です。
(データベースが使用不能などの理由で)接続に失敗すると、プリコンパイラは処理を停止し、エラー・メッセージを発行します。オプションUSERIDが指定されないと、プリコンパイラは埋込みDECLARE TABLE文から必要な情報を取得することになります。
D.3.1.2 DECLARE TABLEの使用方法
プログラムで無名PL/SQLブロックからストアド・プロシージャまたは関数をコールしないかぎり、プリコンパイラはデータベースに接続しなくても意味検査を実行できます。プリコンパイラは、意味検査に必要な表やビューに関する情報を、埋込みDECLARE TABLEディレクティブから取得する必要があります。つまり、DML文またはPL/SQLブロック内で参照する表をすべてDECLARE TABLE文内で定義する必要があります。
DECLARE TABLE文の構文は次のとおりです。
EXEC SQL DECLARE table_name TABLE (col_name col_datatype [DEFAULT expr] [NULL|NOT NULL], ...) END-EXEC.
exprは、CREATE TABLE文でデフォルトの列値として使用できる任意の式です。col_datatypeは、Oracleの列宣言です。整数のみ使用することができ、式は使用できません。「DECLARE TABLE(Oracle埋込みSQLディレクティブ)」を参照してください。
DECLARE TABLEを使用して既存のデータベースの表を定義した場合、プリコンパイラはその定義に従います。このときデータ・ディクショナリの定義は無視されます。