如何在不出现 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:未实现或不合理的转换错误的情况下将大字符串设置为参数?的主要内容,如果未能解决你的问题,请参考以下文章