使用JBoss和Tomcat管理Java CLOB

时间:2015-05-18 15:15:50

标签: java oracle jdbc

使用tomcat和mysql在webapps中使用clobs似乎很容易。 对于以下示例,我们假设我们将表'mytable'与clob'myclob'和一个键'id' 这是如何将字节数组放在clob中的示例:

Connection           conn = null;
PreparedStatement    stmt = null;
ByteArrayInputStream  bis = null;
try {
    if (mydatasource != null)
        conn = mydatasource.getConnection();
    StringBuffer sb=new StringBuffer("update mytable set myclob = ? where id = ?");
    bis=new ByteArrayInputStream(myArrayOfBytes);
    stmt.setBinaryStream( 1, bis);
    stmt.setString(2, "myId");
    stmt.executeUpdate();
} catch(Exception ex){
    ex.printStackTrace();
} finally {
    try{bis.close();} catch (Exception x) {;}
    try{stmt.close();} catch (Exception x) {;}
    try{conn.close();} catch (Exception x) {;}
}

当我尝试将我的webapp移动到jboss 5.0和Oracle db时,困难的是:

  

ORA-01461:只能插入LONG值才能插入LONG列

问题是:如何解决这个错误(也认为方法'createClob()'不起作用?

3 个答案:

答案 0 :(得分:0)

使用PreparedStatement#setClob而不是setBinaryStream。另外,请确保oracle表中的字段也是CLOB。

为了创建Clob使用Connection#createClob的实例。

答案 1 :(得分:0)

搜索和搜索后的解决方案是:
1-使用“select for update”查询获取clob 2-将数据写入clob
3-用表格执行

更新表格

这里是你的代码

Connection           conn = null;
PreparedStatement    stmt = null;
try {
    if (infodatasource != null)
    conn = infodatasource.getConnection();

    //Update to prevent null pointer exceptions during next query
    stmt = conn.prepareStatement("UPDATE mytable set myclob=empty_clob() WHERE id = ?");
    stmt.setString(1, idPoi);
    stmt.executeUpdate();

    stmt = conn.prepareStatement("SELECT myclob FROM mytable WHERE id = ? FOR UPDATE");
    stmt.setString(1, idPoi);
    ResultSet rs = stmt.executeQuery();
    Clob myclob=null;
    if(rs.next()) {
    myclob=rs.getClob("CARTASER");
    }

    OutputStream writer = myclob.setAsciiStream(0L);
    writer.write(myArrayOfBytes);
    writer.flush();
    writer.close();

    stmt = conn.prepareStatement("UPDATE mytable SET myclob = ? WHERE id = ?");
    stmt.setClob(1, myclob);
    stmt.setString(2, "myid");
    return stmt.execute(); //Note: explicit commit required if autocommit is off
} catch(Exception ex){
    ex.printStackTrace();
    //out.println("Cannot get connection: " + ex);
} finally {
    try{stmt.close();} catch (Exception x) {;}
    try{conn.close();} catch (Exception x) {;}
}
return false;

答案 2 :(得分:0)

这个问题与SO的许多问题重复。通常问题是BLOB / CLOB不是Java对象,不能位于Java堆上。它类似于文件,它存在于数据库中。而且morevover只能由数据库创建。

因此,有这些方法如何创建CLOB

  • Connection.createClob(),这将需要对数据库进行roundtrinp,并将在TEMPorary表空间中创建CLOB。当在下一个查询中使用此clob时,必须将数据从一个磁盘位置复制到另一个磁盘位置(在最坏的情况下)
  • INSERT insert into T(it, file) values(t_seq.nextval, empty_blob()) returning id, file into :id, :file;从Oracle的角度来看,这个结构是最好的选择。往返次数减少,无需在TEMP表空间中分配空间。但是,不幸的returnng子句是proprietatry SQL扩展,并且JDBC标准不支持
  • 两步法。首先使用file=empty_blob()函数INSERT / UPDATE行,然后在第2步中通过SELECT FOR UPDATE语句返回新创建的LOB的句柄。

至少在Oracle的情况下,您不能将LOB视为另一个绑定变量占位符。在这种情况下,你依赖于一些隐式数据类型转换,这是不安全的。