微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle 19c jdbc 驱动程序不支持大于 30 字节的模式名称

如何解决Oracle 19c jdbc 驱动程序不支持大于 30 字节的模式名称

根据 Oracle 的 19c documentation

架构名可以是128个字节,表名可以是128个字节,列名可以是128个字节。

但是,每当我尝试使用大于 30 字节的架构名称时,我都会面临这个问题:

Caused by: java.sql.sqlException: Invalid argument(s) in call
at oracle.jdbc.driver.PhysicalConnection.setSchema(PhysicalConnection.java:9462)
at com.zaxxer.hikari.pool.ProxyConnection.setSchema(ProxyConnection.java:460)
at com.zaxxer.hikari.pool.HikariProxyConnection.setSchema(HikariProxyConnection.java)

使用的驱动程序是:

        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>19.7.0.0</version>
        </dependency>

看起来驱动程序不支持根据 12c 版本引入的更长的对象名称,是否可以以某种方式配置任何线索?是否也可能是一些 AWS RDS 特定问题?

在使用相同 jdbc url 的 sql Developer 上:

SELECT name,value FROM v$parameter WHERE name = 'compatible';

NAME       | VALUE
-------------------
compatible | 19.0.0

ALTER SESSION SET CURRENT_SCHEMA = VERY_VERY_VERY_LONG_SCHEMA_NAME;

Session altered.

更新: 反编译驱动程序代码后,这是我看到的:

public void setSchema(String schema) throws sqlException {
    try {
        String quoted = "\"[^\u0000\"]{0,28}\"";
        String unquoted = "(\\p{javaLowerCase}|\\p{javaUpperCase})(\\p{javaLowerCase}|\\p{javaUpperCase}|\\d|_|\\$|#){0,29}";
        String idPat = "(" + quoted + ")|(" + unquoted + ")";
        sqlException var10000;
        sqlException var9;
        if (schema == null) {
            var10000 = var9 = (sqlException)((sqlException)DatabaseError.createsqlException(this.getConnectionDuringExceptionHandling(),68).fillInStackTrace());
            throw var10000;
        } else if (!schema.matches(idPat)) {
            var10000 = var9 = (sqlException)((sqlException)DatabaseError.createsqlException(this.getConnectionDuringExceptionHandling(),68).fillInStackTrace());
            throw var10000;
        } else {
            String sql = "alter session set current_schema = " + schema;
            Statement stmt = null;
            try {
                stmt = this.createStatement();
                stmt.execute(sql);
    ...
}

意味着驱动程序被硬编码为仅接受 30 个字符。所以这似乎是 Oracle JDBC 驱动程序中的一个错误实现。有什么替代方案吗?

解决方法

在长标识符更改中,setSchema 似乎被遗忘(而且您似乎必须使用 Oracle 打开 SR 才能使其工作)

相反,JDBC长标识符的基本用法(包括按名称绑定)似乎工作正常。

示例

 def rs = stmt.executeQuery("select COL1,LAAAAAAAAAAAAAAAAAAAAAAAAAAAAARGE_NAME from LAAAAAAAAAAAAAAAAAAAAAAAAAAAAARGE_NAME.LAAAAAAAAAAAAAAAAAAAAAAAAAAAAARGE_NAME")
 
 while(rs.next())
 {
   println "col1= ${rs.getInt('COL1')} col2= ${rs.getInt('LAAAAAAAAAAAAAAAAAAAAAAAAAAAAARGE_NAME')}"
 } 

使用数据库版本 19.3.0.0.0 测试

驱动程序版本 19.3.0.0.0 和 21.1.0.0.0

,

来自您的documentation link

除非另有说明,以下规则列表适用于带引号和不带引号的标识符:

  1. 标识符名称的最大长度取决于 1101 初始化参数的值。

    • 如果 COMPATIBLE 设置为 12.2 或更高的值,则名称的长度必须为 1 到 128 个字节,以下情况除外:

      • 数据库名称限制为 8 个字节。
      • 磁盘组、可插拔数据库 (PDB)、回滚段、表空间和表空间集的名称限制为 30 个字节。
    • 如果 COMPATIBLE 设置为小于 12.2 的值,则名称的长度必须为 1 到 30 个字节,以下情况除外:

      • 数据库名称限制为 8 个字节。
      • 数据库链接的名称最长可达 128 个字节。

您需要检查 COMPATIBLE 初始化参数,如果它设置在 COMPATIBLE 以下,那么您被限制为 30 个字节。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。