【问题标题】:Java Import data from CSV into SQL prevent double entryJava 将数据从 CSV 导入 SQL 防止重复输入
【发布时间】:2014-02-12 00:26:52
【问题描述】:

我有以下代码。我不确定如何安排它们,以便在将记录添加到 SQL 数据库之前检查 CSV 中的条目。 问题是我仍在向 sql 中添加双记录

try {
        br = new BufferedReader(new FileReader(file));
        String[] data1 = br.readLine().split(cvsSplitBy);

        while ((line = br.readLine()) != null) {
            String queryCheck = "SELECT Count(Name) from DB WHERE Name = ?";

            PreparedStatement st = conn.prepareStatement(queryCheck);
            //value is the data of the name column in the CSV
            st.setString(1, data1[0]);
            ResultSet rs = st.executeQuery();
            boolean recordFound = rs.next();

            if (recordFound) {
                //dont add record

                System.out.println("found " + data1[0]);

            } else {


                String[] data = line.split(cvsSplitBy);

                String sql2 = "INSERT INTO DB (Name, ID, Age) values (?, ?, ?)";
                pstmt = conn.prepareStatement(sql2);
                pstmt.setString(1, data[0]);
                pstmt.setString(2, data[1]);
                pstmt.setString(3, data[2]);
                pstmt.executeUpdate();
            }

        }

【问题讨论】:

  • while 循环放入else
  • 即使我这样做了仍然添加双记录
  • 您确定您在比较name 的正确值吗?您是如何从 csv 中检索到 value 的值的?
  • 好的,现在还有一个问题..找到记录时,它将跳过对其余条目的检查。因此发现后的所有内容都不会添加
  • 添加 try/catch 块的其余部分...是否抛出任何异常。您还可以将代码更新为您现在的代码吗?

标签: java sql csv


【解决方案1】:

您上面的代码仅检查数据库中是否存在第一行数据。 将您的查询检查也放入while 循环中。

你应该简单地SELECT * 而不是SELECT count(Name) 因为SELECT count(Name) 会给你结果,即使计数结果是0

试试这个:

    br = new BufferedReader(new FileReader(file));
    String queryCheck, insert;
    PreparedStatement st;
    ResultSet rs;
    boolean recordFound;
    while ((line = br.readLine()) != null) {
        queryCheck = "SELECT * from DB WHERE Name = ?";
        String[] data1 = line.split(cvsSplitBy);
        System.out.println("Name= " + data1[0] + " , ID= " + data1[1] + " , Age= " + data1[2]);
        st = conn.prepareStatement(queryCheck);
        st.setString(1, data1[0]);
        rs = st.getResultSet();
        recordFound = rs.next();

        if (recordFound) {
            System.out.println(data1[0]+" already exist in the database!");
        }
        else{
            String[] data = line.split(cvsSplitBy);
            insert = "INSERT INTO DB (Name, ID, Age) values (?, ?, ?)";
            pstmt = conn.prepareStatement(insert);
            pstmt.setString(1, data[0]);
            pstmt.setString(2, data[1]);
            pstmt.setString(3, data[2]);
            pstmt.executeUpdate();
        }

    }

【讨论】:

  • 可能希望将一些变量声明移到 while 循环之外,String queryCheckString[] data1PreparedStatement st 等,这样您就不会在每次迭代时重新声明它们。
  • 哇。我在这里有点困惑..我现在需要时间看看这个
  • @ninabei 慢慢来 :)
  • @Rafa El 感谢您的帮助,终于我明白了代码 =D
【解决方案2】:

看起来有几个逻辑错误。您需要使用 if 语句来控制何时调用插入。我反转了您的 recordFound 变量,因为如果找到记录,您只想什么都不做,因此不需要 else 块。看起来像这样:

     if (!recordFound) {
            while ((line = br.readLine()) != null) {

                 String[] data = line.split(cvsSplitBy);

                 String sql2 = "INSERT INTO DB (Name, ID, Age) values (?, ?, ?)";
                 pstmt = conn.prepareStatement(sql2);
                 pstmt.setString(1, data[0]);
                 pstmt.setString(2, data[1]);
                 pstmt.setString(3, data[2]);
                 pstmt.executeUpdate();
           }
     }

另外,我相信你也在滥用rs.next() 电话;即使计数为 0,该值仍会返回,并且始终会导致 rs.next() 调用为 true 。您需要获取结果的值并查看它是否大于 0。像这样:

boolean recordFound = false;
PreparedStatement st = conn.prepareStatement(queryCheck);
//value is the data of the name column in the CSV
st.setString(1, value);
ResultSet rs = st.getResultSet();
rs.first();//move cursor to single result
if(rs.getInt(1) > 0)
    recordFound = true;     

此外,您正在以静态方式读取文件的第一行,然后在 found 块中尝试循环遍历它。您最初只需要循环遍历它,而不是查看第一行然后再循环

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2011-06-29
    • 1970-01-01
    相关资源
    最近更新 更多