SQL Server 2000 でテーブル変数にインデックスを作成できますか?
すなわち
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
に索引を作成できますName
か?
SQL Server 2000 でテーブル変数にインデックスを作成できますか?
すなわち
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
に索引を作成できますName
か?
この質問には SQL Server 2000 というタグが付けられていますが、最新バージョンで開発している人々のために、最初に取り上げます。
SQL Server 2014
以下で説明する制約ベースのインデックスを追加する方法に加えて、SQL Server 2014 では、テーブル変数宣言でインライン構文を使用して一意でないインデックスを直接指定することもできます。
そのための構文例を以下に示します。
/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);
フィルター処理されたインデックスと含まれる列を含むインデックスは現在、この構文で宣言できませんが、SQL Server 2016 ではこれがさらに緩和されています。CTP 3.1 から、テーブル変数のフィルター選択されたインデックスを宣言できるようになりました。RTM では、インクルードされた列も許可される場合があるかもしれませんが、現在の位置は、 「リソースの制約により、SQL16 に含まれない可能性が高い」ということです。
/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)
SQL Server 2000 ~ 2012
名前にインデックスを作成できますか?
簡単な答え: はい。
DECLARE @TEMPTABLE TABLE (
[ID] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
UNIQUE NONCLUSTERED ([Name], [ID])
)
より詳細な回答は以下にあります。
SQL Server の従来のテーブルは、クラスター化されたインデックスを持つことも、ヒープとして構造化することもできます。
クラスター化されたインデックスは、一意として宣言してキー値の重複を禁止するか、デフォルトで非一意に設定することができます。一意でない場合、SQL Server は重複キーに一意化子を暗黙的に追加して、それらを一意にします。
非クラスター化インデックスも一意として明示的に宣言できます。それ以外の場合、SQL Serverは行ロケーター(ヒープのクラスター化インデックス キーまたはRID ) を (重複だけでなく) すべてのインデックス キーに追加します。
UNIQUE
SQL Server 2000 ~ 2012 では、テーブル変数のインデックスは、 orPRIMARY KEY
制約を作成することによってのみ暗黙的に作成できます。これらの制約タイプの違いは、主キーが null 非許容列にある必要があることです。一意の制約に参加している列は、NULL 可能である可能性があります。(ただし、s が存在する場合の SQL Server の一意の制約の実装はNULL
、SQL 標準で指定されているものではありません)。また、テーブルは 1 つの主キーしか持てませんが、一意の制約は複数持つことができます。
これらの論理的な制約は両方とも、一意のインデックスを使用して物理的に実装されています。明示的に指定されていない場合はPRIMARY KEY
、クラスター化されたインデックスとクラスター化されていない一意の制約になりますが、この動作は指定するか、制約宣言を使用して明示的にオーバーライドできますCLUSTERED
(NONCLUSTERED
構文例)
DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)
上記の結果として、SQL Server 2000 ~ 2012 のテーブル変数に次のインデックスを暗黙的に作成できます。
+-------------------------------------+-------------------------------------+
| Index Type | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index | Yes |
| Nonunique Clustered Index | |
| Unique NCI on a heap | Yes |
| Non Unique NCI on a heap | |
| Unique NCI on a clustered index | Yes |
| Non Unique NCI on a clustered index | Yes |
+-------------------------------------+-------------------------------------+
最後のものは少し説明が必要です。この回答の冒頭にあるテーブル変数の定義では、一意ではない非クラスター化インデックスが一意のインデックスでName
シミュレートされます (とにかく、SQL Server がクラスター化インデックス キーを非一意の NCI キーにサイレントに追加することを思い出してください)。Name,Id
一意でないクラスター化インデックスはIDENTITY
、一意化子として機能する列を手動で追加することによっても実現できます。
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
ただし、これはすべての行に "Uniqueifier" を追加するため、非一意のクラスター化インデックスが実際に SQL Server に実装される方法の正確なシミュレーションではありません。それを必要とする人だけではありません。