DBCC CHECKCONSTRAINTS
を実行できます SQLServerデータベース内のすべての制約違反のリストを返すconsoleコマンド。
このコマンドは、現在のデータベース内の指定されたテーブルの指定された制約またはすべての制約の整合性をチェックします。外部キーとCHECK
を返します 検出された制約違反。
ALL_CONSTRAINTS
を使用できます 有効な制約と無効な制約の両方をチェックするオプション。これを省略すると、有効な制約のみが返されます(チェックする制約を明示的に指定しない限り、その場合、有効か無効かに関係なく返されます)。
例1-チェック制約違反
この例は、CHECK
を含むデータベースに対して実行しました。 制約違反。
USE Test; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
結果:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
これは、データベースに3つの制約違反があることを示しています。
列の説明
3つの列は、次の情報を返します。
- テーブル
- 制約違反を含むテーブル名の名前。
- 制約
- 違反している制約の名前。
- 場所
- 制約に違反している1つまたは複数の行を識別する列値の割り当て。この列の値は、
WHERE
で使用できますSELECT
の句 制約に違反する行をクエリするステートメント。
したがって、3番目の列のおかげで、すべての無効なデータを検索(および更新)できるようになりました。
無効なデータを見つける
したがって、DBCC CHECKCONSTRAINTS
の最初の行を見ると 結果から、[JobTitle] = 'Digital Nomad'
を使用して問題のあるデータを見つけることができることがわかります。 WHERE
条項。
このように:
SELECT * FROM [dbo].[Occupation] WHERE [JobTitle] = 'Digital Nomad';
結果:
+----------------+---------------+ | OccupationId | JobTitle | |----------------+---------------| | 7 | Digital Nomad | +----------------+---------------+
制約の定義
chkJobTitle
の実際の定義を見てみましょう。 制約:
SELECT Definition FROM sys.check_constraints WHERE name = 'chkJobTitle';
結果:
+-------------------------------+ | Definition | |-------------------------------| | ([JobTitle]<>'Digital Nomad') | +-------------------------------+
この制約は、 JobTitle の値が 列はしてはいけません デジタル遊牧民 、それでもデジタル遊牧民はまだ私のデータベースに入ることができました!
問題のあるデータを更新する
問題のあるデータを更新するか、削除するか、そのままにしておくことができます。
この例では、同じWHERE
を使用します 値を更新する句:
UPDATE [dbo].[Occupation] SET [JobTitle] = 'Unemployed' WHERE [JobTitle] = 'Digital Nomad';
ここでもう一度チェックを実行すると、そのレコードは問題ではなくなり、他の2つの問題のみが残ります。
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
結果:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
例2–違反した外部キー制約
この例では、いくつかの外部キー制約違反を含むデータベースに切り替えます。
USE Music; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
結果:
+----------------+---------------------+--------------------+ | Table | Constraint | Where | |----------------+---------------------+--------------------| | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' | | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17' | +----------------+---------------------+--------------------+
この場合、 Albums の2つの行が表示されます テーブルは ArtistId を参照しています それは存在しません。
無効なデータを見つける
ここでも、
Where
を使用できます WHERE
を作成するための列 句。今回は、両方の違反をWHERE
に追加します 条項:
SELECT * FROM [dbo].[Albums] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
結果:
+-----------+-------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------+---------------+------------+-----------| | 21 | Yo Wassup | 2019-03-12 | 17 | 3 | | 22 | Busted | 1901-05-11 | 123 | 3 | +-----------+-------------+---------------+------------+-----------+
これで、制約に違反する2つの行を確認できます(ただし、これは ArtistsId のみです) 制約に違反する列)。
主キーテーブルを確認する
Artists に問い合わせることで、違反を確認できます テーブル(つまり、この外部キーの主キーを含むテーブル)。
それでは、 Artists に対して同じクエリを実行してみましょう。 テーブル。
SELECT * FROM [dbo].[Artists] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
結果:
(0 rows affected)
予想どおり、どちらの値もそのテーブルにはありません。
外部キーは、これが発生するのを防ぐことになっています。外部キーが無効になっているときに無効なデータがデータベースに入力されたか、外部キーが作成される前に入力されました。いずれにせよ、外部キーまたはCHECK
を作成または有効にする場合 制約がある場合は、WITH CHECK
を使用する必要があります 制約を有効にする前に、既存のすべてのデータをチェックする必要があることを指定します。
例3–有効な制約のみをチェックする
現在有効になっている制約のみを確認する場合は、WITH ALL_CONSTRAINTS
を削除してください。 :
USE Test; DBCC CHECKCONSTRAINTS;
結果:
+--------------------+---------------+------------------------------+ | Table | Constraint | Where | |--------------------+---------------+------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | +--------------------+---------------+------------------------------+
したがって、違反した2つの制約のうち、 chkJobTitle 有効にされたのは1つだけです。
次のクエリでこれをさらに確認できます:
SELECT name, is_disabled FROM sys.check_constraints WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';
結果:
+-----------------+---------------+ | name | is_disabled | |-----------------+---------------| | chkJobTitle | 0 | | chkValidEndDate | 1 | +-----------------+---------------+
例4–特定のテーブルの制約のみをチェックする
テーブルの制約のみを確認する場合は、括弧内にテーブルの名前を追加できます。
USE Test; DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
結果:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
例5–単一の制約を確認する
単一の制約をチェックするには、その名前を括弧で囲みます。
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate);
結果:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
単一の制約を指定する場合、WITH ALL_CONSTRAINTS
効果はありません:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
結果:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+