web-dev-qa-db-ja.com

「DELETEステートメントがREFERENCE制約と競合しました」というエラーが表示されました

私は外部キーでテーブルを切り詰めようとしましたが、メッセージが表示されました:

"外部キー制約によって参照されているため、テーブルを切り捨てることはできません"。

問題に関する多くの文献を読み、deleteを使用して解決策を見つけたと思いました

DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)

しかし、まだエラーメッセージが表示されます。

"DELETEステートメントがREFERENCE制約と競合しました"。

Microsoft Management Studioで削除して、前のクエリを実行しようとすると

DELETE FROM table_name DBCC CHECKIDENT (table_name, RESEED, 0)

エラーは発生せず、正常に機能します。テーブルからすべての情報を削除して新しいテーブルに追加したいのですが、外部キーを削除して作成したくありません。

47
Peter

エラーは、削除しようとしているデータを参照する他のテーブルにデータがあることを意味します。

制約をドロップして再作成するか、外部キーが参照するデータを削除する必要があります。

次のテーブルがあるとします

dbo.Students
(
StudentId
StudentName
StudentTypeId
)


dbo.StudentTypes
(
StudentTypeId
StudentType
)

StudentTypeIdStudentTypes列とStudentTypeIdStudents列の間に外部キー制約が存在するとします。

StudentTypesのすべてのデータを削除しようとすると、StudentTypeIdStudents列がStudentTypesテーブルのデータを参照するため、エラーが発生します。

編集:

DELETETRUNCATEは本質的に同じことを行います。唯一の違いは、TRUNCATEが変更をログファイルに保存しないことです。また、WHERE句でTRUNCATE句を使用することはできません

これをSSMSで実行できるが、アプリケーション経由では実行できない理由について。私は本当にこれが起こっているのを見ることができません。トランザクションの発信元に関係なく、FK制約は引き続きエラーをスローします。

46
codingbadger

ON DELETE CASCADE関連する場合

12
annakata

別の行(おそらく別のテーブル)によって参照されている行を削除しようとしています。

最初にthat rowを削除する必要があります(または、少なくともその外部キーを別のものに再設定します)。そうしないと、存在しない行を参照する行になってしまいます。データベースはそれを禁止しています。

7
Konrad Rudolph

参照を変更せずに削除するには、最初に他のテーブルのすべての関連する行を削除するか、目的に適した方法で変更する必要があります。

切り捨てるには、参照を削除する必要があります。 TRUNCATEは、DMLステートメント(INSERTやDELETEなど)ではなく、DDLステートメント(CREATEおよびDROPに匹敵)であり、明示的または参照やその他の制約に関連付けられているトリガーに関係なく、トリガーを起動しません。このため、参照を持つテーブルでTRUNCATEが許可されている場合、データベースは一貫性のない状態になる可能性があります。これは、TRUNCATEが一部のシステムで使用されている標準の拡張機能であり、現在では追加されたために標準で義務付けられている場合のルールでした。

1
Jon Hanna