更新时出现Sql错误:UPDATE语句与FOREIGN KEY约束冲突

时间:2014-05-25 14:39:02

标签: sql-server

我有一个名为patient_address的表,它在patient表中引用了一个PK密钥。但是,如果我尝试运行以下声明之一:

update patient set id_no='7008255601088' where id_no='8008255601088'
update patient_address set id_no='7008255601088' where id_no='8008255601088'

我收到此错误消息:

  

" UPDATE语句与REFERENCE约束冲突   " FK__patient_a__id_no__27C3E46E&#34 ;.冲突发生在数据库中   " PMS",table" dbo.patient_address",column' id_no'。"或者" The   UPDATE语句与FOREIGN KEY约束冲突   " FK__patient_a__id_no__27C3E46E&#34 ;.冲突发生在数据库中   " PMS",table" dbo.patient",column' id_no'。"

有没有人知道可能的原因?感谢。

10 个答案:

答案 0 :(得分:42)

当表的主键更新但是来自另一个表的外键引用它并且特定于更新的设置为无操作时,会遇到此错误。 No操作是默认选项。

如果是这种情况并且在更新操作上未设置任何操作,则可以将外键定义更改为Cascade。

右键单击外键并选择修改。在INSERT和UPDATE细节下的外键关系对话框中,在Cascade上设置UPDATE规则:

enter image description here

您还可以使用T-SQL设置规则:

ALTER TABLE YourTable
DROP Constraint Your_FK
GO

ALTER TABLE YourTable
ADD CONSTRAINT [New_FK_Constraint]
FOREIGN KEY (YourColumn) REFERENCES ReferencedTable(YourColumn)
ON DELETE CASCADE ON UPDATE CASCADE
GO 

希望这有帮助

答案 1 :(得分:1)

在MySQL中

set foreign_key_checks=0;

UPDATE patient INNER JOIN patient_address 
ON patient.id_no=patient_address.id_no 
SET patient.id_no='8008255601088', 
patient_address.id_no=patient.id_no 
WHERE patient.id_no='7008255601088';

请注意,foreign_key_checks仅临时设置外键检查false。所以它需要在update语句之前每次执行。我们将其设置为0,好像我们首先更新父级,然后不允许这样,因为孩子可能已经具有该值。如果我们首先更新孩子,那么也不允许这样做,因为父母可能没有我们正在更新的那个值。所以我们需要设置外键检查。 另一件事是,如果您使用命令行工具来使用此查询,那么请注意提到我在代码中添加新行或ENTER的位置。由于命令行将其带入一行,因此可能会发生两个单词作为patient_addressON而产生语法错误。

答案 2 :(得分:0)

我想如果你改变id_no,一些外键就不会引用任何东西,因此会违反约束。 您可以将initialy deffered添加到外键,因此在提交更改时会检查约束

答案 3 :(得分:0)

如果列dbo.patient_address.id_no允许NULL,那么您可以使用此解决方案:

SET XACT_ABORT ON;
BEGIN TRANSACTION;

-- I assmume that [id] is the primary key of patient_address table (single column key)
-- replace the name of [id] column with the name of PK column from patient_address table
-- replace INT data type with the proper type
DECLARE @RowsForUpdate TABLE([id] INT PRIMARY KEY); 
UPDATE patient_address 
SET id_no = NULL
OUTPUT deleted.[id] INTO @RowsForUpdate ([id])
WHERE id_no='8008255601088'

UPDATE patient 
SET id_no='7008255601088' 
WHERE id_no='8008255601088'

UPDATE patient_address 
SET id_no='7008255601088' 
WHERE [id] IN (SELECT u.[id] FROM @RowsForUpdate u)

COMMIT;

答案 4 :(得分:0)

我不会改变约束, 相反,您可以使用主键(id_no = 7008255601088)在table_1中插入新记录。这只是id_no = 8008255601088的重复行。所以现在可以更新具有外键约束(id_no = 8008255601088)的patient_address以指向具有新ID(需要更新的ID)的记录,这是更新id_no到id_no = 7008255601088。

然后您可以删除id_no = 7008255601088的初始主键行。

三个步骤包括:

  1. 为新的id_no
  2. 插入重复的行
  3. 更新Patient_address以指向新的重复行
  4. 删除旧id_no
  5. 的行

答案 5 :(得分:0)

这是我的解决方案:

-- Check how it is now
select * from patient
select * from patient_address

-- Alter your DB
alter table patient_address nocheck constraint FK__patient_a__id_no__27C3E46E
update patient 
set id_no='7008255601088'
where id_no='8008255601088'

alter table patient_address nocheck constraint FK__patient_a__id_no__27C3E46E
update patient_address 
set id_no='7008255601088'
where id_no='8008255601088'

-- Check how it is now
select * from patient
select * from patient_address

答案 6 :(得分:0)

当您尝试Insert/Update的实体{strong}实际上不存在{strong}的实体{strong}不存在时,有时会发生这种情况。因此,请确保foreign key存在,然后重试。

答案 7 :(得分:0)

原因正如@MilicaMedic所说。替代解决方案是禁用所有约束,进行更新,然后再次启用约束,如下所示。在测试环境中更新测试数据时非常有用。

exec sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

update patient set id_no='7008255601088' where id_no='8008255601088'
update patient_address set id_no='7008255601088' where id_no='8008255601088'

exec sp_MSforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

来源:

https://stackoverflow.com/a/161410/3850405

答案 8 :(得分:0)

如果您不想更改表结构,则可以运行以下查询:

ALTER TABLE [UserStore] 
NOCHECK CONSTRAINT FK_UserStore_User_UserId

ALTER TABLE [UserIdentity]
NOCHECK CONSTRAINT  FK_UserIdentity_User_UserId

BEGIN TRAN

UPDATE  [user] 
SET Id = 10
WHERE Id = 9

UPDATE  [dbo].[UserStore]
SET UserId = 10
WHERE UserId = 9

UPDATE  [dbo].UserIdentity
SET UserId = 10
WHERE UserId = 9

COMMIT TRAN

ALTER TABLE [UserStore] 
CHECK CONSTRAINT FK_UserStore_User_UserId

ALTER TABLE UserIdentity 
CHECK CONSTRAINT FK_UserIdentity_User_UserId

答案 9 :(得分:0)

我遇到这个问题是因为 DBCC CHECKIDENT ([Table], RESEED, 0) 的重新播种。将其更改为 DBCC CHECKIDENT ([Table], RESEED, 1) 为我解决了问题。

相关问题