次の方法で共有


CHECK 制約

CHECK 制約は、列に格納できる値を制限することによってドメイン整合性を強制します。列に格納される値を制御するという点では、FOREIGN KEY 制約に似ています。異なる点は、有効な値を決定する方法です。FOREIGN KEY 制約では別のテーブルから有効な値の一覧が取得されますが、CHECK 制約では別の列のデータとは無関係な論理式から有効な値が決定されます。たとえば、salary 列の値の範囲は、$15,000 ~ $100,000 のデータのみを許容する CHECK 制約を作成することにより制限できます。これにより、この一定の給与範囲を超える給与を入力できなくなります。

論理演算子に基づいて TRUE または FALSE を返す論理 (ブール) 式を使って CHECK 制約を作成できます。前述の給与範囲の例で使用する論理式は、salary >= 15000 AND salary <= 100000 になります。

複数の CHECK 制約を 1 つの列に適用できます。テーブル レベルで CHECK 制約を作成すると、1 つの CHECK 制約を複数の列に適用できます。たとえば、複数列の CHECK 制約を使用して、country/region 列の値が USA であるいずれかの行の state 列に 2 文字の値が格納されているかどうかを確認できます。これにより、1 か所で複数の条件をチェックできるようになります。

注記注意

暗黙的または明示的なデータ型の変換が含まれる制約により、特定の操作が失敗することがあります。たとえば、パーティションの切り替え元のテーブルに定義された制約により、ALTER TABLE...SWITCH 操作が失敗することがあります。制約の定義ではデータ型を変換しないようにしてください。

CHECK 制約の制限事項

CHECK 制約は、FALSE と評価された値を拒否します。NULL 値は UNKNOWN と評価されるので、式に NULL 値が含まれていると制約が無効になる場合があります。たとえば、int 型の列 MyColumn に、MyColumn には値 10 (MyColumn=10) しか格納できないことを指定する制約を適用したとします。MyColumn に値 NULL を挿入すると、NULL が追加され、エラーは返されません。

CHECK 制約は、チェックしている条件がテーブルのすべての行に対して FALSE でない場合、TRUE を返します。作成したばかりのテーブルに行が含まれていない場合、このテーブルに適用された 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;

CHECK 制約では、テーブル CheckTbl に 1 行以上が格納されていなければならないことを指定していますが、DELETE ステートメントは成功します。