web-dev-qa-db-fra.com

L'instruction DELETE est en conflit avec la contrainte REFERENCE

J'essaie de supprimer tous les utilisateurs mais j'obtiens l'erreur:

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.

La requête:

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

Semble que je dois utiliser on delete cascade; mais je suis coincé.

10
Darkmage

Vous n'avez pas besoin d'utiliser la cascade de suppression. Quelqu'un (l'auteur de la conception du schéma) s'est assuré que vous ne pouvez pas supprimer une personne qui est toujours référencée par un article. Cela a réussi, vous essayiez simplement de le faire et a été bloqué, bravo au designer.

Maintenant, allez parler à quelqu'un qui a conçu le schéma et connaît les contraintes et demandez-lui comment supprimer correctement les enregistrements que vous essayez de supprimer, dans le bon ordre et en prenant les précautions appropriées pour maintenir la base de données cohérente.

18
Remus Rusanu

Vous avez ici deux choix réels, vous pouvez désactiver les contraintes sur la table. Ce n'est généralement pas une bonne idée car vous pouvez vous retrouver avec une mauvaise condition de données si vous jouez avec des données qui se rapportent à d'autres tables, mais ne connaissez pas l'étendue complète de votre schéma et cela peut convenir à vos besoins:

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

N'oubliez pas de réactiver la contrainte après la suppression avec

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

Le deuxième choix serait de supprimer et de rajouter la contrainte avec l'option ON DELETE CASCADE en utilisant:

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

En fonction de votre nom FK, il semble que votre table parent soit M02ArticlePersons et la colonne parent est M06Persons.

Si vous n'avez pas créé ce schéma, essayez de déterminer pourquoi les contraintes peuvent être présentes et comprenez que les violer de cette manière peut avoir des effets secondaires involontaires.

9
Ahrotahntee

la table dbo.M02ArticlePersons de la colonne M06PersonId est référencée dans une autre table. Donc, avant de supprimer l'instruction, désactivez ces relations et réessayez

ci-dessous est pour disbling la clé étrangère

 ALTER TABLE dbo.M02ArticlePersons NOCHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

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

et c'est pour lui permettre

ALTER TABLE dbo.M02ArticlePersons CHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

J'espère que cela fonctionnera

2
Navin 431

Il existe également une autre option manuelle:

Vous pouvez accéder à la table enfant et supprimer les lignes enfant référencées par la clé parent. Vous pouvez ensuite supprimer la ligne parent. C'est essentiellement ce que fait la suppression en cascade. De cette façon, vous n'avez pas à supprimer/recréer/modifier vos contraintes.

1
StanleyJohns

Ce petit code vous aidera pour toute table dont vous souhaitez supprimer les enregistrements. Il prend également en charge l'intégrité référentielle ...

Le code ci-dessous générera des instructions DELETE. Spécifiez simplement le nom du schéma.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
1
Kin Shah