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特有的方法

ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (queryResult.next()) {
    tfzn018KtfjxxPO.setTec_attachid(queryResult.getLong("TEC_ATTACHID"));
    tfzn018KtfjxxPO.setTec_attachpostfix(queryResult.getString("TEC_ATTACHPOSTFIX"));
    java.sql.Blob blob = queryResult.getBlob("TEC_ATTACHCONTENT");
    InputStream is = blob.getBinaryStream();
    int bytesRead = 0;
    byte[] buffer = new byte[8192];
    // 从输入流读到字节数组
    while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
        // 从字节数组到输出流
        baos.write(buffer, 0, bytesRead);
    }
    byte[] bufferFile = baos.toByteArray();
    tfzn018KtfjxxPO.setTec_attachcontent(bufferFile);
    connection.commit();
}


三、定义
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进来的数据行使用的


附:
select * from dba_tablespaces; //dba权限用户查看表空间参数

你可能感兴趣的:(java,oracle,blob)