如何在不出现 ORA-01460:未实现或不合理的转换错误的情况下将大字符串设置为参数?

Posted

技术标签:

【中文标题】如何在不出现 ORA-01460:未实现或不合理的转换错误的情况下将大字符串设置为参数?【英文标题】:How to set large string as param without getting ORA-01460: unimplemented or unreasonable conversion error? 【发布时间】:2019-12-06 08:20:03 【问题描述】:

在 spring-boot 中使用 namedParameterJdbcTemplate(Oracle db 版本 12 和 odbc8 驱动程序 12.2)

我在执行与大于 4000 个字符的参数绑定的 SELECT 查询时遇到以下错误,而更新查询工作正常。

ORA-01460:请求的转换未实现或不合理

我正在尝试执行的单元测试;

@Test
public void testSqlSelectQueryLargeStringParameter() 
    MapSqlParameterSource params = new MapSqlParameterSource();
    params.addValue("param", theLargeStr);

    // @formatter:off
    String sql =
        "SELECT NULL id, NULL text FROM DUAL WHERE 'X' != :param ";
    // @formatter:on

    namedParameterJdbcTemplate.queryForRowSet(sql, params);

有没有办法通过MapSqlParameterSource 设置这个大参数

【问题讨论】:

【参考方案1】:

我是 @ahmet-orhan 的同事,我们找到了解决方案。

感谢@kfinity 的建议,它适用于插入和更新,但是当我们在 select 语句中将 clob 或 blob 设置为“参数”时,我们仍然收到此错误。

如果使用支持 JDBC4.0 的驱动程序,正确的解决方案是创建一个 DefaultLobHandler 并将 streamAsLob 或 createTemporaryLob 设置为 true。

    MapSqlParameterSource params = new MapSqlParameterSource();
    String myString = "";

    for (int i = 0; i < MAX_CLOB_BLOB_SIZE_IN_SELECT; i++) 
        myString = myString + "1";
    

    DefaultLobHandler lobHandler = new DefaultLobHandler();
    lobHandler.setStreamAsLob(true);

    params.addValue("param", new SqlLobValue(myString, lobHandler), Types.CLOB);

    // @formatter:off
    String sql =
        "SELECT 1 id  FROM DUAL WHERE :param IS NOT NULL ";
    // @formatter:on

    Integer id = namedParameterJdbcTemplate.queryForObject(sql, params, Integer.class);

我们更喜欢 streamAsLob,但老实说,我们不知道哪个更好。

【讨论】:

【参考方案2】:

This comment points out JDBC 查询中的 ORA-01460 与“ORA-01704: string literal too long”相同。 (字符串文字长度不能超过 4000 个字符。)也许是try this solution?

params.addValue("param", theLargeStr, Types.CLOB);

虽然!= 也不适用于 clob 比较,但您还需要将查询更改为

SELECT NULL id, NULL text FROM DUAL WHERE dbms_lob.compare('X',:param) != 0

【讨论】:

感谢回答,我之前尝试过 Types.CLOB,但结果还是一样。

以上是关于如何在不出现 ORA-01460:未实现或不合理的转换错误的情况下将大字符串设置为参数?的主要内容,如果未能解决你的问题,请参考以下文章

提交缺陷指引说明

如何在不相关的类型上实现动态多态(运行时调用调度)?

如何找到不相关的未使用属性?

DBA神级操作:我是如何将工作“合理分摊”给开发?

如何在不杀死未完成的芹菜任务的情况下重新启动heroku应用程序

未实现方法或操作