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


11

すべてのユーザーを削除しようとしていますが、エラーが発生します。

Msg 547, Level 16, State 0, Line 1
The DELETE statement conflicted with the REFERENCE constraint "FK_M02ArticlePersons_M06Persons". The conflict occurred in database "workdemo.no", table "dbo.M02ArticlePersons", column 'M06PersonId'.
The statement has been terminated.

クエリ:

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
WHERE ID > '13'
GO

使用する必要on delete cascade;があるようですが、行き詰まっています。

回答:


18

on deleteカスケードを使用する必要はありません。誰か(スキーマ設計の作成者)が、記事で参照されている人物を削除できないようにしています。それは成功しました、あなたはただこれをやろうとしていて、ブロックされました、デザイナーへの称賛。

次に、スキーマを設計し、制約を知っている誰かと話し、削除しようとしているレコードを正しい順序で適切に削除し、データベースの一貫性を保つために適切な予防策を講じる方法を尋ねます。


9

ここには2つの選択肢があります。テーブルの制約を無効にできます。他のテーブルに関連するデータをいじっているが、スキーマの全範囲がわからない場合、目的に合う可能性があるため、データの状態が悪くなる可能性があるため、これは通常は良いアイデアではありません。

ALTER TABLE [workdemo.no].[dbo].[M06Persons] NOCHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

削除後に制約をオンに戻すことを忘れないでください

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH CHECK CHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

2番目の選択肢は、ON DELETE CASCADEオプションを使用して制約を削除して再度追加することです。

ALTER TABLE [workdemo.no].[dbo].[M06Persons] DROP CONSTRAINT [FK_M02ArticlePersons_M06Persons]

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH NOCHECK ADD CONSTRAINT [FK_M02ArticlePersons_M06Persons] FOREIGN KEY(M06PersonId)
REFERENCES <parent table here> (<parent column here>)
ON DELETE CASCADE

FK名に基づいて、親テーブルはM02ArticlePersonsであり、親列はM06Personsであるように見えます。

このスキーマを作成しなかった場合は、制約が存在する理由を検討し、この方法で違反すると意図しない副作用が生じる可能性があることを理解してください。


2

列M06PersonIdのdbo.M02ArticlePersonsテーブルは、別のテーブルに参照されています。したがって、ステートメントを削除する前に、この関係を無効にして再試行してください

以下は外部キーを無効にするためのものです

 ALTER TABLE dbo.M02ArticlePersons NOCHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
  WHERE ID > '13'
GO

これはそれを有効にすることです

ALTER TABLE dbo.M02ArticlePersons CHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

これがうまくいくことを願っています


2
恐ろしい提案。上級dbaである場合を除き、FK制約を無効にしないでください(この場合、上記の質問を書かなかったはずです)。これらの制約は、レコードを削除できないようにするためのものです。それらを無効にすると、データベースのデータが不正になります。あなたは最悪の習慣を良いものではないことをお勧めします。
HLGEM 2013

1

別の手動オプションもあります:

子テーブルに移動して、親キーによって参照される子行を削除できます。その後、親行を削除できます。これは基本的にカスケード削除が行うことです。この方法では、制約を削除/再作成/変更する必要はありません。


1

この小さなコードは、レコードを削除するテーブルに役立ちます。参照整合性も処理します...

以下のコードはDELETEステートメントを生成します.. schema.table_Nameを指定するだけです

Declare @sql1 varchar(max)
      , @ptn1 varchar(200)
      , @ctn1 varchar(200)
      , @ptn2 varchar(200)
      , @ctn2 varchar(200)
--
SET @ptn1 = ''
--
SET @ctn1 = ''
--
SET @ptn2 = ''
--
SET @ctn2 = ''
--
SELECT @sql1 = case when (@ptn1 <> OBJECT_NAME (f.referenced_object_id)) then
                         COALESCE( @sql1 + char(10), '') + 'DELETE' + char(10) + ' ' + OBJECT_NAME (f.referenced_object_id) + ' FROM ' + OBJECT_NAME(f.parent_object_id) + ', '+OBJECT_NAME (f.referenced_object_id) + char(10) +' WHERE ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    else
                         @sql1 + ' AND ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    end + char(10)
     , @ptn1 = OBJECT_NAME (f.referenced_object_id)
     , @ptn2  = object_name(f.parent_object_id)
FROM   sys.foreign_keys AS f
       INNER JOIN
       sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
WHERE  f.parent_object_id = OBJECT_ID('dbo.M06Persons'); -- CHANGE here schema.table_name
--
print  '--Table Depended on ' + @ptn2 + char(10) + @sql1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.