这个问题被标记为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)添加到所有索引键(不仅是重复的),这再次确保了它们是唯一的。
在SQL Server 2000-2012中,只能通过创建UNIQUE
or PRIMARY KEY
约束隐式创建表变量的索引。这些约束类型之间的区别在于,主键必须位于不可为空的列上。参与唯一约束的列可以为空。(尽管SQL Server在存在NULL
s 的情况下对唯一约束的实现不符合SQL标准中指定的约束)。此外,表只能具有一个主键,但可以具有多个唯一约束。
这两个逻辑约束都通过唯一索引在物理上实现。如果未明确指定,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 |
+-------------------------------------+-------------------------------------+
最后一个需要一些解释。在此答案开头的表变量定义中,on上的非唯一非聚集索引Name
是由on上的唯一索引模拟的Name,Id
(请记住,SQL Server 始终会默默地将聚集索引键添加到非唯一NCI密钥)。
非唯一聚集索引也可以通过手动添加IDENTITY
列以充当唯一符来实现。
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
但是,这不是对非唯一聚集索引通常在SQL Server中通常如何实际实现的准确模拟,因为这会将“唯一标识符”添加到所有行。不仅仅是那些需要它的人。