2014-05-25 71 views
12

我有一個名爲patient_address的表,它引用patient表中的PK密鑰。但如果我嘗試運行下面的語句之一:更新時發生SQL錯誤:UPDATE語句與FOREIGN KEY約束衝突

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

我收到此錯誤信息:

「UPDATE語句衝突與基準約束 ‘FK__patient_a__id_no__27C3E46E’衝突發生於數據庫 「PMS」,表「dbo.patient_address」,列'id_no'。「或「 UPDATE語句與FOREIGN KEY約束衝突 」FK__patient_a__id_no__27C3E46E「衝突發生在數據庫 」PMS「,表」dbo.patient「,列'id_no'。」 。

有沒有人知道可能的原因?謝謝。

+0

「dbo.patient_address.id_no」列允許使用NULL嗎?如果是,那麼你可以將'dbo.patient_address.id_no'設置爲NULL,更新'dbo.patient.id_no',然後將'dbo.patient_address.id_no'設置爲新值。 –

+0

是的。這是可能的原因嗎? –

+0

不是,這不是原因。是解決方案。 –

回答

30

當更新表的主鍵時,會遇到此錯誤,但它會被另一個表的外鍵引用,更新特定設置爲無操作。 「無」操作是默認選項。

如果這是您的情況,並且在更新操作中未設置任何操作,您可以將外鍵定義更改爲Cascade。

右鍵單擊您的外鍵並選擇修改。外鍵關係下的INSERT和UPDATE細節對話框設置級聯更新規則:

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 

希望這有助於

enter image description here

也可以使用T-SQL設置規則

+1

哇,像夢一樣工作。非常感謝你。 –

+0

我很樂意幫助:) –

+2

我已經在這裏設置了'ON DELETE CASCADE ON UPDATE CASCADE'。我仍然得到同樣的錯誤。你有什麼主意嗎? –

0

我想如果你改變id_no,一些外鍵不會引用任何東西,因此違反約束。 您可以將initialy deffered添加到外鍵中,因此在更改提交時會檢查約束條件

+0

根據此鏈接:http://stackoverflow.com/questions/998095/deferrable-constraints-in-sql-server,SQL Server不支持緩衝。這是真的 ?我正在忙着搞清楚如何申請假設外鍵 –

+0

它取決於服務器,我認爲postgrsql支持它。對於其他服務器,我不知道 – wastl

+0

不幸的是我的服務器不支持postgrsql。 –

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; 
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. 更新Patient_address指向新的重複行
  3. 老id_no上刪除的行
0

在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。所以它需要每次更新語句之前執行。我們將它設置爲0,就像我們先更新父對象一樣,那麼這將不被允許,因爲孩子可能已經有了這個值。如果我們先更新孩子,那麼這也將是不允許的,因爲家長可能沒有我們正在更新的那個值。所以我們需要設置外鍵檢查。 另一件事是,如果你正在使用命令行工具來使用這個查詢,然後把照顧提及空間的地方,我把新行或代碼輸入。由於命令行將它放在一行中,所以可能會發生兩個詞作爲patient_addressON粘在一起,從而產生語法錯誤。

相關問題