UNIQUE 制約と CHECK 制約は、SQL Server テーブルでデータ整合性を適用するために使用できる 2 種類の制約です。 これらは重要なデータベース オブジェクトです。
このトピックは、次のセクションで構成されています。
UNIQUE 制約
制約とは、SQL Server データベース エンジンによって適用される規則です。 たとえば、UNIQUE 制約を使用して、主キーに含まれていない特定の列に重複する値が入力されないようにすることができます。 UNIQUE 制約と PRIMARY KEY 制約の両方で一意性が適用されますが、主キーではない列の一意性または列の組み合わせを強制する場合は、PRIMARY KEY 制約の代わりに UNIQUE 制約を使用します。
PRIMARY KEY 制約とは異なり、UNIQUE 制約では値 NULL を使用できます。 ただし、UNIQUE 制約に含まれる値と同様に、列ごとに 1 つの null 値のみが許可されます。 UNIQUE 制約は FOREIGN KEY 制約によって参照できます。
UNIQUE 制約がテーブル内の既存の列に追加されると、既定では、データベース エンジンは列内の既存のデータを調べて、すべての値が一意であることを確認します。 重複する値を持つ列に UNIQUE 制約が追加された場合、データベース エンジンはエラーを返し、制約は追加しません。
データベース エンジンは、UNIQUE 制約の一意性要件を適用する UNIQUE インデックスを自動的に作成します。 したがって、重複する行を挿入しようとすると、UNIQUE 制約に違反し、テーブルに行が追加されないことを示すエラー メッセージがデータベース エンジンから返されます。 クラスター化インデックスが明示的に指定されていない限り、UNIQUE 制約を適用するために、一意の非クラスター化インデックスが既定で作成されます。
CHECK 制約
CHECK 制約では、1 つ以上の列で受け入れられる値を制限することで、ドメインの整合性が強制されます。 論理演算子に基づいて TRUE または FALSE を返す任意の論理 (ブール) 式で CHECK 制約を作成できます。 たとえば、 給与 列の値の範囲を制限するには、$15,000 から $100,000 の範囲のデータのみを許可する CHECK 制約を作成します。 これにより、この一定の給与範囲を超える給与を入力できなくなります。 論理式は、 salary >= 15000 AND salary <= 100000
になります。
1 つの列に複数の CHECK 制約を適用できます。 テーブル レベルで作成することで、1 つの CHECK 制約を複数の列に適用することもできます。 たとえば、複数列のCHECK制約を使用して、country_region 列の値がUSAの場合に、州列に2文字の値があることを確認できます。 これにより、1 か所で複数の条件をチェックできるようになります。
CHECK 制約は、列に配置される値を制御するという点で FOREIGN KEY 制約に似ています。 違いは、どの値が有効であるかを判断する方法にあります。FOREIGN KEY 制約は別のテーブルから有効な値のリストを取得し、CHECK 制約は論理式から有効な値を決定します。
注意事項
暗黙的または明示的なデータ型変換を含む制約により、特定の操作が失敗する可能性があります。 たとえば、パーティション切り替えのソースであるテーブルに定義されているこのような制約により、ALTER TABLE...SWITCH 操作が失敗します。 制約の定義ではデータ型を変換しないようにしてください。
CHECK 制約の制限事項
CHECK 制約は、FALSE に評価される値を拒否します。 NULL 値は UNKNOWN と評価されるため、式内に存在すると制約がオーバーライドされる可能性があります。 たとえば、MyColumn に値 10 のみを含めることができる (MyColumn=10) ことを指定して、int
列 MyColumn に制約を配置するとします。
MyColumn に値 NULL を挿入すると、データベース エンジンは NULL を挿入し、エラーを返しません。
CHECK 制約は、チェック中の条件がテーブル内の行に対して FALSE でない場合に TRUE を返します。 CHECK 制約は行レベルで機能します。 作成したばかりのテーブルに行がない場合、このテーブルの CHECK 制約は有効と見なされます。 この場合、次の例に示すような予期しない結果が生成されることがあります。
CREATE TABLE CheckTbl (col1 int, col2 int);
GO
CREATE FUNCTION CheckFnctn()
RETURNS int
AS
BEGIN
DECLARE @retval int
SELECT @retval = COUNT(*) FROM CheckTbl
RETURN @retval
END;
GO
ALTER TABLE CheckTbl
ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() >= 1 );
GO
追加する CHECK
制約では、テーブル CheckTbl
に 1 行以上の行が格納されていなければならないことを指定します。 ただし、この制約の条件を確認する対象となる行がテーブル内にないため、ALTER TABLE ステートメントは成功します。
CHECK 制約は、DELETE ステートメント中は検証されません。 そのため、特定の種類の check 制約を持つテーブルに対して DELETE ステートメントを実行すると、予期しない結果が発生する可能性があります。 たとえば、テーブル CheckTbl
で次のステートメントを実行するとします。
INSERT INTO CheckTbl VALUES (10, 10);
GO
DELETE CheckTbl WHERE col1 = 10;
DELETE
制約では、テーブル CHECK
に CheckTbl
行以上が格納されていなければならないことを指定していますが、1
ステートメントは成功します。
関連タスク
注
テーブルがレプリケーション用にパブリッシュされている場合は、ALTER TABLE または SQL Server 管理オブジェクト (SMO) Transact-SQL ステートメントを使用してスキーマを変更する必要があります。 テーブル デザイナーまたはデータベース ダイアグラム デザイナーを使用してスキーマを変更すると、テーブルの削除と再作成が試みられます。 パブリッシュされたオブジェクトを削除できないため、スキーマの変更は失敗します。
課題 | トピック |
---|---|
UNIQUE 制約の作成方法について説明します。 | 一意の制約を作成する |
UNIQUE 制約の変更方法について説明します。 | UNIQUE 制約の変更 |
UNIQUE 制約の削除方法について説明します。 | UNIQUE 制約の削除 |
レプリケーション エージェントによってテーブルのデータが挿入または更新された場合に CHECK 制約を無効にする方法について説明します。 | レプリケーションの CHECK 制約の無効化 |
テーブルに対してデータの追加、更新、または削除を行う際に、CHECK 制約を無効にする方法について説明します。 | INSERT ステートメントまたは UPDATE ステートメントによる CHECK 制約の無効化 |
制約式を変更するか、または特定条件の制約を有効または無効にするオプションを変更する方法について説明します。 | CHECK 制約の変更 |
CHECK 制約の削除方法について説明します。 | CHECK 制約の削除 |
CHECK 制約のプロパティを表示する方法について説明します。 | UNIQUE 制約と CHECK 制約 |