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;
Object value = data.get(key);
vals = 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;
}
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com