也许很多人会疑问为什么会报这个错,这个是因为Oracle在存储时,如果发现内容超过4000的话,会自动强转成long类型,但是你数据其实不是long类型的,所以会报这个错误。
不说别的了,我们在set PreparedStatement 的时候,必须使用stmt.setClob(new Clob),但是jdk里面的Clob是接口,并不是所有的数据库供应商都实现了接口,Oracle实现了这个接口。
先来看API:
CLOB clob = oracle.sql.CLOB.createTemporary((OracleConnection) conn, true,CLOB.DURATION_SESSION);
问题:createTemporary的构造函数需要三个参数,第一个是Oracle的connection,第二个表示当前的Clob是否需要缓存,第三个表示当前Clob的持续时间。具体怎么用?
connection必须是Oracle的,jdbc的不行,其他服务器插件封装过的也不行。此处展开谈获取Oracle的连接。
如果是单纯的驱动连接肯定很简单:
DriverManager.registerDriver(new OracleDriver()); connection = DriverManager.getConnection(getUrl(),getUserID(),getPassword());
但是一般我们数据连接都是通过服务器配置,从环境中lookup来的,这样不同的服务器插件会有不同的封装,比如Jboss会封装成org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionJDK,所以想要获取对底层的驱动连接引用,必须使用meta信息(以jboss为例)。
Connection myCon = originalCon.getMetaData().getConnection();
这样获取的connection就是环境加载是装载的驱动连接。
第二个参数表示是否用缓存,这个按照个人要求。
第三个参数表示Clob的持续时间,一般我们用DURATION_SESSION,表示当前session范围内有效(不是httpsession),一般用于客户端连接。还有其他的值DURATION_CALL,一般用于存储过程的调用。
这样完整的set prepare statement 方法就是这样的:
Connection conn = con.getMetaData().getConnection(); CLOB clob = oracle.sql.CLOB.createTemporary((OracleConnection) conn, true,CLOB.DURATION_SESSION); clob.setString(1, strFldValue); stmt.setClob(iFldIndex, clob); clob.freeTemporary();
free方法必须要在stmt提交之后调用,这里只是模拟代码。如果提前清楚会报错:
java.sql.SQLException: ORA-22922: nonexistent LOB value
记录以备查阅。
补充一点,在jdk1.6以后,jdk已经支持了oracle的Clob字段,也就是不用到底层取Oracle的连接了,而是直接使用jdk的标准接口访问:
clob =conn.createClob(); clob.setString(1, strFldValue); stmt.setClob(iFldIndex, clob);