Oracle 10g+WebLogic8x下存取blob对象

原创 2006年06月15日 21:21:00

oracle10g的jdbc存在bug,在weblogic环境下处理的blob对象会出现错误:
encountered SQLException [ORA-01461: can bind a LONG value only for insert into a LONG column ]; nested exception is: java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column
针对这个问题,目前只能更改blob对象的处理方法以避免。
解决的思路是先向数据库里面插入一个空的blob对象,然后利用select ....for update语句单独向刚刚插入的行中放置blob对象,这两个操作要放在同一个事务中。同样,对于blob对象的更新问题,也需要,先把要替换的记录行的blob对象置空(EMPTY_BLOB()),然后再向里面插入blob对象。
代码如下:

/**
  * Oracle数据库附件专用方法
  */
 public static int insertDB(DataSource ds , String tableName, Map data) {
  if(ds==null)
  {
   throw new RuntimeException("DataSource is null");
  }
  
  byte[] temp = null;
  Object cols[] = data.keySet().toArray();
  Object vals[] = new Object[cols.length];
  
  /* 组织sql */
  StringBuffer colsSql = new StringBuffer();

  StringBuffer valsSql = new StringBuffer();
  for(int i=0; i<cols.length ; i++)
  {
   String key = (String) cols[i];
   Object value = data.get(key);
   vals[i] = value;
   if(key!=null && key.equals(WorkForm.COLUMN_NAME_SUBCONTENT))
   {
    temp =  UtilObject.getBytes(value);
   }
   if (i > 0) {
    colsSql.append(" ,");
    valsSql.append(" ,");
   }
   
   colsSql.append(key);
   
   if(key!=null)
   {
    if(key.equals(WorkForm.COLUMN_NAME_SUBCONTENT))
     valsSql.append("EMPTY_BLOB()");
    else
    { 
     if(key.equals(WorkForm.COLUMN_NAME_SUBTIME))
     {
      valsSql.append("SYSDATE");
      //valsSql.append("current_timestamp()");
     }
     else
     {
      valsSql.append("'")
          .append(value)
          .append("'");
     }
    }
   }
  }
  
  if(temp==null)
  {
   throw new RuntimeException("字节数组为空!");
  }
  /* 插入数据SQL */
  StringBuffer InsertSQL = new StringBuffer();
  InsertSQL.append("INSERT INTO ")
    .append(tableName)
    .append(" (")
    .append(colsSql.toString())
    .append(") VALUES (")
    .append(valsSql.toString())
    .append(")");
  
  /* 取出数据SQL */
  StringBuffer QuerySQL = new StringBuffer();
  QuerySQL.append("SELECT ")
    .append(WorkForm.COLUMN_NAME_SUBCONTENT)
    .append(" FROM ")
    .append(tableName)
    .append(" ")
    .append(" WHERE ID='")
    .append((String) data.get(WorkForm.COLUMN_NAME_SUBID))
    .append("' AND DATAID='")
    .append((String) data.get(WorkForm.COLUMN_NAME_DATAID))
    .append("' FOR UPDATE");
  
  /* 然后在从表中取出来,进行更新 */
  Connection conn = null;
  Statement stmt = null;
  boolean defaultCommit;
  ResultSet result = null;
  int returnValue = 0;
  
  try {
   conn = ds.getConnection();
   
   defaultCommit = conn.getAutoCommit();
   /* 设置为不能自动提交 */
   conn.setAutoCommit(false);
   stmt = conn.createStatement();
   /* 插入空的附件 */
   returnValue = stmt.executeUpdate(InsertSQL.toString());
   
   /* 查询此BLOB对象并锁定 */
   result = stmt.executeQuery(QuerySQL.toString());
   if (result == null) {
    throw new RuntimeException("result is null");
   }
   ResultSet rs = stmt.executeQuery(QuerySQL.toString());
   if (rs.next()) {
    weblogic.jdbc.wrapper.Blob blob = (weblogic.jdbc.wrapper.Blob) rs.getBlob(WorkForm.COLUMN_NAME_SUBCONTENT);
    oracle.sql.BLOB oblob = (oracle.sql.BLOB)blob.getVendorObj();
    OutputStream output = oblob.getBinaryOutputStream();
    ByteArrayInputStream inputStream = new ByteArrayInputStream(temp);
    int len = 0;
    while ((len = inputStream.read(temp)) != -1) {
     output.write(temp, 0, len);
    }
    inputStream.close();
    output.flush();
    output.close();
   }
   
   /* 正式提交 */
   conn.commit();
   stmt.close();
   conn.setAutoCommit(defaultCommit);
   
  } catch (IOException ioex) {
   throw new RuntimeException("IOException", ioex);
  }catch (SQLException ex) {
   ex.printStackTrace();
   try {
    conn.rollback();
   } catch (SQLException e) {
    throw new RuntimeException("回滚失败", e);
   }
  } finally {
   if (conn != null) {
    try {
     conn.close();
    } catch (SQLException e) {
     throw new RuntimeException("关闭连接失败", e);
    }
   }
  }
  return returnValue;
 }

相关文章推荐

W8 64位操作系统安装Oracle 10g

Oracle 默认不支持win8操作系统,在安装之前先要修改Oracle的配置文件,否则会提示程序异常终止,无法安装。 我用的是Oracle 10.2 ,自行下载安装包,我的安装包目录如下:...

【LINUX】在虚拟机上安装红帽Linux.5.5.for.x86.服务器版系统(按针对安装oracle 10g作的配置)

在虚拟机上安装红帽Linux.5.5.for.x86.服务器版系统(按针对安装oracle 10g作的配置) 分类: Oracle 2011-07-17 21:21 290人阅读 评...
  • kenkywu
  • kenkywu
  • 2011年12月08日 23:23
  • 1336

在虚拟机上安装红帽Linux.5.5.for.x86.服务器版系统(按针对安装oracle 10g作的配置)

软件版本:虚拟机版本:vmwareworkstation 7.11 build-282343红帽5版本:[红帽Linux.5.5.for.x86.服务器版].rhel-server-5.5-i386-...
  • pxpdqz
  • pxpdqz
  • 2011年07月17日 21:21
  • 3257

Oracle 10g 中 X$KCVFH 说明

一. X$表说明 之前整理了一篇有关动态性能视图的blog:Oracle 动态性能视图http://blog.csdn.net/tianlesoftware/article/details/58631...

Orcale(一)----WIN7 X64下安装ORACLE 10g(检查操作系统版本: 6.1a等问题)

事出有因 解决方案 修改配置文件oraparamini 修改refhostxml文件 注意事项 事出有因最近在学习DRP,要用到Orcale数据库,由于本电脑注意是window10的系统,之前装过Or...

Mac OS X (Intel) 上安装 Oracle 10g

官方的资源已经不能用了 我是从网上找的 网友的网盘分享资源. (就不做广告了)     Oracle Database 10g Rel 2 for Mac OS X on Intel x86...

RED HAT ES 5.4 X64安装ORACLE 10G R2 64bit

REDHAT 5.4 64bit 安装oracle 10G 64BIT 1、检查包 rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE} (%...

win7(x64)安装oracle 10g 32位的方法

操作系统:window 7 旗舰版64位 oralce 版本:oracle10.2.0.1 for windows 直接给出步骤: 1,要解除oracle安装window的版本检测: 以我的盘...

Ubuntu 11.10 x64下安装oracle 10G

(一)          系统需求 Ubuntu 11.10 x64  Gcc 4.6.1 Oracle 10g for linux_x86_64 Swap分区:>1GB 如果不够,执行以...

CentOS 6.3(x86_32)下安装Oracle 10g R2

一、硬件要求 1、内存 & swap Minimum: 1 GB of RAM Recommended: 2 GB of RAM or more 检查内存情况 # g...
  • yuanya
  • yuanya
  • 2014年06月05日 16:34
  • 350
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Oracle 10g+WebLogic8x下存取blob对象
举报原因:
原因补充:

(最多只允许输入30个字)