Java 使用while循环处理异常
我正在使用postgreSql和Java,下面是eclipse控制台中显示的错误Java 使用while循环处理异常,java,sql,postgresql,jdbc,exception-handling,Java,Sql,Postgresql,Jdbc,Exception Handling,我正在使用postgreSql和Java,下面是eclipse控制台中显示的错误 org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "km_rel_user_test_details_pkey", 这里错误的原因是(我猜)由于数据库中存在重复的密钥, 我已经编写了一个while循环来处理这个异常,我只是想知道,这个方法是否正确,是否适用于所有情况,如果发现任何错误/要
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "km_rel_user_test_details_pkey",
这里错误的原因是(我猜)由于数据库中存在重复的密钥,
我已经编写了一个while循环来处理这个异常,我只是想知道,这个方法是否正确,是否适用于所有情况,如果发现任何错误/要求改进,我们将不胜感激,提前感谢,这是我的java方法
public String saveConceptTestDetails(String testId,String userId,String selected_ans, String check_user_save, String conceptTestOrder , int ans) {
boolean isInserted=false;
String newId1=null;
while(!isInserted){
try{
newId1=getNextVal(DBKeys.SEQ_REL_USER_TEST_DETAILS); // this is what generatres new Id
Hashtable resultHash=executeUpdate(new StringBuffer(" insert into "+DBKeys.TABLENAME_REL_USER_TEST_DETAILS+" ("+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_ID+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_TESTID+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_USERID+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_CREATEDDT+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_MODIFIEDDT+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_SELECTED_ANS+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_CHECK_USER_SAVE_TEST+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_TEST_TYPEORDER+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_TEST_VERSION+","+DBKeys.COLUMNNAME_REL_USER_TEST_DETAILS_SAVEANS+")values ("+newId1+","+testId+","+userId+",current_date,current_date,"+selected_ans+","+check_user_save+","+conceptTestOrder+",0,"+ans+")"));
isInserted=true;
}
catch (Exception e) {
System.out.println("Exception");
isInserted=false;
}
}
return newId1;
}
如果您有相同的异常,您将有无止境的循环 检查
executeUpdate
可以引发哪些异常,并使用适当的消息添加适当的catch块
例如:
catch (PSQLException) {
System.out.println("The key is already exist");
isInserted=true;
}
catch (SQLException e) {
System.out.println(e);
isInserted=false;
}catch (SQLTimeoutException e) {
System.out.println(e);
isInserted=false;
}
使用生成器的原因是为了避免这个问题,它应该确保您只获得未使用的ID。如果您不能在此处依赖此功能,您可以添加一个变通方法:
- 您可以先查询以查找表中的最大id。如果生成器允许设置下一个值,则将其更改为从那里开始,否则反复调用生成器,直到获得高于该最大值的密钥
- 您可以编写一个查询来获取现有的行号,并让插入代码检查id是否不在列表中(假设这是执行插入的唯一操作)
- 您可以在每次插入之前执行select计数,以确保id未被使用
您的insert SQL似乎没有引用其值,您连接的值周围没有单引号,因此结果将不正确(除非您将单引号作为传入字符串的一部分)。您最好使用PreparedStatements,它们不仅可以防止SQL注入,还可以为您处理参数值的引用,因此更不容易出错。正确的方法是检查
getNextVal
返回重复键值的原因。我在谷歌上搜索过,但序列生成的代码和所有内容都是正确的,donno y它不工作。getNextVal
做什么?它是一个序列生成器,生成下一个id,就像mysql中的autoincrement一样。+1用于使用PreparedStatement
,我想补充一点,除非您确定需要它的线程安全(同步)功能,否则您应该避免使用StringBuffer
行为。@NoData:像这样使用StringBuffer是很奇怪的,但由于无竞争的同步并不太昂贵(尤其是与jdbc开销相比),它似乎相对不重要。伙计们,我们公司有自己的框架(有点类似于struts 1.3),而且这个项目已经有10多年的历史了,ExecuteUpdate只将StringBuffer作为参数,我无法避免StringBuffer