我使用“postgresql-9.3-1102.jdbc3.jar”来连接数据库。
当我有一个异常,比如一个空值,
我可以用几种方法来捕捉异常。
例如
试试看{
............}
catch(PSQLException服务器){
.........
}
或者
尝试{.......}
catch(SQLException se){.......}
或者
试试看{
.......}
catch(异常se){
........
}
我的目标是在我感兴趣的情况下捕获特定的SQLState。
例如,我想捕获一个字段的无效空值,
postgres返回值“23502”SQLState,但在前面的任何一个“catch”中,我都无法执行此操作,因为错误代码是继承的,我无法检查它。
在前面的“catch”中,我可以使用“.getmessage”,但这并不能帮助我检查SqlState
谢谢你的意见。

最佳答案

捕捉SQLExceptoin然后使用SQLException.getSQLState()并进行比较,看看它是否符合您的要求。

catch (SQLException ex) {
   final String ss = ex.getSQLState();
   //... blah blah ...
}

有关SQLState的详细信息,请参见PostgreSQL error codes。(虽然大多数状态类别和代码在DBs中是标准的,但并不是所有的DBs都以相同的方式实现它们并在相同的时间抛出它们,而且大多数DBs都有特定于DB的附加项)。
无法捕获基于SQLState的异常。不幸的是,你必须抓住它,如果它不是你想要的,就把它包起来再扔。(不要不包装就重新开始,否则会丢失原始堆栈)。
在JDBC 4中,可以捕获类似于SQLExceptionSQLNonTransientException子类,但前提是JDBC驱动程序抛出这些子类。在编写时,PgJDBC不支持它们,并且总是简单地抛出SQLException,因此如果您试图捕获它们,您将永远不会捕获任何内容。(欢迎使用修补程序!).
在现实世界中,您通常对许多不同的错误条件感兴趣,并希望根据它们执行不同的操作。
有点像未经测试的东西,写在窗户上:
} catch (SQLException ex) {
  final String ss = ex.getSQLState();
  if (ss.equals("40001") || ss.equals("40P01")) {
     /* It is a serialization failure or a deadlock abort. Retry the tx. */
     retry_transaction = true;
  } else if (ss.startsWith("08") || ss.startsWith("53")) {
     /* It is a connection error or resource limit. Reconnect and retry. */
     try {
        conn.close();
     } catch (SQLException ex) {
        logger.log("Error closing suspected bad connection after SQLState " + ss, ex);
     }
     conn = null; /* App knows to reconnect if it sees a null connection */
     retry_transaction = true;
  } else {
     throw new MyAppException(ex);
  }
}

... 如果你的应用程序发现一个空连接,它就会知道重新连接,并保存它刚刚尝试的事务的记录,以便在遇到死锁或序列化失败时可以在循环中重试,直到成功为止。
实际上,你会比这更聪明,增加重试率限制等等。这只是一个简单的例子。
有关更多详细信息,请在测试可浇铸性后将异常强制转换为PSQLException,或者首先将其捕获为PSQLException。然后获取详细信息:
ex.getServerErrorMessage()

这会给你一个ServerErrorMessage的详细字段。

10-08 19:04