迁移Oracle数据备忘(表中有blob字段)
最近需要迁移一个数据库,06年开始用的,oracle 9i,迁移用的是oracle10g的,由于用了10多年了,数据库存在一些表空间文件损坏,数据有一些坏点,导致用一般的 imp 和 exp 方式无法正常迁移。 里面有一个有 blob 字段的表,2w多条记录,但是这个表的内容达到了40g,由于里面的内容存在损坏,无法正常通过dmp 导入导出,甚至plsql特有 的导入导出也不行。 解决方案: 一. 收集老数据库的信息(服务命名,表空间,用户的创建和角色权限)
二. 建立新数据库,用获取的服务命名创建数据库实例,创建符合容量的表空间,通过老数据库的用户sql 来创建用户,确保这些用户的角色和权限正常,并且使用的表空间也正确。
三. 导出老的数据库用户数据 导出每个用户的数据dmp,把带有blob 字段的表排除在外。
四. 把用户的数据导入到新的数据库 处理表数据,还要确认所有的对象有正确导入,如触发器,视图,dblinks和序列等。
五. 通过java 代码迁移带blob 的表 我尝试了不少方式,发现用java 代码来处理的话,其实更灵活和效率更高,效率比dmp 的方式高多了。 用java 代码, 读取blob 的内容简单,getBlob就可以拿到,但是写入blob 字段的话,不能直接插入,并且需要使用io 流才行,直接的update 和setBlob 的方式是不行的。 1. 写入的数据库连接不能用自动事务,因为blob 字段的写入是通过io和更新的方式进行 conn.setAutoCommint(false); ...............写入数据后 conn.commit(); ...............关闭连接前 conn.setAutoCommint(true); ...............连接不用了关闭 conn.close(); 2. 读取blob 数据,这个不难,简单直接 java.sql.Blob blob_obj = null; //建立一个blob 对象 。。。。查询数据库后得到ResultSet 对象rs blob_obj = rs.getBlob(*); //*具体参数看实际情况 3. 写入blob 数据,这个要分多个步骤,不能直接写入 a. 先插入记录到表中,并且blob 要先写入空的内容,用empty_blob() 函数。 如,insert into tableblob values(?,?,empty_blob()), 最好表中有主键。 b. 再通过主键获取blob 字段的对象 java.sql.Blob blob_obj_t = null; //建立一个blob 对象指向要写入的blob 字段 select blob_obj from tableblob where id=? ,通过主键获取blob字段对象 。。。。查询数据库后得到ResultSet 对象rs2 blob_obj_t = rs2.getBlob(1); c. 使用IO 流写入blob 字段内容 InputStream in = blob_obj.getBinaryStream(); OutputStream out = blob_obj_t.setBinaryStream(1L); byte[] buffer = new byte[1024]; int length = -1; while((length = in.read(buffer)) != -1){ out.write(buffer,length); } //数据写入完成,关闭IO,这个是必须的 in.close(); out.close(); //提交数据 conn.commit(); d. 注意每个prepareStatement 对象在操作后记得及时关闭,因为每个ps 对象都会使用一个游标,oracle 的游标是有数量限制的,超过数量就会返回异常,ps.close() 可以让游标得到回收,避免这个异常。 4. 检查这些表的触发器,索引主键,授权等是否正确,是否有关联的视图编译异常等。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |