无法从代码插入中间表,但是当从 MySQL 中的 phpmyadmin 执行时,它会正确插入
Posted
技术标签:
【中文标题】无法从代码插入中间表,但是当从 MySQL 中的 phpmyadmin 执行时,它会正确插入【英文标题】:Cant insert into intermediate table from code but when executing from phpmyadmin in MySQL it inserts it properly 【发布时间】:2019-12-03 10:40:18 【问题描述】:我最近需要在我的数据库中添加一个中间表。这一切都在 innoDB 中。我在软件上使用 Java,我从来没有遇到过执行 SQL 命令的问题。在插入表格并将其与我意识到的代码一起设置后,我可以从 java 将数据插入其中。它总是给出同样的错误
Cannot add or update a child row: a foreign key constraint fails
(`jjeventoscorev3`.`event_category_link`, CONSTRAINT
`event_category_link_ibfk_1` FOREIGN KEY (`event_category_id`)
REFERENCES `event_category` (`event_category_id`))
我检查了查询:
insert into event_category_link (event_link_id, event_id,
event_category_id) values (NULL,118,1)
然后我尝试在 phpmyadmin 上执行它。 id 在同一个查询下成功地做到了。 我真的不知道如何调试它。该代码与 ive 用于其他中间表的代码相同,并且没有什么特别之处。
这是我在 java 上成功用于表的代码:
trycon = (Connection) DriverManager.getConnection("jdbc:mysql://"+home.credentials[0],home.credentials[1],home.credentials[2]);
String query3 = " insert into client_event (client_id, event_id)"
+ " values (?, ?)";/*query para insertar en la tabla intermedia*/
PreparedStatement preparedStmt3 = con.prepareStatement(query3);
if(existing == false)/*si existe se manda el ids[0]*/
preparedStmt3.setInt (1, ids[0]); //cliente
else
preparedStmt3.setInt (1, id_existing); /*se manda el id existente*/
preparedStmt3.setInt (2, ids[1]); //evento
preparedStmt3.execute();
con.close();
JOptionPane.showMessageDialog(new JFrame(), "Evento añadido");
pnlone1.continue_doc = true; /*se cambia el valor de continue_doc en el pnlone para poder generar el archivo*/
catch (Exception e)
System.err.println("Got an exception! in 3");
System.err.println(e.getMessage());
continuar = false; /*se pasa a falso para no continuar con la operación*/
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(new JFrame(), "Error: verificar datos");
这是我在收到错误的表上使用的代码:
if(continuar == true)
System.out.println("Iniciando tabla de eventos conectados");
trycon = (Connection) DriverManager.getConnection("jdbc:mysql://"+home.credentials[0],home.credentials[1],home.credentials[2]);
String query4 = " insert into event_category_link (event_link_id, event_id, event_category_id)"
+ " values (NULL,"+ids[1]+","+eventlist.get(0)+")";/*query para insertar en la tabla intermedia*/
//INSERT INTO `event_category_link` (`event_link_id`, `event_id`, `event_category_id`) VALUES (NULL, '105', '27');
PreparedStatement preparedStmt4 = con.prepareStatement(query4);
System.out.println(preparedStmt4);
preparedStmt4.execute();
con.close();
JOptionPane.showMessageDialog(new JFrame(), "Relacion añadida");
catch (Exception e)
System.err.println("Got an exception! in 4");
System.err.println(e.getMessage());
JOptionPane.showMessageDialog(new JFrame(), "Error: verificar datos");
在这里你可以看到 PhpMyAdmin 是如何完美执行的
我将衷心感谢您的帮助。谢谢
【问题讨论】:
【参考方案1】:错误告诉您,您尝试插入的event_category_id
在您尝试插入它的那一刻不存在。您应该将此视为事实,并检查您的代码是否会出现这种情况。也许尝试直接在您之前运行查询
query4
检查值 "eventlist.get(0)"
是否确实在表中。然后倒退并检查该值的来源。
有几个原因可以让您稍后在 phpmyadmin 中执行它(它们不应该让您误以为该值确实丢失了,但可能有助于缩小查看范围):
缺失值现在已经存在。这可以例如如果插入缺失的event_category_id
的代码在插入失败后运行(并且在发生外键错误后继续应用),则会发生这种情况。或者插入event_category
发生在与插入event_category_link
不同的事务中,并且尚未提交因此可用(因为您似乎为每个查询打开一个新连接)。或者您的代码意外删除/更新了event_category_id
,但由于错误,事务可能会回滚,因此当您在 phpmyadmin 上进行测试时,它再次可用。
这实际上不是(完全)相同的查询。您在应用程序代码中使用 value
并在您测试的查询中使用 VALUE
和 ''
- 引用您的值是可疑的。尝试实际复制和粘贴。数千人年的时间都花在盯着完全相同的代码上,但事实并非如此。在你的情况下,例如'01'
和 01
的行为可能完全不同。
如果错误发生在不同的地方,您会得到一个变体,例如您在代码的另一部分插入该表。您的异常消息包含“4”标记,因此我假设您能够识别正确的代码,但可能值得验证。你可以例如通过对具有违反该外键约束的触发器的不同表执行某些操作来间接获取此错误。
您可能在不同的数据库上运行查询。您的数据库似乎有 4 个版本,可能您的应用程序(或此特定查询)连接到与 phpmyadmin 不同的版本。
您可以在 phpmyadmin 中禁用外键检查(这将允许您绕过检查)。虽然我的西班牙语(?)有点生疏,但它应该是您图像中的最后一个复选框,并且它已被选中,所以可能不是它。
【讨论】:
以上是关于无法从代码插入中间表,但是当从 MySQL 中的 phpmyadmin 执行时,它会正确插入的主要内容,如果未能解决你的问题,请参考以下文章