如何使用Java中的Postgres JDBC驱动程序获取导致SQLException的sql语句?

背景在我目前的项目中 – 没有GUI前端的服务器产品,我正在尝试编写更好的错误处理支持.当前错误输出到日志,通常不被用户读取.我们使用PostgreSQL作为我们的数据库后端,我们使用直接JDBC调用和DAO通过数据库池来访问...

背景

在我目前的项目中 – 没有GUI前端的服务器产品,我正在尝试编写更好的错误处理支持.当前错误输出到日志,通常不被用户读取.

我们使用PostgreSQL作为我们的数据库后端,我们使用直接JDBC调用和DAO通过数据库池来访问它.大多数与数据库相关的异常都包含在一个实现RuntimeException的通用DatabaseException类中,并尝试从传递的异常中提取调试和状态信息.在我们的特定情况下,它将访问底层的PostgreSQL数据库驱动程序 – PSQLException.到目前为止,这种方法可以很好地获取有关导致数据库错误的更多详细信息,下面将介绍明显的例外情况.

此外,由于我们有非常具体的性能和遗留支持要求,我们有很多自定义SQL魔术,使得跟踪堆栈跟踪的时间更加集中,但并非不可能或困难.

问题描述

我注意到,当我们因错误的SQL语句而得到SQLException时,驱动程序的实现不会返回导致错误的SQL语句.在做了一点搜索之后,我发现有一种方法可以在启动时将PostgreSQL驱动程序放入调试模式,并让它显示有关其内部查询的属性.但是,我们不希望在我们的生产环境中以调试模式运行驱动程序(老实说,我还没弄清楚如何让它进入freakin模式!).

有没有其他人之前处理过同样的问题,并找到了解决方案?如果没有,是否有一些OOP模式用于在执行之前存储查询信息,然后将该信息分配给抛出的异常?或者大多数开发人员只是觉得他们不需要完整的查询来解决数据库问题?老实说,我不需要它,因为我有完整的堆栈跟踪,我可以查找调用查询,但它肯定加快我的调试,因为它是我在错误日志中看到的第一件事.

解决方法:

我假设当你调用执行查询时你得到了语句,并且你收到了异常,所以那时你有两个.看起来你可以在那里进行分析.

但是,也许你正在进一步追赶.那么,你可能会做的是你自己的自定义子类Exception,DatabaseException,添加一个带有getter和setter的triggeringSQLStatement成员,然后在你尝试执行语句的地方,从PostgreSQL中捕获原始的Exception,创建一个新的DatabaseException,将triggeringSQLStatement设置为刚刚执行的语句,并在DatabaseException上调用initCause()以将从PostgreSQL捕获的Exception设置为异常的原因;然后抛出你的DatabaseException,捕获它的调用代码将有一个对象打印出一个非常不错的堆栈跟踪发生的事情,并提供对导致问题的SQL语句的访问.有关此方法的更多信息,您可能希望研究Java Exception链.即使你没有使用我刚才描述的所有内容,我认为你肯定应该使用Java Exception链接.

如果代码中没有任何地方可以访问导致问题的SQL语句和抛出异常的SQL语句,那么我会非常好奇为什么以及如何实现这一点.我建议你重新设计你的代码,这样你就有了这样的地方.

编辑:因为您希望在日志中首先看到SQL语句,所以您可能还会覆盖DatabaseException的toString()方法(或其他适当的方法;我不确定打印出Exception时会调用什么)打印出包含的SQL语句,假设您按上述方法包含它.

本文标题为:如何使用Java中的Postgres JDBC驱动程序获取导致SQLException的sql语句?

基础教程推荐