无法从代码插入中间 table,但是当从 MySQL 中的 phpmyadmin 执行时,它会正确插入

Cant insert into intermediate table from code but when executing from phpmyadmin in MySQL it inserts it properly

我最近需要在我的数据库中添加一个中间 table。一切都在 innoDB 中。我在软件上使用 Java,我在执行 SQL 命令时从未遇到过问题。在插入 table 并将其与我意识到的代码一起设置后,我可以从 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 在同一查询下成功完成。 我真的不知道如何调试它。该代码与我用于其他中间 table 的代码相同,并且没有什么特别之处。

这是我在 table 上成功使用的代码 java:

 try{con = (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");
        }

这是我在 table 上使用的代码 我遇到了错误:

      if(continuar == true){
        System.out.println("Iniciando tabla de eventos conectados");
        try{con = (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是如何完美执行的

我将衷心感谢您的帮助。谢谢

错误告诉您您尝试插入的 event_category_id 在您尝试插入时不存在。您应该将此视为事实,并检查您的代码是如何发生的。也许尝试 运行 直接在你之前查询 query4 检查值 "eventlist.get(0)" 是否实际上在 table 中。然后倒退并检查该值的来源。

稍后您可以在 phpmyadmin 中执行它有几个原因(它们不应该让您误以为该值确实丢失了,但可能有助于缩小查找范围):

  • 目前缺失值存在。这可以例如如果在插入失败后插入缺少的 event_category_id 运行 的代码(并且在发生外键错误后继续应用程序),则会发生这种情况。或者插入到 event_category 发生在与插入到 event_category_link 不同的事务中并且尚未提交因此可用(因为您似乎为每个查询打开一个新连接)。或者您的代码不小心 deletes/updates event_category_id,但由于错误,事务可能会回滚,因此当您在 phpmyadmin 上进行测试时,它又可用了。
  • 这实际上不是(完全)相同的查询。您在应用程序代码中使用 value,并且在您测试的查询中使用 VALUE'' 引号将您的值引号,这是可疑的。尝试实际复制和粘贴。数千人年一直盯着完全相同的代码,但事实并非如此。在你的情况下,例如'01'01 的行为可能完全不同。
  • 如果错误发生在不同的地方,例如您在代码的另一部分插入 table 。您的异常消息包含“4”标记,因此我假设您能够识别正确的代码,但它可能值得验证。你可以例如通过对具有违反外键约束的触发器的不同 table 执行某些操作来间接获得此错误。
  • 您可能 运行 在不同的数据库上查询。您的数据库似乎有 4 个修订版,也许您的应用程序(或此特定查询)连接到与 phpmyadmin 不同的版本。
  • 您可以在 phpmyadmin 中禁用外键检查(这将允许您绕过检查)。虽然我的西班牙语(?)有点生疏,但它应该是您图像中的最后一个复选框,并且已选中,所以可能不是。