免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2960 | 回复: 0
打印 上一主题 下一主题

Oracle BLOB 字段导入导出问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-10 12:29 |只看该作者 |倒序浏览
Oracle BLOB 字段导入导出问题




一、案例
假如有t1和t2在表空间tbs1上,其中t1有blob字段,现在在另外的一台机子上建了实例,表空间名为tbs2,使用imp倒入的时候,t2正常倒入,t1不能倒入,出现错误
"IMP-00017: 由于 ORACLE 错误 959, 以下语句失败:
"CREATE TABLE "t1"...............
IMP-00003: 遇到 ORACLE 错误 959
ORA-00959: tablespace 'tbs1' does not exist"

我是这样解决的
imp tables = t1 indexfile = temp.sql

- 编辑 temp.sql 只保留所需的建表命令并指定表空间为tbs2

- 以表的所有者执行temp.sql

- imp tables = t1 ignore = Y


二、java示例
blob是单独分块的,java中获取oracle blob字段值,为了防止乱码应该使用getBlob()这个oracle特有的方法


Java代码
  1. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  2. if (queryResult.next()) {
  3.     tfzn018KtfjxxPO.setTec_attachid(queryResult.getLong("TEC_ATTACHID"));
  4.     tfzn018KtfjxxPO.setTec_attachpostfix(queryResult.getString("TEC_ATTACHPOSTFIX"));
  5.     java.sql.Blob blob = queryResult.getBlob("TEC_ATTACHCONTENT");
  6.     InputStream is = blob.getBinaryStream();
  7.     int bytesRead = 0;
  8.     byte[] buffer = new byte[8192];
  9.     // 从输入流读到字节数组
  10.     while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
  11.         // 从字节数组到输出流
  12.         baos.write(buffer, 0, bytesRead);
  13.     }
  14.     byte[] bufferFile = baos.toByteArray();
  15.     tfzn018KtfjxxPO.setTec_attachcontent(bufferFile);
  16.     connection.commit();
  17. }
复制代码
三、定义
BLOB、CLOB、和 NCLOB:它们在数据库中要么存储在表中,要么存储在单独的段或表空间中。
       BLOB 能够存储大容量的二进制数据,典型例子有图形图像和照片。
       CLOB 能够存储大容量的字符数据,而且对于存储非结构化的 XML 文档很有用。
       NCLOB:由对应于为 Oracle 数据库定义的本地字符集的字符数据组成。
BFILE:它们作为操作系统文件存储。
       BFILE 是一种 LOB 类型,它的值由二进制(“原始”)数据组成,而且存储在数据库表空间之外的服务器端操作系统文件中。

用oracle 9i 创建表空间,如果有这句:SEGMENT SPACE MANAGEMENT AUTO,自动段管理表空间,这样的话是不能创建clob和 blob字段的。看解释说是oracle9i的特性,把SEGMENT SPACE MANAGEMENT AUTO 去掉就可以创建clob、blob字段了。


四、sql操作
Oracle表移动表空间:
alter table tb_name move tablespace tbs_name;
使用上面语句对表做空间迁移时,只能移动非lob字段以外的数据,如果要同时移动lob字段数据,必需改用下面的语句才行:
alter table tb_name move tablespace tbs_name lob (col_lob1,col_lob2) store as(tablesapce tbs_name);

建立表空间,赋予表空间权限。
create tablespace tablespace_lob datafile 'd:/xxx/lob.dbf' size 100M autoextend on;//所有表的lob字段都用一个专用的lob表空间,导出导入数据时方便。
alter user bbb quota unlimited on tablespace_lob;//给bbb添加表空间权限。

使用exp和imp导出导入数据时,若含有blob字段,则imp过程中可能由于blob字段表空间不存在而报错。这时可以先检查源库中blob字段所在表空间名称,然后在目标库中建立同名表空间。数据导入完成后,可以使用上面语句移动blob数据到指定的表空间。


五、Q&A
1.
Q.含有blob字段的表删除记录后所在表空间不回收问题

9.2.0.8
有一张表,存储大量的图片记录,blob字段在建表时都指定norow参数,存储到单独的表空间上.

目前保存图片的表空间已满,删除若干记录,大概20%的记录,但仍然无法插入新记录,表空间的可用空间没有增加.

就用delete from table where id=xxxx语句进行删除,删除后新的图片仍然无法写入.

A.使用delete是不会回收高水位的。
alter table TABLE_NAME move;  这样空间就回收了。最好在没有业务的时间做
另外对于lob字段,alter table move也是不能降低hwm的
需要move 相应的lob段。

move完表后,这个表上测index会失效。
所以要在move后,执行alter index index_name rebuild;

Q.delete操作应该是在表空间上回收数据块的啊.将部分的数据块置为可用,这里还谈不到高水位的问题.
delete不能改变高水位这个我明白,不明白的是delete操作难道没有改变表空间的数据块的可用标记吗?我的表空间是LMT方式.

A.delete后,在oracle上看这个表的使用空间是不会改变的。但delete出来的那些空间是可以被后来的insert进来的数据行使用的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP