【问题标题】:Create CLOB from long string using JDBC使用 JDBC 从长字符串创建 CLOB
【发布时间】:2011-02-21 15:01:45
【问题描述】:

我有以下疑问:

select id from table1 where some_func(?) = 1;

其中some_func 是一个函数,它的参数可以是VARCHAR2 或CLOB,而? 是一些字符串,它可能非常长。

我正在尝试使用以下代码来绑定变量:

stmt.setObject(i+1, obj);

但在string.length() > 4000 的情况下,我会收到以下错误:

java.sql.SQLException: ORA-01460: unimplemented or unreasonable conversion requested

原因很明显:VARCHAR2 的大小限制为 4000 个字符。

然后我尝试使用以下代码:

if(obj instanceof String && ((String) obj).length() >= 4000) {
  String s = (String) obj;
  StringReader stringReader = new StringReader(s);
  stmt.setClob(i+1, stringReader, s.length());
} else {
  stmt.setObject(i+1, obj);
}

这给出了一个不同的错误:

ORA-22922: nonexistent LOB value

我尝试的最后一个想法是使用oracle.sql.CLOB.createTemporary() 方法创建一个CLOB,但由于以下异常而失败:

java.lang.ClassCastException:
  org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper 
  cannot be cast to oracle.jdbc.OracleConnection

我做错了什么?有没有其他的可能性来做到这一点?

【问题讨论】:

  • 你试过 PreparedStatement 中的 setCharacterStream 方法吗?
  • 是的,请看我之前的回答(a_horse_with_no_name 快一点)

标签: java oracle jdbc clob


【解决方案1】:

可以通过简单的方式创建 CLOB:

if(obj instanceof String && ((String) obj).length() >= 4000) {
    Clob clob = connection.createClob();
    clob.setString(1, (String) obj);
    stmt.setClob(i+1, clob);
}

那么当然应该释放这些 clob。

【讨论】:

  • 何时使用 setString 而不是 setCharacterStream?
【解决方案2】:

根据我的经验,setCharacterStream() 比 setClob() 可靠得多

字符串 s = (字符串) obj; StringReader stringReader = new StringReader(s); stmt.setCharacterStream(i + 1, stringReader, s.length());

它无需创建 CLOB 对象即可工作

【讨论】:

  • 不幸的是,我得到了与字符串相同的错误:java.sql.SQLException: ORA-01460: unimplemented or unreasonable conversion requested
  • 底层列是什么数据类型?将它与 CLOB 列一起使用没有问题。
  • 这只是 some_func 函数的一个参数,它是 3rd-party 软件,所以我只知道它接受 CLOB 或 varchar2 作为参数。
  • 您可能会获得函数的 VARCHAR2 版本。使用命名参数来确保你得到你期望的参数。
  • 我找不到在这样的函数中使用命名参数的方法,所以我尝试创建一个 CLOB 并成功。如果您愿意,请参阅我的回答。
猜你喜欢
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多