Java 执行 Postgresql Jdbc 类型异常时,复杂sql难定位的解决方案

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介: Java 执行 Postgresql Jdbc 类型异常时,复杂sql难定位的解决方案

由于复杂sql篇幅比较长,这里就随意执行一串比较简单的sql作为代表,怎么去实现较为精准的异常sql定位,帮助各位开发小伙伴解决问题

ps:文章末尾有解决该异常的彩蛋,能让开发更顺畅哟

相关驱动前置说明

 <!-- postgresql jdbc 驱动包 -->
 <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.24</version>
        </dependency>
       
        <!-- druid jdbc连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>

执行sql如下:

        // 随意编写的一句sql
        String sql = "select * from cr_vehicle_type " +
                "where VEHICLE_TYPE_ID in(?,200) " +
                " and create_time > ? ";
        // create_time 字段故意传入时间字符串,pg会报错,mysql是不会的
        EDb.use("pg").find(VehicleType.class,sql,100, "2020-01-08");

异常信息如下:

com.jfinal.plugin.activerecord.ActiveRecordException: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: operator does not exist: timestamp without time zone > character varying
  建议:No operator matches the given name and argument types. You might need to add explicit type casts.
  位置:81

    at com.edbplus.db.EDbPro.find(EDbPro.java:1144)

如果是以上异常信息提示的话,我们很难去定位到 create_time 字段的类型有异,简单的sql还好,复杂的sql有好多字段,光凭 【位置:81】 和 【ERROR: operator does not exist: timestamp without time zone > character varying】 等关键字眼,对开发人员来说,实在太难了

所以建议结合druid进行相关简单的改造

继承 FilterEventAdapter 实现sql上下游动作的相关监听

public class EDbDruidSqlLogFilter extends FilterEventAdapter{
   ...
   ...
   /**
     * druid自带的sql异常之上下游监听 -> 执行sql报错之后触发
     * @param statement
     * @param sql
     * @param error
     */
    @Override
    protected void statement_executeErrorAfter(StatementProxy statement, String sql, Throwable error) {
        try{
            if(error.getMessage().contains("位置")){
                String errStr = error.getMessage();
                // 提取 【位置:81】 里的数字,便于结合sql语句进行精准范围定位
                int idx = ReUtil.getFirstNumber(errStr.substring(errStr.indexOf("位置")));
                int startIdx,endIdx =0;
                if((idx - 20)>0){
                    startIdx = idx - 20;
                }else{
                    startIdx = 0;
                }
                if((idx + 10)<sql.length()){
                    endIdx = idx + 10;
                }else{
                    endIdx = sql.length();
                }
                // 弥补pgsql打印时,无法精准输出异常字段的问题
                String errMsg = "sql异常位置:" + sql.substring(startIdx,endIdx) ;
                log.error(errMsg);
            }
        }catch (Throwable e)
        {
          log.error(e);
        }
    }
}

结果如下

image.png

如上图所示,我们就可以通过 【sql异常位置: and create_time > ?】的提示并结合【ERROR: operator does not exist: timestamp without time zone > character varying】,非常方便定位到异常信息和问题,能很快的发现问题并修复该异常,节省大量的测试时间和结构性差异对比

ps:其实解决格式化异常最好的方式是数据库驱动自己兼容实现:

stringtype=unspecified -> 格式化参数即可
-- 连接示例参考:
jdbc:postgresql://192.168.1.11:5432/pg_test?currentSchema=public&reWriteBatchedInserts=true&TimeZone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&stringtype=unspecified

希望有帮助到大家,在java往postgresql开发的路上快速迭代和提升~~~

欢迎大家留言

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
4月前
|
SQL 安全 网络安全
SQL安装程序规则错误解决方案
在安装SQL Server时,遇到安装程序规则错误是一个比较常见的问题
|
4月前
|
SQL 安全 Windows
SQL安装程序规则错误解析与解决方案
在安装SQL Server时,用户可能会遇到安装程序规则错误的问题,这些错误通常与系统配置、权限设置、依赖项缺失或版本不兼容等因素有关
|
4月前
|
SQL 安全 关系型数据库
SQL错误代码1303解析与解决方案:深入理解并应对权限问题
在数据库管理和开发过程中,遇到错误代码是常见的事情,每个错误代码都代表着一种特定的问题
|
4月前
|
SQL 数据库
执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)之解决方案
执行 Transact-SQL 语句或批处理时发生了异常。 (Microsoft.SqlServer.ConnectionInfo)之解决方案
700 0
|
4月前
|
SQL 数据库
SQL-serve数据库不能连接本地服务器的解决方案
SQL-serve数据库不能连接本地服务器的解决方案
529 0
|
5月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
6月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
79 3
|
6月前
|
SQL 安全 关系型数据库
PostgreSQL SQL注入漏洞(CVE-2018-10915)--处理
【8月更文挑战第8天】漏洞描述:PostgreSQL是一款自由的对象关系型数据库管理系统,支持多种SQL标准及特性。存在SQL注入漏洞,源于应用未有效验证外部输入的SQL语句,允许攻击者执行非法命令。受影响版本包括10.5及更早版本等。解决方法为升级PostgreSQL
394 2
|
6月前
|
Java Apache Android开发
Struts 2的秘密武器:揭秘社区中隐藏的学习宝藏,让你从新手到高手的不归路!
【8月更文挑战第31天】Struts 2学习资源丰富,除官方文档外,TutorialsPoint和W3Schools等网站提供详尽教程;《Apache Struts 2实战》等书籍含全面实例。Udemy、Pluralsight及YouTube上视频课程众多,Apache Software Foundation亦有网络研讨会。实践方面,GitHub上的开源项目及个人小项目都是好选择。寻求帮助可访问Apache官方论坛、Stack Overflow等平台。
56 0
|
6月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
704 0