チェック制約は、 SQLの整合性制約の一種で、データベーステーブルの各行が満たさなければならない要件を指定します。制約は述語でなければなりません。単一の列、またはテーブルの複数の列を参照できます。述語の結果は、NULLの有無に応じて、、、、またはのいずれかになります。述語が と評価された場合、制約は違反されておらず、行をテーブルに挿入または更新できます。これは、またはステートメントの句の述語とは異なります。TRUEFALSEUNKNOWNUNKNOWNWHERESELECTUPDATE
例えば、製品を含むテーブルでは、製品の価格と数量が非負の値であることを確認するチェック制約を追加することができます。
価格 >= 0
数量 >= 0
これらの制約がなければ、価格がマイナス(-30ドル)になったり、数量がマイナス(-3個)になったりすることも可能になるだろう。
チェック制約は、データベース内のデータの妥当性を確保し、データの整合性を保証するために使用されます。データベースレベルでチェック制約を使用すると、データベースを使用するアプリケーションは、たとえアプリケーション自体が無効なデータを受け入れる場合でも、無効なデータを追加したり、有効なデータを無効にするような変更を加えたりすることができなくなります。
CREATE TABLE各チェック制約は、次の構文を使用して、またはALTER TABLEステートメント内で定義する必要があります。
テーブルテーブル名を作成します( ...、 制約constraint_name CHECK (述語) ... )
ALTER TABLE table_name ADD CONSTRAINT constraint_name CHECK ( predicate )
チェック制約が単一の列のみを参照する場合、列定義の一部として制約を指定することが可能です。
テーブルテーブル名を作成します( ... column_name型CHECK (述語) ... )
制約は、述語付きの以下のチェック制約と機能的に同等です。NOT NULLIS NOT NULL
チェック(列がNULLでないことを確認する)
一部のリレーショナルデータベース管理システムでは、上記の制約構文NOT NULLではなく制約構文を使用するとパフォーマンスを最適化できます。 [ 1 ]CHECK
ほとんどのデータベース管理システムは、チェック制約を単一の行に制限し、定数と決定論的関数へのアクセスは許可しますが、他のテーブルのデータや、トランザクション分離のために現在のトランザクションから見えないデータへのアクセスは許可しません。
このような制約は、厳密にはテーブルチェック制約ではなく、行チェック制約です。これらの制約は、パフォーマンス上の理由から、行が直接更新されたときにのみ検証され、多くの場合、暗黙的INSERTまたはUPDATEトリガーとして実装されるため、これらの制限がなければ、間接的な操作によって整合性制約が違反される可能性があります。さらに、これらのレコードに対する本来有効な変更も、制約によって阻止されることになりますCHECK。危険な制約の例としては、次のようなものがあります。
CHECK((selectcount(*)frominvoiceswhereinvoices.customerId=customerId)<1000)CHECK(dateInserted=CURRENT_DATE)CHECK(countItems=RAND())ユーザー定義トリガーを使用することで、これらの制約を回避できます。実装方法は似ていますが、トリガーはテーブルが直接変更された場合にのみ起動され、他のテーブルにおける間接的で重要な変更の処理は設計者の責任であるという点が意味的に明確です。一方、制約は、ユーザーの操作や設計者の予見不足に関わらず、「常に真」であることを意図しています。