SQL 文
この SQL 文のリストは、SQL クエリおよびその他の操作のレコードを提供しています。これには、テーブルとインデックスの定義、挿入、更新、および削除が含まれます。これらの SQL 文は、クエリ・プランにリンクされています。また、このリンクはクエリ・プランを凍結するオプションを提供します。
コンパイルされた SQL 操作ごとに SQL 文が作成されます。これにより、テーブルごと、ビューごと、またはプロシージャ名ごとに示された SQL DDL 操作および DML 操作のリストを提供します。テーブル定義を変更する場合は、この SQL 文のリストを使用して、それぞれの SQL 操作のクエリ・プランがこの DDL の変更の影響を受けるかどうかや、SQL 操作に変更が必要になるかどうかを判断できます。その後で、以下のことが可能になります。
-
それぞれの SQL 操作に、どのクエリ・プランを使用するかの判断が可能になります。テーブル定義への変更を反映するように改訂されたクエリ・プランを使用することもできます。また、現在のクエリ・プランを凍結して、テーブル定義に変更を加える前に生成したクエリ・プランを維持することもできます。
-
テーブル定義への変更に基づいて、そのテーブルに対して SQL 操作を実行するルーチンにコードの変更を加えるかどうかの判断が可能になります。
SQL 文は、テーブル定義への変更の影響を受ける可能性がある SQL ルーチンのリストです。テーブル定義やテーブル・データへの変更の履歴としては使用しないでください。
SQL 文を作成する操作
以下の SQL 操作により、対応する SQL 文が作成されます。
データ定義 (DDL) 操作:基本となる永続クラスをコンパイルすると (または更新して再コンパイルすると)、常に 1 つ以上の SQL 文が生成されます。UNIQUE や PRIMARY KEY などの制約が定義されている場合は、複数の文が定義されます。
データ管理 (DML) 操作:テーブルに対するクエリと、挿入操作、更新操作、削除操作が含まれます。埋め込み SQL のデータ管理 (DML) 操作ごとに、SQL 文が作成されます。これは、埋め込み SQL は、それを含んでいるルーチンがコンパイルされるときにコンパイルされるためです (既定の動作)。ダイナミック SQL SELECT コマンドは、クエリが準備されるときと、クエリがクエリ・キャッシュとして保存されるときに SQL 文を作成します。これにより、すべての SQL コマンドの最新のコンパイル済みバージョンのリストが作成されます。クエリが複数のテーブルを参照している場合は、参照されるすべてのテーブルを [テーブル/ビュー/プロシージャ名] 列にリストする 1 つの SQL 文が作成されます。
ほとんどの SQL 文には、クエリ・プランが関連付けられています。クエリ・プランは、作成時には凍結されていません。その後で、このクエリ・プランを凍結プランとして指定できます。クエリ・プランを持つ SQL 文には、SELECT 操作を伴う DDL コマンドと DML コマンドが含まれます。クエリプランを持たない SQL 文については、後述する “プランの状態” のセクションに示します。
SQL 文は、直前にコンパイルされたバージョンの SQL 操作のみをリストします。SQL 文が凍結されていなければ、その文は Caché によって次期バージョンに置き換えられます。そのため、ルーチン内で SQL コードを書き換えると、古い SQL コードは SQL 文から削除されます。
その他の SQL 文の操作
以下の SQL コマンドは、より複雑な SQL 文の操作を実行します。
-
ALTER TABLE:列の追加や削除では、SQL 文は作成されません。代わりに、既存の DDL SQL 文が、テーブル定義への変更を取り入れるように再コンパイルされます。列制約 (UNIQUE など) を追加しても、追加の SQL 文は作成されず、既存の DDL 文が再コンパイルされます。
-
CREATE TRIGGER:トリガが定義されたテーブルでは、トリガの定義時とトリガの起動時のどちらの場合も SQL 文は作成されません。ただし、そのトリガが別のテーブルに対して DML 操作を実行する場合は、トリガを定義することで、そのトリガのコードで変更されるテーブルに SQL 文が作成されます。[場所] には、トリガが定義されているテーブルを指定します。SQL 文は、トリガの定義時に定義されます。トリガを削除すると、その SQL 文は削除されます。トリガを起動しても、SQL 文は作成されません。
-
CREATE VIEW は、コンパイルされるものがないため、SQL 文が作成されません。また、ソース・テーブルに含まれる SQL 文のプラン・タイムスタンプが変更されることもありません。ただし、ビューの DML コマンドをコンパイルすると、そのビューに対する SQL 文が作成されます。
SQL 文のリスト
古くなっていたり、古いルーチン参照がある可能性のある SQL 文の Index エントリをクリーンアップするために、システム・タスクがすべてのネームスペースで 1 時間に 1 回、自動的に実行されます。そのため、その時間内に加えられたすべての変更が SQL 文のリストに反映されているとは限りません。管理ポータルを使用して、この毎時クリーンアップを監視したり、直ちにクリーンアップするよう強制したりできます。[システム操作]→[タスクマネージャ]→[タスクスケジュール] の順に選択してから、Cleanup SQL Statement Index タスクを選択します。
管理ポータルの SQL インタフェースから、次のように SQL 文をリストできます。
-
[SQL 文] タブ:ネームスペース内のすべての SQL 文がリストされます。リストはスキーマごとの照合シーケンスで示されてから、それぞれのスキーマ内のテーブル名/ビュー名ごとに示されます。このリストには、現在のユーザが権限を持つテーブル/ビューのみが含まれます。SQL 文が複数のテーブルを参照する場合は、参照されるすべてのテーブルが [テーブル/ビュー/プロシージャ名] 列にアルファベット順にリストされます。
列のヘッダをクリックすると、SQL 文のリストを [テーブル/ビュー/プロシージャ名]、[プランの状態]、[場所]、[SQL 文テキスト] などのリストの列でソートできます。
このタブにある [フィルタ] オプションを使用すると、リストされている SQL 文を特定のサブセットに絞り込むことができます。指定したフィルタ文字列により、SQL 文のリストに含まれるすべてのデータにフィルタが適用されます。最も役立つフィルタは、スキーマ名またはスキーマ名.テーブル名、ルーチンの場所、または SQL 文テキスト内の部分文字列に対するフィルタです。フィルタ文字列では、大文字と小文字が区別されません。クエリが複数のテーブルを参照している場合、[テーブル/ビュー/プロシージャ名] 列で参照されるテーブルを選択すると、[フィルタ] には SQL 文が含まれます。
-
[カタログの詳細] タブ:テーブルを選択して、そのテーブルのカタログ詳細を表示します。このタブには、[テーブルの SQL 文] ボタンがあり、そのテーブルに関連付けられている SQL 文を表示できます。SQL 文が複数のテーブルを参照している場合、その SQL 文は参照されるテーブルごとに [テーブルの SQL 文] リストに示されますが、[テーブル名] 列には現在選択されているテーブルのみが示されます。
列のヘッダをクリックすると、リストに含まれる任意の列でテーブルの SQL 文のリストをソートできます。
両方のリスト・インタフェースに、テーブル (またはビュー) の修飾名、プランの状態、この文を定義したルーチンの場所 (128 文字までに切り捨てられます)、および SQL 文テキストが示されます。SQL 文テキストは、正規化された形式で示されるため、後述するように、コマンド・テキストとは異なることがあります。
SQLTableStatements() カタログ・クエリまたは INFORMATION_SCHEMA.STATEMENTS を使用すると、さまざまな条件で選択した SQL 文をリストできます。詳細は、後述の "SQL 文の問い合わせ" を参照してください。
プランの状態
[プランの状態] には、以下のいずれかがリストされます。
-
未凍結:凍結されていませんが、凍結できます。
-
未凍結/並列:凍結されておらず、凍結することもできません。
-
凍結/明示的:ユーザによって凍結されていますが、未凍結にすることができます。
-
凍結/アップグレード: Caché バージョンのアップグレードによって凍結されていますが、未凍結にすることができます。
-
空欄:関連付けられたクエリ・プランがありません。
-
INSERT... VALUES() コマンドは、関連付けられるクエリ・プランがない SQL 文を作成するため、未凍結にすることも凍結することもできません ([プランの状態] 列は空欄になります)。この SQL コマンドはクエリ・プランを生成しませんが、SQL 文のリストに加えておくと便利です。こうすることで、このテーブルに対するすべての SQL 操作をすばやく見つけることができます。例えば、テーブルに列を追加する場合は、そのテーブルに対する SQL INSERT が存在する場所をすべて調べて、この新しい列が含まれるように該当するコマンドを更新する必要があります。
-
カーソル・ベースの UPDATE コマンドや DELETE コマンドには、関連付けられるクエリ・プランがありません。そのため、未凍結にすることも凍結することもできません ([プランの状態] 列は空欄になります)。DECLARE CURSOR コマンドは、クエリ・プランが関連付けられる SQL 文を生成します。カーソル (OPEN cursor、FETCH cursor、CLOSE cursor) を使用する埋め込み SQL 文は、別個の SQL 文を生成しません。カーソル・ベースの UPDATE または DELETE はクエリ・プランを生成しませんが、SQL 文のリストに加えておくと便利です。こうすることで、このテーブルに対するすべての SQL 操作をすばやく見つけることができます。
-
SQL 文テキスト
一般に、SQL 文テキストは SQL コマンドとは異なります。これは、Caché が大文字/小文字と空白を正規化するためです。それ以外の相違点は、以下のとおりです。
管理ポータル・インタフェースまたは SQL Shell インタフェースからクエリを発行すると、結果の SQL 文は、DECLARE Q1 CURSOR FOR を伴う SELECT 文が先行する点で、クエリとは異なります ("Q1" は生成されたカーソル名の一種になります)。これにより、その文テキストはダイナミック SQL クエリ・キャッシュの文テキストと照合できるようになります。
SQL コマンドで修飾されていないテーブル名またはビュー名を指定していると、結果の SQL 文には既定のスキーマ名が含まれます。
SQL 文テキストは、1,024 文字以降が切り捨てられます。完全な SQL 文テキストを確認するには、[SQL 文の詳細] を表示します。
単一の SQL コマンドが、複数の SQL 文を生成する場合があります。例えば、クエリがビューを参照する場合、[SQL 文] には、2 つの文テキストが表示されます。1 つはビュー名の下側にリストされ、もう 1 つは基になるテーブル名の下側にリストされます。どちらかの文を凍結すると、両方の文の [プランの状態] が [凍結] になります。
データ管理 (DML) SQL 文
SQL 文を作成するデータ管理言語 (DML) のコマンドは、INSERT、UPDATE、INSERT OR UPDATE、DELETE、TRUNCATE TABLE、SELECT、および DECLARE CURSOR FOR SELECT です。ダイナミック SQL や埋め込み SQL を使用すると、DML コマンドをコンパイル (または準備) できます。DML コマンドは 1 つのテーブルまたは 1 つのビューに対してコンパイルできます。Caché は対応する SQL 文を 1 つ作成します。
ダイナミック SQL が準備されるとき、または埋め込み SQL がコンパイルされるときに SQL 文が作成されますが、SQL が実行されるときには作成されません。SQL 文のタイムスタンプには、SQL コードが準備またはコンパイルされた時刻が記録されますが、そのコードが実行された時刻 (または実行されたかどうか) は記録されません。そのため、SQL 文が実際には一度も実行されたことのないテーブルへの変更を表していることがあります。
ダイナミック SQL DML コマンドを準備すると、対応する SQL 文が作成されます。この SQL 文に関連付けられている [場所] は、クエリ・キャッシュになります。ダイナミック SQL は、管理ポータル SQL インタフェースまたは SQL Shell インタフェースから SQL を実行したときや、.txt ファイルからインポートしたときに準備されます。未凍結のクエリ・キャッシュを削除すると、対応する SQL 文が削除されます。凍結されたクエリ・キャッシュを削除すると、対応する SQL 文の [場所] の値が削除されます。SQL 文は、凍結されていないときに削除されます。
非カーソル埋め込み SQL データ管理言語 (DML) コマンドをコンパイルすると、対応する SQL 文が作成されます。埋め込み SQL DML コマンドごとに、対応する SQL 文が作成されます。1 つのルーチンに複数の埋め込み SQL コマンドが含まれている場合は、それぞれの埋め込み SQL コマンドごとに個別の SQL 文が作成されます(一部の埋め込み SQL コマンドは、複数の SQL 文を作成します)。SQL 文リストの [場所] 列には、埋め込み SQL を含んでいるルーチンが明示されます。この方法で、SQL 文は埋め込み SQL DML コマンドごとのレコードを維持します。
非カーソル・ベースの埋め込み SQL データ管理言語 (DML) コマンドをコンパイルすると、DECLARE CURSOR の SQL 文がクエリ・プランと共に作成されます。関連する埋め込み SQL 文 (OPEN cursor、FETCH cursor、CLOSE cursor) により、個別の SQL 文が生成されることはありません。FETCH cursor に続く、関連する UPDATE table WHERE CURRENT OF cursor または DELETE FROM table WHERE CURRENT OF cursor は個別の SQL 文を生成しますが、個別のクエリ・プランは生成しません。
リテラル値を挿入する INSERT コマンドは、[プランの状態] 列が空白の SQL 文を作成します。このコマンドはクエリ・プランを作成しないため、SQL 文を凍結することはできません。
埋め込み SQL を含んでいるルーチンの変更
埋め込み SQL を含んでいるルーチンをコンパイルすると、それぞれの SQL コマンドは、そのルーチンの文ディクショナリのエントリとして記録されます。ルーチンを変更して再コンパイルすると、Caché は、すべてのテーブルから、そのルーチンの以前の文ディクショナリのエントリをすべて削除して、現在の埋め込み SQL の内容に対応する新しいエントリを作成します。再コンパイルされたルーチンに埋め込み SQL が含まれていなかった場合は、以前の SQL 文は削除されますが、新しい SQL 文は追加されません。そのため、既定では、ルーチン内の直前にコンパイルしたバージョンの埋め込み SQL が SQL 文として保持されます。
再コンパイルによる SQL 文の削除や置換が行われないようにするには、SQL 文を凍結プランとして指定します。これにより、その文のクエリ・プランを維持できるようになります。それ以降のルーチンの SQL コードへの変更は、凍結された SQL 文に影響を及ぼしません。
SELECT コマンド
クエリをコンパイル (または準備) すると、対応する SQL 文が作成されます。これは、単純な SELECT 操作、または CURSOR ベースの SELECT/FETCH 操作になります。クエリは、テーブルまたはビューに対して発行できます。
-
JOIN を含んでいるクエリは、各テーブルにまったく同じ SQL 文を作成します。[場所] は、各テーブルのリストに含まれる同一のストアド・クエリになります。[文は以下のリレーションを使用します] には、"SQL 文の詳細" の "[ルーチン] セクションと [リレーション] セクション" で説明するように、すべてのテーブルがリストされます。
-
select-item サブクエリを含んでいるクエリは、各テーブルにまったく同じ SQL 文を作成します。[場所] は、各テーブルのリストに含まれる同一のストアド・クエリになります。[文は以下のリレーションを使用します] には、"SQL 文の詳細" の "[ルーチン] セクションと [リレーション] セクション" で説明するように、すべてのテーブルがリストされます。
-
外部 (リンクされた) テーブルを参照するクエリは凍結できません。
-
FROM 節に %PARALLEL キーワードを含んでいるクエリは、複数の SQL 文を作成することがあります。%PARALLEL クエリの SQL 文は凍結できません。
-
FROM 節を含んでいないためにテーブルを参照しないクエリも、SQL 文を作成します。例えば、SELECT $LENGTH('this string') は、[テーブル] 列の値が %TSQL_sys.snf の SQL 文を作成します。
SQL 文の詳細
SQL 文テキストをクリックすると、[SQL 文の詳細] ボックスが表示されます。このボックスを使用して、プランを凍結または凍結解除できます。
完全な文テキスト、クエリ・プラン、およびクエリ・プランを凍結または未凍結にするボタンに加えて、このボックスには以下の情報が含まれています。
-
パフォーマンス統計 ([文の詳細] セクションに含まれる)
[文の詳細] セクション
[文の詳細] セクション:
-
[文ハッシュ]:文定義の内部ハッシュ表現です。これは、SQL 文 Index のキーとして使用されます (内部使用専用)。
-
[タイムスタンプ]:最初のタイムスタンプは、プランが作成されたときのものです。このタイムスタンプは、凍結/凍結解除の後に更新され、プランが未凍結になった時刻が記録されます (プランが再コンパイルされた時刻ではありません)。凍結解除のタイムスタンプを表示するには、[ページの更新] ボタンのクリックが必要になることがあります。文を含んでいるルーチン/クラスの日付/時刻値を [プラン・タイムスタンプ] と比較することで、ルーチン/クラスが再コンパイルされた場合に、同じクエリ・プランを使用していないことを確認できます。
-
[バージョン]:プランを作成した際の Caché バージョン。[プランの状態] が [凍結/アップグレード] の場合は、Caché の前のバージョン。クエリ・プランを未凍結にすると、[プランの状態] は [未凍結] に変化し、[プランのバージョン] は現在の Caché バージョンに変化します。
-
[プランの状態]:[凍結/明示的]、[凍結/アップグレード]、[未凍結]、または [未凍結/並列]。[凍結/明示的] は、この文のプランがユーザの明示的な操作によって凍結されていて、この SQL 文を生成したコードへの変更にかかわらず、この凍結プランがクエリ・プランとして使用されることを表しています。[凍結/アップグレード] は、この文のプランが Caché バージョンのアップグレードによって自動的に凍結されていることを表しています。[未凍結] は、現在、プランが凍結されていないことと、凍結される可能性があることを表しています。[未凍結/並列] は、プランが凍結されていないことと、%PARALLEL 処理を使用するために凍結できないことを表しています。NULL (空) のプランの状態は、関連付けられているクエリ・プランが存在しないことを表します。
-
Natural Query:クエリが "ナチュラル・クエリ" かどうかを示すブーリアン・フラグ。チェックを付けると、クエリはナチュラル・クエリになり、クエリ・パフォーマンス統計は記録されません。チェックを外すと、パフォーマンス統計が記録される可能性があります。実際に統計が記録されるかどうかは他の要素によって決まります。ナチュラル・クエリは、統計を記録するオーバーヘッドがクエリ・パフォーマンスに影響するほど単純な埋め込み SQL クエリとして定義されています。クエリが既に非常に単純であるため、ナチュラル・クエリの統計を保持する利点はありません。わかりやすいナチュラル・クエリの例として、SELECT Name INTO :n FROM Table WHERE %ID=? が挙げられます。このクエリの WHERE 節は等値条件になります。このクエリには、ループやインデックスの参照がありません。ダイナミック SQL クエリ (クエリ・キャッシュ) には、ナチュラル・クエリとしてフラグが設定されることはありません。クエリ・キャッシュについては、統計が記録されることも記録されないこともあります。
-
このセクションには、5 つのクエリ・パフォーマンス統計のフィールドも含まれています。これらのフィールドについては、以下のセクションで説明します。
パフォーマンス統計
クエリを実行すると、パフォーマンス統計が対応 SQL 文に追加されます。この情報は、最も遅いクエリと実行回数が最も多いクエリを確認するために使用できます。この情報を使用して、最適化によってパフォーマンスを大幅に向上できるクエリを特定できます。
SQL 文の名前、プランの状態、場所、およびテキストの他に、以下の追加情報がキャッシュ・クエリに提供されます。
-
Count:このクエリが実行された回数の整数値。このクエリのクエリ・プランが異なるものになる変更が行われると (テーブルにインデックスを追加するなど)、この数はリセットされます。
-
Average Count:このクエリが 1 日に実行される平均回数。
-
Total Time:このクエリの実行にかかった時間 (秒)。
-
Average Time:このクエリの実行にかかった平均時間 (秒)。クエリがキャッシュ・クエリの場合、初めてクエリを実行したときにかかる時間は、次回以降にそのクエリ・キャッシュから最適化されたクエリを実行する際にかかる時間よりも大幅に長い可能性が高いです。
-
Std Dev:合計時間と平均時間の標準偏差。クエリを 1 回だけ実行した場合の標準偏差は 0 です。クエリを多数回実行すると、一般的に、数回だけ実行した場合よりも標準偏差は低下します。
-
Date first seen: クエリが初めて実行されたときの日付。これは、クエリが準備された日時である [最終コンパイル日時] とは異なります。
クエリ・パフォーマンス統計は、完了したクエリ実行を反映するために、定期的に更新されます。これによって、これらの統計を維持する際のオーバーヘッドが最小化されます。結果として、現在実行中のクエリは、クエリ・パフォーマンス統計には反映されません。完了したばかりのクエリ (おおむね 1 時間以内) は、クエリ・パフォーマンス統計にすぐに反映されない場合があります。
Caché では、%PARALLEL サブクエリのパフォーマンス統計は個別には記録されません。%PARALLEL サブクエリの統計は、外側のクエリの統計と共に合計されます。並列で実行するために実装によって生成されたクエリには、個々に追跡されるパフォーマンス統計はありません。
Caché では、"ナチュラル" クエリのパフォーマンス統計は記録されません。統計を収集した場合、クエリのパフォーマンスが低下します。また、ナチュラル・クエリは既に最適であるため、さらに最適化される可能性はありません。
これらのクエリ・パフォーマンス統計は、管理ポータルの SQL インタフェースから [このネームスペースの SQL 文] タブに表示できます。この SQL 文のリストは任意の列で並べ替えることができます。これによって、例えば、平均時間が最大のクエリを簡単に特定できます。
"SQL 文の問い合わせ" で説明されているように、INFORMATION.SCHEMA.STATEMENTSOpens in a new tab クラス・プロパティをクエリすることによって、これらのクエリ・パフォーマンス統計にアクセスできます。
[コンパイル設定] セクション
[コンパイル設定] セクション:
-
[選択モード]:文がコンパイルされたときの SelectMode。DDL コマンドの場合は、常に Runtime になります。DML コマンドの場合は、#SQLCompile Select を使用して設定できます。既定値は Logical です。#SQLCompile Select=Runtime の場合は、$SYSTEM.SQL.SetSelectMode() の呼び出しにより、クエリ結果セットの表示を変更できますが、[選択モード] の値は変更されません (Runtime のままになります)。
-
[既定のスキーマ]:文がコンパイルされたときに設定された既定のスキーマ。DDL コマンドの場合は、実際に使用されたスキーマになります。DML コマンドの場合は、コマンドを発行したときに効力のあったシステム既定のスキーマになります。
-
[スキーマ・パス]:文がコンパイルされたときに定義したスキーマのパス。 DDL コマンドの場合は、常に空白になります。DML コマンドの場合は、#SQLCompile Path を使用して設定した文字列になります。
[ルーチン] セクションと [リレーション] セクション
[文は以下のルーチンで定義されています] セクション:
-
[ルーチン]:テーブル (DDL の場合)、クエリ・キャッシュ (ダイナミック SQL DML の場合)、またはルーチン名 (埋め込み SQL DML の場合) に関連付けられたクラス名。
-
[タイプ]:[クラスメソッド] または [MAC ルーチン] (埋め込み SQL DML の場合)。
-
[最終コンパイル日時]:ルーチンの最終コンパイル日時または準備日時。SQL 文が凍結されていない場合は、MAC ルーチンを再コンパイルすることで、このタイムスタンプと [プランのタイムスタンプ] の両方が更新されます。SQL 文が凍結されている場合は、MAC ルーチンを再コンパイルすることで、このタイムスタンプのみが更新されます。[プラン・タイムスタンプ] はプランの凍結を解除するまで変更されません。その後、[プラン・タイムスタンプ] にはプランの凍結を解除した時刻が表示されます。
[文は以下のリレーションを使用します] セクションには、クエリ・プランの作成に使用された 1 つ以上の定義済みテーブルがリストされます。別のテーブルから値を抽出するクエリを使用する INSERT や、別のテーブルを参照する FROM 節を使用する UPDATE または DELETE の場合、ここには両方のテーブルがリストされます。それぞれのテーブルについて、以下の値がリストされます。
-
[テーブル名またはビュー名]:テーブルまたはビューの修飾名。
-
[タイプ]:[テーブル] または [ビュー]。
-
[最終コンパイル日時]:テーブル DDL が最後にコンパイルされた日時。
-
[クラス名]:テーブルに関連付けられているクラス名。
このセクションには、クラスを再コンパイルするためのオプションがあります。未凍結のプランを再コンパイルすると、3 つの時刻フィールドのすべてが更新されます。凍結プランを再コンパイルすると、2 つの [最終コンパイル日時] フィールドが更新されますが、[プラン・タイムスタンプ] は更新されません。プランの凍結を解除して、[ページの更新] ボタンをクリックすると、[プラン・タイムスタンプ] はプランの凍結を解除した時刻に更新されます。
データ定義 (DDL) SQL 文
テーブルを作成すると、対応する永続クラスがコンパイルされるため、1 つ以上の SQL 文が作成されます。ビューを作成しても、永続クラスは作成されないため、SQL 文も作成されません。
SQL テーブルは、永続クラスとして定義するか、埋め込み SQL またはダイナミック SQL から SQL CREATE TABLE コマンドを使用して定義することで作成できます。テーブルの作成方法にかかわらず、対応する SQL 文が 1 つ以上作成されます。[場所] には、テーブル定義に関連付けられたクラス名を指定されます。
テーブルの作成時に、Caché SQL はビットマップ・エクステント・インデックスを定義します。そのときに、対応する SQL 文が以下に示すように作成されます。
DECLARE QEXTENT CURSOR FOR SELECT ID FROM SAMPLE . SQLTEST
テーブル定義を変更すると、既存のテーブル作成 SQL 文が再コンパイルされます。
インデックスを作成するときに、テーブル・クラス定義を変更したり、SQL CREATE INDEX コマンドを発行したりすると、以下に示すように、Caché は作成したインデックスごとに対応する SQL 文を保存します。SQL 文は、作成したインデックスのタイプにかかわらず同じものになります。1 つのフィールドに対して複数のタイプのインデックスを作成しても、追加の SQL 文は保存されません。
SELECT %ID INTO :id FROM SAMPLE . SQLTEST WHERE ( :K1 IS NOT NULL AND LASTNAME = :K1 ) OR ( :K1 IS NULL AND LASTNAME IS NULL )
また、インデックスを追加すると、すべてのテーブル作成 SQL 文が再コンパイルされ、それらすべてのプラン・タイムスタンプが、その他のインデックスに対する SQL 文も含めて更新されます。DROP INDEX は、この SQL 文を削除して、残りの DDL SQL 文のすべてが再コンパイルされるようにし、プラン・タイムスタンプを更新します。
主キー制約または一意制約を定義すると、Cache は主キー・インデックスを定義するため、前述したような SQL 文を作成します。前述した 2 つの SQL 文に加えて、Caché は以下の 4 つの文を追加します (この例では、LastName フィールド)。
SELECT 1 AS _PASSFAIL FROM SAMPLE . SQLTEST WHERE LASTNAME = :pValue(1) AND %ID <> :id SELECT LASTNAME INTO :tCol1 FROM SAMPLE . SQLTEST WHERE %ID = :pID DECLARE EXT CURSOR FOR SELECT %ID INTO :tID FROM SAMPLE . SQLTEST SELECT %ID INTO :id FROM SAMPLE . SQLTEST WHERE LASTNAME = :%d(2)
それぞれの追加の UNIQUE フィールドにより、WHERE 節で UNIQUE フィールド (この例では、SSN フィールド) を指定する、以下に示すような SQL 文がさらに 3 つ追加されます。
SELECT %ID INTO :id FROM SAMPLE . SQLTEST WHERE ( :K1 IS NOT NULL AND SSN = :K1 ) OR ( :K1 IS NULL AND SSN IS NULL ) SELECT 1 AS _PASSFAIL FROM SAMPLE . SQLTEST WHERE SSN = :pValue(1) AND %ID <> :id SELECT %ID INTO :id FROM SAMPLE . SQLTEST WHERE SSN = :%d(3)
また、以下に示すように、追加の UNIQUE フィールドを含めるように後続の文が変更されます。
SELECT SSN , LASTNAME INTO :tCol2 , :tCol1 FROM SAMPLE . SQLTEST WHERE %ID = :pID
テーブルの削除と SQL 文
テーブルが削除されると、凍結されていない ([プランの状態] が [未凍結] の) すべての SQL 文 が削除されます。凍結された文 ([プランの状態] が [凍結/明示的] の文) は削除されませんが、[テーブル/ビュー/プロシージャ名] 列は変更されます (例:SAMPLE.MYTESTTABLE - Deleted?? Sample.Person)。削除されたテーブルの名前はすべて大文字に変換され、"Deleted??" のフラグが設定されます。DDL 文の [場所] 列は、テーブルが削除されているために空白になります。ダイナミック SQL DML 文の [場所] 列は、テーブルに関連付けられているすべてのクエリ・キャッシュが自動的に削除されたために空白になります。
SQL 文の問い合わせ
SQLTableStatements()Opens in a new tab ストアド・クエリを使用すると、特定のテーブルの SQL 文を返すことができます。以下に例を示します。
ZNSPACE "Samples"
SET mycall = "CALL %Library.SQLTableStatements('Sample','Person')"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus=tStatement.%Prepare(mycall)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET rset=tStatement.%Execute()
IF rset.%SQLCODE '= 0 {WRITE "SQL error=",rset.%SQLCODE QUIT}
DO rset.%Display()
INFORMATION_SCHEMA パッケージのテーブルを使用すると、SQL 文のリストを問い合わせることができます。Caché では以下のクラスがサポートされています。
-
INFORMATION_SCHEMA.STATEMENTS:現在のネームスペース内で現在のユーザがアクセス可能な SQL 文の Index エントリを格納しています。
-
INFORMATION_SCHEMA.STATEMENT_LOCATIONS:SQL 文が呼び出された各ルーチンの場所を格納しています。永続クラス名またはクエリ・キャッシュ名です。
-
INFORMATION_SCHEMA.STATEMENT_RELATIONS:SQL 文で使用される各テーブルまたはビューのエントリを格納しています。
これらのクラスを使用したサンプル・クエリを以下に示します。
以下の例では、ネームスペース内のすべての SQL 文が返され、ハッシュ値 (正規化された SQL 文を一意に識別する計算 ID)、凍結状態フラグ (0 ~ 3 の値)、文が準備されプランが保存されたときのローカル・タイムスタンプ、および文のテキスト自体がリストされます。
SELECT Hash,Frozen,Timestamp,Statement FROM INFORMATION_SCHEMA.STATEMENTS
以下の例では、すべての凍結プランの SQL 文が返され、プランが凍結されていなかった場合とは違ったものになっているかどうかが示されます。未凍結文は Frozen=0 または Frozen=3 になる場合があることに注意してください。単一行 INSERT などの凍結できない文の場合、Frozen 列には NULL が表示されます。
SELECT Frozen,FrozenDifferent,Timestamp,Statement FROM INFORMATION_SCHEMA.STATEMENTS
WHERE Frozen=1 OR Frozen=2
以下の例では、特定の SQL テーブルについて、すべての SQL 文と、その文が含まれているルーチンを返します(テーブル名 (SAMPLE.PERSON) には、SQL 文テキストで使用されているものと同じ文字種 (すべて大文字) を使用する必要があります)。
SELECT Statement,Frozen,STATEMENT_LOCATIONS->Location AS Routine,STATEMENT_LOCATIONS->Type AS RoutineType
FROM INFORMATION_SCHEMA.STATEMENTS
WHERE STATEMENT_RELATIONS->Relation='SAMPLE.PERSON'
以下の例では、現在のネームスペース内で凍結されたプランを持っているすべての SQL 文を返します。
SELECT Statement,Frozen,Frozen_Different,STATEMENT_LOCATIONS->Location AS Routine,STATEMENT_LOCATIONS->Type AS RoutineType
FROM INFORMATION_SCHEMA.STATEMENTS
WHERE Frozen=1 OR Frozen=2
以下の例では、現在のネームスペース内で COUNT(*) 集約関数を含んでいるすべての SQL 文を返します(文テキスト (COUNT ( * )) は、SQL 文テキストで使用されているものと同じ空白を指定する必要があります)。
SELECT Statement,Frozen,STATEMENT_LOCATIONS->Location AS Routine,STATEMENT_LOCATIONS->Type AS RoutineType
FROM INFORMATION_SCHEMA.STATEMENTS
WHERE Statement [ ' COUNT ( * ) '