【问题标题】:Erroneous INSERT in MySQL from Java application来自 Java 应用程序的 MySQL 中的错误 INSERT
【发布时间】:2025-12-19 00:25:01
【问题描述】:

美好的一天!我希望有人能够指出我正确的方向,或者能够指出什么 我可能做错了。

我对使用 Java 和 MySQL 还很陌生;更具体地说,使用 Java 在 MySQL 中进行数据库操作。

我用Java编写了附加的原型来解决以下问题:

给定一个表“邮寄”:

    CREATE TABLE `mailing` (
        ind INT AUTO_INCREMENT,
        `addr` VARCHAR(255) NOT NULL,
        PRIMARY KEY (ind)
    );

邮件表最初是空的。每天都会添加新地址。预计该表将存储至少 10,000,000 个电子邮件地址和 100,000 个域。

编写一个程序来更新另一个表,该表按其域名保存每日电子邮件地址计数。

使用此表按过去 30 天与总数相比的百分比增长来报告排名前 50 的域。

** 注意 **

  • 不应修改原始邮件表。

我几乎有一个解决方案,但我的解决方案产生了一个我无法解释的意外结果。以点的形式,这就是我正在做的事情:

  • 如果 TempResult 表不存在,则创建一个。 TempResult 表在形式上与上面显示的原始“邮件”表相同。
  • 接下来,我通过设置差异对“mailing”和“TempResult”执行查询,将“mailing”中发现的差异插入到 'TempResult'。
  • 然后我对“TempResult”执行查询,解析提取域的每个电子邮件地址,并将结果插入到数组列表中。
  • 解析完成后,我将每个唯一元素插入到哈希映射中,并增加 value 属性,从而计算出现次数。
  • 下一步是遍历哈希映射,并将每个映射插入到数据库中的“结果”表中。结果表格式如下,仅在以前不存在时才创建。

    CREATE TABLE `Result` (
        ind INT AUTO_INCREMENT,
        `domain` VARCHAR(255),
        dailyCount INT,
        theDate DATE,
        primary key (ind)
    );
    
  • 最后,我执行查询以生成所需的最终输出。

这是我的问题。当我使用示例数据运行该程序时,“TempResult”和“Result”都不存在,程序正确执行,我得到了我期望的输出数据。但是,当我使用相同的数据再次运行它时,我的“结果”表显示重复记录和错误计数。当我执行 INSERT INTO 'Result' 时,我已将问题缩小到代码块,但我看不出我做错了什么。有人可以指出我哪里出错了吗?

提前谢谢你......如果这是一个菜鸟的错误,请原谅我。

迈克

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.*;
    import java.time.*;
    import java.util.*;


    public class Test 
    {
        public static void main(String[] args) throws Exception
        {
        String ConnectionURL = "jdbc:mysql://www.xxxxxxxx.ca:3306/Emails?autoReconnect=true&useSSL=false";
        String user = "xxxxxxxxxxxx";
        String password = "xxxxxxxxxxxxxxxx";
        String driver = "com.mysql.jdbc.Driver";
        Connection conn = null;
        List<String> addresses = new ArrayList<String>();

        //establish connection to DB
        try 
        {
            // The newInstance() call is a work around for some
            // broken Java implementations
            Class.forName(driver).newInstance();
        } 
        catch (Exception ex) 
        {
            // handle the error
            System.out.println(ex.getMessage());
        }

        //connect to DB and perform queries
        try 
        {
            //get  connection to the database 'Emails'
            conn = DriverManager.getConnection(ConnectionURL, user, password);
            conn.setAutoCommit(false);

            //check to see if TempResult Table exists.
            DatabaseMetaData metaOne = conn.getMetaData();
            ResultSet metaDataOne = metaOne.getTables(null, null, "TempResult", null);

            //Create temporary result table TempResult if not exists
            if (!metaDataOne.next())
            {
                String queryOne = "CREATE TABLE TempResult (ind INT AUTO_INCREMENT, addr VARCHAR(255), PRIMARY KEY ( ind ))";
                PreparedStatement statementOne = conn.prepareStatement(queryOne);
                statementOne.executeUpdate();
                conn.commit();
            }


            //Insert set difference between mailing and TempResult into TempResult
            String queryTwo = "INSERT INTO TempResult (SELECT * FROM mailing e WHERE NOT EXISTS (SELECT * FROM TempResult t WHERE e.ind = t.ind))";
            PreparedStatement statementTwo = conn.prepareStatement(queryTwo);
            statementTwo.executeUpdate();
            conn.commit();


            //now read into memory table TempResult into an arraylist
            //parse each email to obtain the domain of each email only  
            Statement queryThree = conn.createStatement();
            ResultSet result = queryThree.executeQuery("SELECT addr FROM TempResult");
            while (result.next())
            {
                String delimiter = "[@]";
                String elements[] = result.getString("addr").split(delimiter);      
                addresses.add(elements[1]);
                //System.out.println(result.getString("addr"));
            }
            queryThree.close();
            result.close();


            //now map the arraylist to a HashMap to create a 'dictionary' with counts on the domains.
            int occurance;
            int temp;
            HashMap<String, Integer> domains = new HashMap<String, Integer>();
            for (String a : addresses)
            {
                if(domains.containsKey(a))
                {
                    temp = domains.get(a);
                    occurance = temp + 1;
                    domains.replace(a, occurance);
                }
                else
                {
                    occurance = 1;
                    domains.put(a, occurance);
                }
            }


            /* //for testing only
            for (HashMap.Entry<String, Integer> entry : domains.entrySet())
            {
                System.out.println(entry.getKey() + " " + entry.getValue());
            } */


            //check to see if Result Table exists.
            DatabaseMetaData metaTwo = conn.getMetaData();  
            ResultSet metaDataTwo = metaTwo.getTables(null, null, "Result", null);

            //Create Result table if not exists
            if (!metaDataTwo.next())
            {
                String queryFour = "CREATE TABLE Result (ind INT AUTO_INCREMENT, domain VARCHAR(255), dailyCount INT, theDate DATE, PRIMARY KEY ( ind ))";
                PreparedStatement statementFour = conn.prepareStatement(queryFour);
                statementFour.executeUpdate();
                conn.commit();
            }


            //insert hashmap into Result table.
            String queryFive = "INSERT INTO Result (ind, domain, dailyCount, theDate) VALUES (NULL, ?, ?, CURDATE())";
            PreparedStatement statementFive = conn.prepareStatement(queryFive);
            for (HashMap.Entry<String, Integer> entry : domains.entrySet())
            {
                statementFive.setString(1, entry.getKey());
                statementFive.setInt(2, entry.getValue());
                statementFive.executeUpdate();
                conn.commit();
            }


            //Read Result table into memory and display to system console
            Statement display = conn.createStatement();
            String query = "SELECT domain, " +
                " dailyCount / " +
                " (SELECT " +
                " SUM(dailyCount) " +
                " FROM Result) " +
                " * 100 " +
                " AS PercentGrowth " +
                " FROM Result " +
                " WHERE theDate " +
                " > DATE_SUB(CURDATE(), " +
                " INTERVAL 1 MONTH) " +
                " ORDER BY PercentGrowth " +
                " DESC LIMIT 50 ";
            ResultSet finalResult = display.executeQuery(query);
            while (finalResult.next())
            {
                System.out.println(finalResult.getString("domain") + " " + finalResult.getString("PercentGrowth"));
            }
            finalResult.close();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
        finally
        {
            //close the connection to the database
            conn.close();
        }
    }
}

【问题讨论】:

    标签: java mysql jdbc


    【解决方案1】:

    如果表存在,则需要删除。

    【讨论】:

    • 杰,谢谢。但是,我需要每天添加到结果表中,并且我使用 TempResult 表通过对这两个执行等效于 MINUS 来确定将哪些新条目放入“邮件”中。
    • ok 等等,您要将这些条目放入 TempResult,然后将它们放入 Result?重复条目只会出现在 ID 上,因此从 TempResult 中获取您所拥有的内容并插入到 Result 中,如果您在没有“ID”列的情况下执行此操作,如果您将 Result 设置为自动递增,它应该只给自己自己的 ID。
    • 其实,我想我现在知道问题出在哪里了....傻我。我想我需要为设置的差异添加一个额外的表,完成后我会删除它......我稍后会玩这个来确认我的发现。
    【解决方案2】:

    我发现了我的主要错误。我需要创建一个额外的临时表来保存设置的差异,将其导入哈希映射,然后在完成后删除 tis 表。我的问题解决了。我只需要修复我的最终查询。

    这是更新的代码。 请原谅格式错误*

        import java.sql.Connection;
        import java.sql.DriverManager;
        import java.sql.SQLException;
        import java.sql.*;
        import java.time.*;
        import java.util.*;
    
    
        public class Test 
        {
            public static void main(String[] args) throws Exception
            {
                String ConnectionURL = "jdbc:mysql://www.xxxxxxxxx:3306/Emails?autoReconnect=true&useSSL=false";
                String user = "xxxxxxxxxxxxxxx";
        String password = "xxxxxxxxxxxxxxxxxxxxx";
        String driver = "com.mysql.jdbc.Driver";
        Connection conn = null;
        List<String> addresses = new ArrayList<String>();
    
        //establish connection to DB
        try 
        {
            // The newInstance() call is a work around for some
            // broken Java implementations
            Class.forName(driver).newInstance();
        } 
        catch (Exception ex) 
        {
            // handle the error
            System.out.println(ex.getMessage());
        }
    
        //connect to DB and perform queries
        try 
        {
            //get  connection to the database 'Emails'
            conn = DriverManager.getConnection(ConnectionURL, user, password);
            conn.setAutoCommit(false);
    
            //check to see if TempResult Table exists.
            DatabaseMetaData metaOne = conn.getMetaData();
            ResultSet metaDataOne = metaOne.getTables(null, null, "TempResult", null);
    
            //Create temporary result table TempResult if not exists
            if (!metaDataOne.next())
            {
                String queryOne = "CREATE TABLE TempResult (ind INT AUTO_INCREMENT, addr VARCHAR(255), PRIMARY KEY ( ind ))";
                PreparedStatement statementOne = conn.prepareStatement(queryOne);
                statementOne.executeUpdate();
                conn.commit();
            }
    
    
            //create another temporary table for the differences only which will be dropped when process
            //is complete.
            String tempQueryOne = "CREATE TABLE Temp (ind INT AUTO_INCREMENT, addr VARCHAR(255), PRIMARY KEY ( ind ))";
            PreparedStatement queryStmtOne = conn.prepareStatement(tempQueryOne);
            queryStmtOne.executeUpdate();
            conn.commit();
    
            String tempQueryTwo = "INSERT INTO Temp (SELECT * FROM mailing e WHERE NOT EXISTS (SELECT * FROM TempResult t WHERE e.ind = t.ind))";
            PreparedStatement queryStmtTwo = conn.prepareStatement(tempQueryTwo);
            queryStmtTwo.executeUpdate();
            conn.commit();
    
            //Insert set difference between mailing and TempResult into TempResult
            String queryTwo = "INSERT INTO TempResult (SELECT * FROM mailing e WHERE NOT EXISTS (SELECT * FROM TempResult t WHERE e.ind = t.ind))";
            PreparedStatement statementTwo = conn.prepareStatement(queryTwo);
            statementTwo.executeUpdate();
            conn.commit();
    
    
            //now read into memory table TempResult into an arraylist
            //parse each email to obtain the domain of each email only  
            Statement queryThree = conn.createStatement();
            ResultSet result = queryThree.executeQuery("SELECT addr FROM Temp");
            while (result.next())
            {
                String delimiter = "[@]";
                String elements[] = result.getString("addr").split(delimiter);      
                addresses.add(elements[1]);
                //System.out.println(result.getString("addr"));
            }
            queryThree.close();
            result.close();
    
    
            //now map the arraylist to a HashMap to create a 'dictionary' with counts on the domains.
            int occurance;
            int temp;
            HashMap<String, Integer> domains = new HashMap<String, Integer>();
            for (String a : addresses)
            {
                if(domains.containsKey(a))
                {
                    temp = domains.get(a);
                    occurance = temp + 1;
                    domains.replace(a, occurance);
                }
                else
                {
                    occurance = 1;
                    domains.put(a, occurance);
                }
            }
    
    
            //for testing only
            for (HashMap.Entry<String, Integer> entry : domains.entrySet())
            {
                System.out.println(entry.getKey() + " " + entry.getValue());
            }
    
    
            //check to see if Result Table exists.
            DatabaseMetaData metaTwo = conn.getMetaData();  
            ResultSet metaDataTwo = metaTwo.getTables(null, null, "Result", null);
    
            //Create Result table if not exists
            if (!metaDataTwo.next())
            {
                String queryFour = "CREATE TABLE Result (ind INT AUTO_INCREMENT, domain VARCHAR(255), dailyCount INT, theDate DATE, PRIMARY KEY ( ind ))";
                PreparedStatement statementFour = conn.prepareStatement(queryFour);
                statementFour.executeUpdate();
                conn.commit();
            }
    
    
            //insert hashmap into Result table.
            String queryFive = "INSERT INTO Result (ind, domain, dailyCount, theDate) VALUES (NULL, ?, ?, CURDATE())";
            PreparedStatement statementFive = conn.prepareStatement(queryFive);
            for (HashMap.Entry<String, Integer> entry : domains.entrySet())
            {
                statementFive.setString(1, entry.getKey());
                statementFive.setInt(2, entry.getValue());
                statementFive.executeUpdate();
                conn.commit();
            }
    
    
            //Read Reult table into memory and display to system console
            Statement display = conn.createStatement();
            String query = "SELECT domain, " +
                " dailyCount / " +
                " (SELECT " +
                " SUM(dailyCount) " +
                " FROM Result) " +
                " * 100 " +
                " AS PercentGrowth " +
                " FROM Result " +
                " WHERE theDate " +
                " > DATE_SUB(CURDATE(), " +
                " INTERVAL 1 MONTH) " +
                " ORDER BY PercentGrowth " +
                " DESC LIMIT 50 ";
            ResultSet finalResult = display.executeQuery(query);
            while (finalResult.next())
            {
                System.out.println(finalResult.getString("domain") + " " + finalResult.getString("PercentGrowth"));
            }
            finalResult.close();
    
    
            //clean up and drop table 'Temp'
            String tempQueryThree = "DROP TABLE Temp";
            PreparedStatement queryStmtThree = conn.prepareStatement(tempQueryThree);
            queryStmtThree.executeUpdate();
            conn.commit();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
        finally
        {
            //close the connection to the database
            conn.close();
                }
            }
        }
    

    【讨论】:

      最近更新 更多