CHECK
を作成するとき SQL Serverの制約では、それがテーブルレベルの制約なのか列レベルの制約なのかさえ考えられないかもしれません。
テーブルレベルのCHECK
制約はテーブルに適用されますが、列レベルの制約は特定の列に適用されます。テーブルレベルのCHECK
制約、データをチェックするときにチェックされるのは行です。列レベルのCHECK
制約、チェックされるのは特定の列です。
一般に、作成する制約がテーブルレベルまたは列レベルの制約であるかどうかは、指定する定義によってわかります。式でチェックされている列が1つだけの場合、それは列レベルの制約になります。それ以外の場合は、テーブルレベルの制約になります。
しかし、既存の制約が列レベルかテーブルレベルかをどうやって知るのでしょうか?
以下のコード例のいずれかを実行して、既存の制約が列レベルかテーブルレベルかを判断できます。これらはすべてのCHECK
を取得します 現在のデータベースの制約ですが、いつでもWHERE
を使用できます 特定の制約に絞り込むための句。
例1-基本的なクエリ
これは、すべてのCHECK
に関する基本情報を返す簡単なクエリです。 現在のデータベースの制約。
ここでは、sys.check_constraints
にクエリを実行します システムビュー(CHECK
である各オブジェクトの行を返します 制約、sys.objects.type = 'C'
)。返す列は4つだけです(ただし、好きなだけ列を返すことができます)。
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints;
結果:
+-----------------+----------------+--------------------+----------------------------------------+ | Name | Table | parent_column_id | Definition | |-----------------+----------------+--------------------+----------------------------------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | 3 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | 3 | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+--------------------+----------------------------------------+
どの制約がテーブルレベルの制約であるかを判断する最も簡単な方法は、ゼロ(
0
)を探すことです。 )
parent_column_id
内 桁。ゼロのあるものはすべて、テーブルレベルのCHECK
です。 制約。ゼロ以外の値は、それが列レベルのCHECK
であることを示します 指定されたID値を持つ列に定義された制約。
したがって、この例では、3つの列レベルの制約と1つのテーブルレベルの制約があります。
同じ parent_column_id には2つの制約があることに注意してください (3)ただし、これら2つの制約は異なるテーブルからのものです。 3は、それぞれのテーブルの3番目の列を示します。
前述のように、特定の制約に関する情報のみが必要な場合は、WHERE
を使用してください 条項:
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints WHERE name = 'chkPrice';
結果:
+----------+----------------+--------------------+---------------+ | Name | Table | parent_column_id | Definition | |----------+----------------+--------------------+---------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | +----------+----------------+--------------------+---------------+
例2–クエリを改善する
IDだけでなく親列名を返すことで、前の例を改善できます。もちろん、これは列レベルの制約の列名のみを返します。テーブルレベルの制約の場合、NULLが返されます。
SELECT cc.name AS 'Constraint', o.name AS 'Table', ac.name AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
結果:
+-----------------+----------------+----------+----------------------------------------+ | Constraint | Table | Column | Constraint Definition | |-----------------+----------------+----------+----------------------------------------| | chkPrice | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | NULL | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+----------+----------------------------------------+
例3–さらなる改善
クエリをもう少し微調整しましょう:
SELECT cc.name AS 'Constraint', cc.is_disabled AS 'Disabled?', CASE WHEN cc.parent_column_id = 0 THEN 'Table-level' ELSE 'Column-level' END AS 'Table/Column', o.name AS 'Table', ISNULL(ac.name, '(n/a)') AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
結果:
+-----------------+-------------+----------------+----------------+----------+----------------------------------------+ | Constraint | Disabled? | Table/Column | Table | Column | Constraint Definition | |-----------------+-------------+----------------+----------------+----------+----------------------------------------| | chkPrice | 0 | Column-level | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | 0 | Table-level | ConstraintTest | (n/a) | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | Column-level | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | Column-level | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+-------------+----------------+----------------+----------+----------------------------------------+
そのため、どちらかによって、「列レベル」または「テーブルレベル」というテキストが返されます。
ISNULL()
も使用します NULL値を「(n / a)」に変換する関数。
また、 is_disabled も追加しました いずれかの制約が無効になっている場合に備えて、列をリストに追加します。この列には、常に parent_column_id と同じ扱いをすることができます。 列に「はい」、「いいえ」、「有効」、「無効」などを表示します。