关于级联删除和级联修改

来源:互联网 发布:淘宝友情链接怎么设置 编辑:程序博客网 时间:2024/04/30 15:33

 

曾经因为级联删除的问题浪费了N多时间,顾此在这里写下小小心得,供大家借鉴。

  在数据库分别建立表t_food(菜单)和表t_book(订单),如下所示:

  t_food:

————————————————————————————

  food_id (主键)       food_name          food_price

  1                                        苹果                       2.4

  2                                    香蕉                       3.5

  ……

————————————————————————————

  t_book:

————————————————————————————

  id                  foodid(外键)                  num

  1                      1                                          5

  2                      2                              4

  ……

————————————————————————————

  如果你想删除t_food中的某一行数据,就有可能会出现如下错误:

java.sql.SQLException: Cannot delete or update a parent row: a foreign key constraint fails (`shopcar2`.`t_book`, CONSTRAINT `b_fid_o_fid` FOREIGN KEY (`foodid`) REFERENCES `t_food` (`food_id`))
 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2921)
 at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1570)
 at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
 at com.mysql.jdbc.Connection.execSQL(Connection.java:2972)
 at com.mysql.jdbc.Connection.execSQL(Connection.java:2902)
 at com.mysql.jdbc.Statement.executeUpdate(Statement.java:929)
 at org.apache.jsp.MyJsp_jsp._jspService(MyJsp_jsp.java:91)
 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:319)
 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:270)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:191)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:227)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:211)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:817)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:623)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:444)
 at java.lang.Thread.run(Thread.java:619)

  为什么会出现这样的问题呢?那是因为你所删除的数据表t_food中包含了主键food_id,如果直接删除数据,那么,

food_id对应的外键foodid就没有被指向,自然就会出现这种错误。
  那么,如何解决这个问题呢?有两种方法:

  第一种,也是最直接的,那就是在删除t_food的数据行之前,先将其所对应的t_book中的数据行删除。如你想删除

t_food中food_id=1所对应的数据行,那么,你可以先删除t_book中foodid=1对应的数据行,然后再删除t_food中

food_id=1所对应的数据行。

  第二种,在建立数据库时,设置主外键on delete cascade。这样,在删除主键对应数据时,外键对应的数据也会

被删除。

  此外,还有级联修改,它跟级联删除一样会出现以上问题,解决方法相似。建立数据库时,设置主外键on

update  cascade。

原创粉丝点击