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

Sql error on update : The UPDATE statement conflicted with the FOREIGN KEY constraint

我有一个名为patient_address的表,它引用了patient表中的一个pk键。但如果我尝试运行以下语句之一:

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

我收到此错误消息:

"The UPDATE statement conflicted with the REFERENCE constraint
"FK__patient_a__id_no__27C3E46E". The conflict occurred in database
"PMS", table"dbo.patient_address", column 'id_no'." or"The
UPDATE statement conflicted with the FOREIGN KEY constraint
"FK__patient_a__id_no__27C3E46E". The conflict occurred in database
"PMS", table"dbo.patient", column 'id_no'." .

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


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

如果是这样,并且没有对更新操作设置任何操作,则可以将外键定义更改为级联。

右键单击您的外键并选择"修改"。在"插入和更新详细信息"下的"外键关系"对话框中,将更新规则设置为"层叠":

enter image description here

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

1
2
3
4
5
6
7
8
9
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

希望这有帮助


在MySQL中

1
2
3
4
5
6
7
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仅临时设置foreign key checking false。所以每次更新语句之前都需要执行。我们将其设置为0,就好像我们首先更新了父级,然后将不允许这样做,因为子级可能已经有了该值。如果我们先更新子级,那么也不允许这样做,因为父级可能没有我们要更新的值。所以我们需要设置外键检查。另一件事是,如果您使用命令行工具来使用这个查询,那么请注意在我放置新行或输入代码的地方提到空格。由于命令行将其放在一行中,所以可能会出现两个单词作为耐心的地址,从而导致语法错误。


原因正如@milikemedic所说。另一种解决方案是禁用所有约束,进行更新,然后像这样再次启用约束。在测试环境中更新测试数据时非常有用。

1
2
3
4
5
6
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


有时,当你尝试一个实体的Insert/Update,而你尝试的foreign key实际上并不存在时,就会发生这种情况。因此,确保foreign key存在,然后再试一次。


这就是我的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 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

我不会改变限制条件,相反,您可以使用主键(ID_no=7008255601088)在表_1中插入新记录。这只是一行重复的ID_no=8008255601088。因此,现在可以更新具有外键约束(ID_no=8008255601088)的患者_地址,以指向具有新ID(需要更新的ID)的记录,该ID_no将更新为ID_no=7008255601088。

然后,可以删除ID_no=7008255601088的初始主键行。

三个步骤包括:

  • 为新ID插入重复行u否
  • 更新患者地址以指向新的重复行
  • 删除带有旧ID的行u否

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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;

    我猜如果您更改id_no,一些外键将不会引用任何内容,因此会违反约束。您可以将initialy deffered添加到外键中,以便在提交更改时检查约束。