ドキュメントの構文に載ってないけどなんか出来たのでメモ。
SQL Server での unique 制約は unique index で実現されてます。
なので、unique 制約を作る = unique index を作る です。
UNIQUE 制約を作る場合
Create Unique Constraints - SQL Server | Microsoft Docs
後から UNIQUE INDEX 作る場合
Create Unique Indexes - SQL Server | Microsoft Docs
filtered ってなんやーですが、SQL Server では index を作る時に条件指定して index を作ることが出来ます。
Create Filtered Indexes - SQL Server | Microsoft Docs
特定の状態のデータに対して index を作りたい場合に使う感じ。
これを利用すると、複数行に null が含む列に対して unique 制約を付けることも出来ます。*1
で、create table の時にまとめて作るのはドキュメントでは出来なさそうだけど、何か書けたのでメモ。
CREATE TABLE (Transact-SQL) - SQL Server | Microsoft Docs
ドキュメントに無い構文だけど、エラーが出なかったクエリ例
create table [サンプル] (
[有効なデータでは一意なId] bigint not null,
[状態] nchar(2) not null,
index [UX_サンプル_Id] unique ([有効なデータでは一意なId]) where [状態] = N'有効'
)
ドキュメントでは
< table_constraint > ::=
[ CONSTRAINT constraint_name ]
{
{ PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
(column [ ASC | DESC ] [ ,...n ] )
[
WITH FILLFACTOR = fillfactor
|WITH ( <index_option> [ , ...n ] )
]
[ ON { partition_scheme_name (partition_column_name)
| filegroup | "default" } ]
| FOREIGN KEY
( column [ ,...n ] )
REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ] ( logical_expression )
< table_index > ::=
{
{
INDEX index_name [ CLUSTERED | NONCLUSTERED ]
(column_name [ ASC | DESC ] [ ,... n ] )
| INDEX index_name CLUSTERED COLUMNSTORE
| INDEX index_name [ NONCLUSTERED ] COLUMNSTORE (column_name [ ,... n ] )
}
[ WITH ( <index_option> [ ,... n ] ) ]
[ ON { partition_scheme_name (column_name )
| filegroup_name
| default
}
]
[ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]
}
ってなってるので、constraint で unique 付ける場合に where は指定出来ないとなってるし、
index の方では、unique 指定出来ないし where もダメってなってる。
普通に unique index を作る場合は、
create unique index [UX_サンプル_Id] on [サンプル] ([有効なデータでは一意なId]) where [状態] = N'有効'
って構文なので、unique の位置が変わるのは注意点?
ただ、ドキュメントに載ってないのでどのバージョンで使えるのかは動かしてみないと分からない。。
とりあえず SQL Server 2016、SQL Database v12 では動いてる。
SQL DB v12 で動いてるから、新しい SQL Server なら問題なさそう。