テーブルにインデックスを定義します。
Synopsis
CREATE [UNIQUE | BITMAP] INDEX index-name
ON [TABLE] table-name (column-name [ASC | DESC], ...)
CREATE INDEX コマンドは特権を必要とする操作です。
CREATE INDEX を使用する前に、%ALTER_TABLE 管理者特権または指定されたテーブルに対する %ALTER 特権があることを確認する必要があります。特権がない場合は、SQLCODE 99 エラー (特権違反) が返されます。適切な特権を持っている場合は、
GRANT コマンドを使用してこのような特権を割り当てることができます。
インデックス名は、指定されたテーブル内では一意の必要があります。インデックス名は、
識別子規約に従い、以下の制限を受けます。既定のインデックス名は、簡単な識別子です。インデックス名は、128 文字を超えることはできません。
Caché は、("SqlName" と呼ばれる) 入力された名前を使用して、クラスおよびグローバル内で対応するインデックス名を生成します。このインデックス名には英数字 (文字と数字) のみを使用でき、最大長は 31 文字です。Caché は、まず入力された SqlName から句読点を削除し、31 文字 (以内) の一意の識別子を生成して、一意にするために必要であれば 31 番目の文字を大文字に置き換えて、インデックス名を生成します。
-
インデックス名は、フィールド、テーブル、ビューと同じ名前にすることができますが、このような名前の重複はお勧めできません。
-
インデックス名には、最低でも 1 字は英字が必要です。インデックス名の先頭の字または最初の句読点の後ろの字は、文字にする必要があります。有効な文字は、
$ZNAME テストに合格する文字です。
-
生成されたインデックス名には句読点が含まれないため、句読点のみが異なるインデックス名の作成は可能ですがお勧めできません。
-
インデックス名は 31 文字よりも大幅に長くすることができますが、最初の 31 文字の英数字と異なるインデックス名にすると作業が簡単になります。
既存インデックスと同じ名前のインデックスを作成する場合に何が起こるかは、以下に説明しています。
既定で Caché は、テーブルに既存インデックスと同じ名前のインデックスを作成することを拒否し、SQLCODE -324 エラーを返します。この振る舞いは以下のように構成可能です。
-
ObjectScript $SYSTEM.SQL.SetDDLNo324() 関数を呼び出します。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings() を呼び出します。これにより、
[SQLCODE=-324 エラーの抑制] の設定が表示されます。
-
既定は
偽 (false) (0) です。既定で Caché は、テーブルに既存インデックスと同じ名前のインデックスを作成することを拒否し、SQLCODE -324 エラーを返します。ここでは、この設定を推奨します。
ただし、このオプションが既存インデックスの再作成を許可するように設定されていても、テーブルにデータが格納されている場合は、IDKEY インデックスの再作成はできません。これを実行しようとすると、SQLCODE -324 エラーが返されます。
UNIQUE キーワードを使用して、インデックス内の各レコードが一意の値を持つよう指定できます。具体的には、インデックス内に (つまり、インデックスがあるテープル内に) 同じ
照合された値を持つレコードは存在しないよう指定できます。既定では、大半のインデックスは、(大文字小文字に関係なく検索するように) 大文字の照合を使用します。この場合、
Smith と
SMITH は等しい値であり、それぞれ一意的ではありません。
インデックス照合および SQL クエリで大文字と小文字を区別するようにするには、以下の Caché ObjectScript コマンドを使用します。
WRITE $$SetEnvironment^%apiOBJ("collation","%String","SQLSTRING")
システム管理ポータルで
[クラス] オプションを選択します。次にストアド・クエリのネームスペースを選択し、
[コンパイル] オプションを使用して対応するクラスをリコンパイルします。その後すべてのインデックスを再構築します。これで大文字と小文字が区別されるようになります。
BITMAP キーワードを使用する場合、このインデックスは、ビットマップ・インデックスであることを指定できます。ビットマップ・インデックスは、ビットマップ (圧縮 2 進数) でインデックスされた値に対応し、行の ID リストを維持します。SQL クエリ・プロセッサは、セット演算を使用して制限を実行するビットマップ・インデックスを利用できます。このため、AND と OR 論理演算子を使用して、(
WHERE 節の) テーブル制限を実行できます。これは、INSERT、UPDATE、DELETE 演算子をビットマップで実行するか通常のインデックスで実行するかでは大差ありません。ビットマップ・インデックスは、既定構造 (
%CacheStorage) を使用するテーブルに対してのみ定義でき、システムが割り当てた数値列 ID (例えば、IDKEY 機能を使用しないなど) を持ちます。テーブルの作成に (クラス定義の使用と反対に) DDL を使用する場合、これらの要件に合致し、ビットマップ・インデックスを有効に利用できます。
CREATE INDEX 文を使用してインデックスの生成を行うと自動的にインデックスが構築されます。しかし、インデックスを明示的に再構築することが必要になる場合もあります。
テーブルのインデックスを再構築するには、以下の Caché ObjectScript コマンドを実行します。
DO ##class(myclass).%PurgeIndices()
DO ##class(myclass).%BuildIndices()
また以下の例のように、特定のインデックスを削除または再構築することもできます。
DO ##class(myclass).%PurgeIndices($ListBuild("NameIDX","AgeIDX"))
DO ##class(myclass).%BuildIndices($ListBuild("NameIDX","AgeIDX"))
壊れたインデックスの削除または再構築、ビットマップ・インデックスの再圧縮、あるいはインデックスの大文字・小文字の区別の設定変更を行うこともできます。
システム管理ポータルを使用して、特定のクラス (テーブル) のインデックスをすべて再構築することもできます。
以下の埋め込み SQL の例では、Fred という名前のテーブルを作成してから、Fred テーブルの
Lastword 列と
Firstword 列に対して (入力された名前 "Fred_Index" から句読点を削除して) "FredIndex" というインデックスを作成します。
&sql(CREATE TABLE Fred (
TESTNUM INT NOT NULL,
FIRSTWORD CHAR (30) NOT NULL,
LASTWORD CHAR (30) NOT NULL,
CONSTRAINT FredPK PRIMARY KEY (TESTNUM))
)
IF SQLCODE=0 { WRITE !,"Table created" }
ELSEIF SQLCODE=-201 { WRITE !,"Table already exists" }
ELSE { WRITE !,"SQL table create error code is: ",SQLCODE
QUIT }
&sql(CREATE INDEX Fred_Index
ON TABLE Fred
(LASTWORD,FIRSTWORD))
IF SQLCODE=-324 {
WRITE !,"Index already exists"
QUIT }
ELSEIF SQLCODE=0 { WRITE !,"Index created" }
ELSE { WRITE !,"SQL index create error code is: ",SQLCODE
QUIT }
以下の例は、Staff テーブルの
City 列に対して、"CityIndex" という名前のインデックスを作成します。
CREATE INDEX CityIndex ON Staff (City)
以下の例は、Staff テーブルの
EmpName 列に対して、"EmpIndex" という名前のインデックスを作成します。列内に同一の値を持つ行を避けるために、UNIQUE 制約を使用します。
CREATE UNIQUE INDEX EmpIndex ON TABLE Staff (EmpName)
以下の例は、Purchase テーブルの
SKU 列に対して、"SKUIndex" という名前のビットマップ・インデックスを作成します。BITMAP キーワードは、コードがビットマップ・インデックスであることを示します。
CREATE BITMAP INDEX SKUIndex ON TABLE Purchases (SKU)