0

我正在尝试将一些数据从 excel 文件插入到表中。我有两个excel文件如下:

Test2:
5/12/2012     5/18/2012 ABQ ANC 1   52
5/12/2012     5/18/2012 ABQ ANC 2   30
5/12/2012     5/18/2012 ABQ ANC 3   34
5/12/2012     5/18/2012 ABQ ANC 4   41
5/12/2012     5/18/2012 ABQ ANC 5   53--->duplicate row
5/12/2012     5/18/2012 ABQ ANC 6   18
5/12/2012      5/18/2012    ABQ ANC 7   4
5/12/2012      5/18/2012    ABQ ATL 1   389
5/12/2012     5/18/2012 ABQ ATL 2   312

测试1:

5/12/2012     5/18/2012 ABQ ATL 4   259
5/12/2012     5/18/2012 ABQ ATL 5   362
5/12/2012     5/18/2012 ABQ ATL 6   240
5/12/2012     5/18/2012 ABQ ATL 7   88
5/12/2012     5/18/2012 ABQ ANC 5   53--->duplicate row
5/12/2012     5/18/2012 ABQ AUS 2   2
5/12/2012     5/18/2012 ABQ BDL 1   164
5/12/2012     5/18/2012 ABQ BDL 2   128
5/12/2012     5/18/2012 ABQ BDL 3   132

我的桌子一开始是空的。所以我插入第一个文件(test2),它工作正常。插入第二个文件(test1)时,它应该在 test1 的第 5 行给出“违反唯一约束”异常。我故意复制该行以进行测试。我编写了以下代码来进行插入。如您所见,批量大小为 3。

插入第二个文件时,代码执行第一批(前 3 行)很好。在第二批(第 4-6 行)中,由于第 (5) 行之一重复,因此引发 BatchUpdatException。我捕获了该异常,并在 catch 块中,我一次处理每一行(第 4-6 行)。所以第 4 行的插入应该可以正常工作。但事实并非如此。相反,它会引发 sqlException。第 5 行也抛出异常(重复行)。但第 6 行没有。第 6 行 executeUpdate() 运行良好。此时,如果我查看我的数据库表,我看到第 4 行也与第 6 行一起插入到表中。怎么会发生这种情况,它只是在第 4 行抛出异常?

我的目标是让用户知道重复行在哪里。由于这种异常行为,当用户尝试插入第二个文件时,会被告知第 4 行和第 5 行中存在重复行。

String sqlStatement = "INSERT INTO DMD_VOL_UPLOAD (ORIGIN, DESTINATION, DAY_OF_WEEK, EFFECTIVE_DATE, DISCONTINUE_DATE, VOLUME)";
    int batchSize=3;
    sqlStatement += " VALUES(?, ?, ?, ?, ?, ?)";
    con = session.connection();
        pstmt = con.prepareStatement(sqlStatement);
    for(currentRow=1; currentRow<=rowCount; currentRow++){
        try{
                forecastBatch = (ForecastBatch) list.get(currentRow-1);                                 
                pstmt = (PreparedStatement) prepareStatement(pstmt, forecastBatch);         
                pstmt.addBatch();               
                if(currentRow % batchSize == 0 || currentRow==rowCount){
                    updateCounts = pstmt.executeBatch();
                    con.commit();
                    pstmt.clearBatch();
                }                           
        }catch(BatchUpdateException e){
                int endPoint = currentRow;
                int i;
                for(i=currentRow-batchSize; i<endPoint; i++){
                    forecastBatch = (ForecastBatch) list.get(i);
                    try{
                        pstmt = (PreparedStatement) prepareStatement(pstmt, forecastBatch); 
                        pstmt.executeUpdate();**strong text**
                        con.commit();
                    }catch(SQLException ex){
                        errorRowNum = errorRowNum + (i+1) + ", ";
                        ex.printStackTrace();
                    }   
                }
        }catch(SQLException e){
                e.printStackTrace();
        }
    }//end of the first for loop
4

1 回答 1

1

当你executeBatch做一批语句时,有的语句可能成功,有的语句可能失败。如果一个语句失败,这并不意味着 JDBC 驱动程序回滚成功的语句。如果一条语句失败,JDBC 驱动程序可能会选择尝试执行批处理中的所有语句,或者一旦语句失败,它可能会选择停止执行批处理中的语句(听起来您正在使用的驱动程序选择停止执行语句为一旦出现故障)。

当你得到一个BatchUpdateException,你需要打电话getUpdateCounts。这将为您提供一个数组int,告诉您语句更新了多少行,Statement.SUCCESS_NO_INFO指示语句成功但没有可用的行数,或者Statement.EXECUTE_FAILED表示语句失败。我希望您会返回一个双元素数组,指示批处理中的第一条语句(电子表格中的第 4 行)成功,而批处理中的第二条语句(电子表格中的第 5 行)失败。数组中缺少第三个元素表示批处理中的第三条语句(电子表格中的第 6 行)未执行。您的重试代码只需要重试未执行的语句。在这种情况下,只需要重试第三条语句(电子表格中的第 6 行),因为它BatchUpdateException已经告诉您第一条语句成功而第二条语句失败。

于 2012-04-27T20:44:11.187 回答