• 删除带外键的表【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 表示级联操作,就是说,如果主键表中被参考字段更新,外键表中也更新,主键表中的记录被删除,外键表中改行也相应删除
    

    所以当我如此设置的时候就把想做的级联删除也都执行了,数据库的很多东西都还要去补啊。

  • 相关阅读:
    kafka 配置属性
    mybatis 启动流程源码分析(二)之 Configuration-Properties解析
    mybatis 配置文件
    mybatis 启动流程源码分析(一)
    mybatis configuration
    使用函数式编程替换if-else
    mybatis 基本使用
    第十二周学习笔记
    T-SQL的进阶:超越基本级别3:构建相关子查询——701小组
    第十周学习笔记
  • 原文地址:https://www.cnblogs.com/flytree/p/11622635.html
Copyright © 2020-2023  润新知