刪除帶外鍵的表【foreign key constraint fails】報錯



title: 刪除帶外鍵的表【foreign key constraint fails】報錯
date: 2018-08-02 21:59:06
tags: 數據庫

遙想當時正在學hibernate的時候,剛好學到了一對多,多對多的關聯操作。時間也正是剛好在那是有了一個項目,把各表的間的結構還理清,俗話說學到就要用到,就把這些表的結構都能配置級聯關系的都把它配上。沒想到就在這里給自己放了個小坑。前幾天在一個帖子中看到別人說,盡量少配些ORM約束,數據庫的外鍵約束什么的。當時還不以為然。沒想到我就遇到了這個問題,或許對數據庫操還是不是很熟悉的人約束真的不要配太多。不過有自然有其的好處就是。

今天在刪除一張表的數據的時候報了如下錯誤:

09:55:49.144 [http-nio-8080-exec-6] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Cannot delete or update a parent row: a foreign key constraint fails (`checkin`.`right_umenu`, CONSTRAINT `FKnmg8itd642tdyn6qh1q42h60r` FOREIGN KEY (`menu_detailPid`) REFERENCES `menu_detail` (`id`))
09:55:49.151 [http-nio-8080-exec-6] ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [could not execute statement]


org.hibernate.exception.ConstraintViolationException: could not execute statement
	at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
	at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
	at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3198)
	.......
	

​ 在網上查找后得到的結果和我認為的是一樣的,就是外鍵的問題引發的(當然報錯里信息都寫了foreign key什么的還不知道,那怎么行(●ˇ∀ˇ●))。網上是說:表之間強制生成了外鍵,在刪除操作時,數據庫會檢查表間的關系導致無法刪除。

解決辦法

SET foreign_key_checks = 0;  // 先設置外鍵約束檢查關閉
 
drop table table1;  // 刪除表,如果要刪除視圖,也是如此
 
SET foreign_key_checks = 1; // 開啟外鍵約束檢查,以保持表結構完整性

原理:

MySQL的環境變量中存在一個foreign_key_checks,這是默認檢查外鍵的配置項,如果將其設置為0,則表示不檢查外鍵約束。查看foreign_key_checks的值:

show VARIABLES like "foreign%";

然而,然而。我即使把外鍵約束檢查關閉,但是在打開檢查的地方又還會報錯。這我就無奈了。

不過我在嘗試時把,外鍵的刪除項由 RESTRICT 改為 CASCADE 時不但能刪除且不影響我的另一個方法的執行,而且的更方便的執行了我想寫的方法。

后面又繼續查,這是數據庫定義外鍵的一個選項,操作時可以知道update 和delete 后面可以跟的詞語有四個 :

no action , set null , set default ,cascade 。

no action 表示 不做任何操作,

set null 表示在外鍵表中將相應字段設置為null

set default 表示設置為默認值(restrict)

cascade 表示級聯操作,就是說,如果主鍵表中被參考字段更新,外鍵表中也更新,主鍵表中的記錄被刪除,外鍵表中改行也相應刪除

所以當我如此設置的時候就把想做的級聯刪除也都執行了,數據庫的很多東西都還要去補啊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM