Java 跳过JDBC中的异常
我通过一个java程序运行一个大型的、多样化的数据集,该程序从一个旧模式导入数据,进行转换,然后将数据插入一个新模式。该程序在试点数据上测试成功,但在实际数据上抛出异常 我希望能够计算整个数据集引发的异常数量,并记录引发异常的记录。有人能告诉我怎么做吗? 目前,当程序遇到第一个异常时,程序正在崩溃,因此我不知道如果代码能够在整个数据集中运行,会出现一个异常还是1000个异常 我在下面附上我的代码的相关方面。如何更改它,以便在记录异常的计数和ClientNumber时跳过异常Java 跳过JDBC中的异常,java,jdbc,Java,Jdbc,我通过一个java程序运行一个大型的、多样化的数据集,该程序从一个旧模式导入数据,进行转换,然后将数据插入一个新模式。该程序在试点数据上测试成功,但在实际数据上抛出异常 我希望能够计算整个数据集引发的异常数量,并记录引发异常的记录。有人能告诉我怎么做吗? 目前,当程序遇到第一个异常时,程序正在崩溃,因此我不知道如果代码能够在整个数据集中运行,会出现一个异常还是1000个异常 我在下面附上我的代码的相关方面。如何更改它,以便在记录异常的计数和ClientNumber时跳过异常 try {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection sourceConn = DriverManager.getConnection("jdbc:odbc:source_db");
Statement st = sourceConn.createStatement();
Connection destinationConn = DriverManager.getConnection("jdbc:odbc:destination_db");
int ClientNumber;
String Name;
ResultSet rest = st.executeQuery("SELECT * FROM sourceTable");
PreparedStatement ps5 = null;
PreparedStatement ps6 = null;
PreparedStatement ps7 = null;
PreparedStatement ps8 = null;
while(rest.next()){
ClientNumber = rest.getInt(1);
Name = rest.getString(2);//plus other variables skipped here for brevity
ps5 = destinationConn.prepareStatement(
"INSERT INTO Clients ("
+ "ClientNumber, Name) "
+"VALUES (?, ?)"
);
ps5.setInt(1, ClientNumber);
ps5.setString(2, Name);
ps5.executeUpdate();
//some other stuff for ps6,ps7,ps8
destinationConn.commit();
}
//ps5.close();
}
catch (ClassNotFoundException cnfe){cnfe.printStackTrace();}
catch (SQLException e) {e.printStackTrace();}
下面的代码给出了一个提示。发生错误时打印ClientNumber取决于要打印的内容。但是您可以在内部catch中添加另一个日志。我故意使用exception而不是SQLException,因为您得到的异常可能是您在帖子中没有提到的任何类型的异常
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection sourceConn = DriverManager.getConnection("jdbc:odbc:source_db");
Statement st = sourceConn.createStatement();
Connection destinationConn = DriverManager.getConnection("jdbc:odbc:destination_db");
int ClientNumber;
int errCounter = 0;
String Name;
ResultSet rest = st.executeQuery("SELECT * FROM sourceTable");
PreparedStatement ps5 = null;
PreparedStatement ps6 = null;
PreparedStatement ps7 = null;
PreparedStatement ps8 = null;
while(rest.next()){
try {
ClientNumber = rest.getInt(1);
Name = rest.getString(2);//plus other variables skipped here for brevity
ps5 = destinationConn.prepareStatement(
"INSERT INTO Clients ("
+ "ClientNumber, Name) "
+"VALUES (?, ?)"
);
ps5.setInt(1, ClientNumber);
ps5.setString(2, Name);
ps5.executeUpdate();
//some other stuff for ps6,ps7,ps8
destinationConn.commit();
}catch (Exception e) {
e.printStackTrace();
errCounter++;
}
} //end while
if(errCounter > 0)
System.out.println(String.format("Error occured %d times", errCounter));
} catch (ClassNotFoundException cnfe){
cnfe.printStackTrace();}
}
这样如何,只需以不同的方式编写循环:
try {
// TODO: write your setup code here
boolean hasNext = false;
try {
hasNext = rest.next();
}catch (Exception e) {
// TODO: log exception, increase a counter
}
while(hasNext){
try {
// TODO: write your processing code here
}catch (Exception e) {
// TODO: log exception, increase a counter
}
try {
hasNext = rest.next();
}catch (Exception e) {
// TODO: log exception, increase a counter
hasNext = false; //prevent infinite loops
}
}
} catch (Exception e){
// TODO: this should never happen, handle ClassNotFoundException etc.
}
更新:我们可以避免调用next()两次,如下所示:
try {
// TODO: write your setup code here
while(true){
try {
if(!rest.next()){
break;
}
}catch (Exception e) {
// TODO: log exception, increase a counter
break;
}
try {
// TODO: write your processing code here
}catch (Exception e) {
// TODO: log exception, increase a counter
}
}
} catch (Exception e){
// TODO: this should never happen, handle ClassNotFoundException etc.
}
将
SQLException
的catch
块放得更靠近异常实际发生的部分(您没有提到,但我猜是在循环内部)。@qqilihq谢谢。我正在做这件事,因为实际上有大量的代码,这意味着许多try-catch块。while(rest.next)块请求它自己的try-catch块,而不是让我在其中创建几个try-catch块。你能建议一种方法,我可以改变while的定义,这样我就可以把它的组件分成几个try-catch块吗?我已经完成了整合你的建议。我将您的标记为答案并给出+1,因为创建布尔hasNext变量非常有用。最后,我为在rest上运行的每一行代码创建了一个单独的try-catch块,这就产生了所有的不同。但是,在使用hasNext布尔变量后,这变得更加可行。谢谢,我添加了第二个版本,它不再需要调用next()两次,也不再需要hasNext。有什么原因不好调用next()两次吗?+1感谢您的帮助。我最终用了一种不同的方法来解决这个问题。不过,您的计数想法是有帮助的。谢谢,不客气。您的应用程序似乎正在执行经典的迁移或ETL工作。您正在跳过某些不可处理的记录,可能是因为不兼容或输入数据质量差。springbatchframework试图提供一些开箱即用的方法来处理此类问题,如跳过、块读写等。我将研究Spring批处理框架。我使用其他的Spring工具,如果一切都使用Spring就好了。