最近一次导数据时碰到的问题,记录下来。服务器Oracle版本10.1.0.4,本机Oracle版本10.2.0.1,希望把导出几张表到本机,表中含有BLOB字段。直接使用EXP命令,报错:
EXP-00056: ORACLE error 6550 encountered
ORA-06550: line 1, column 41:
PLS-00302: component 'SET_NO_OUTLINES' must be declared
ORA-06550: line 1, column 15:
PL/SQL: Statement ignored
EXP-00000: Export terminated unsuccessfully
以为是没有权限,于是换了个具有DBA角色的用户,仍然报上面的错误。google到下面这段内容:
Applies to:
Oracle Server - Enterprise Edition - Version: 10.2.0.1.0
This problem can occur on any platform.
Symptoms
While trying to export 9.2.0.6 database with 10.2.0.1.0 Exp utility
receive following errors:-
Export: Release 10.2.0.1.0 - Production on Tue Oct 25 17:11:46 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
EXP-00056: ORACLE error 6550 encountered
ORA-06550: line 1, column 41:
PLS-00302: component 'SET_NO_OUTLINES' must be declared
ORA-06550: line 1, column 15:
PL/SQL: Statement ignored
EXP-00000: Export terminated unsuccessfully
Cause
Use of Higher Version Export utility (10.2.0.1) on Lower version database(9.2.0.6).
This problem occurs when using 10.2 Exp utility for 10.1,9.2,8.1.7 databases.
Solution
As per compatibility Matrix,You need to use the export utility of the lower version of source and target database.
好像是说10.2的EXP命令无法导出9.2的表,版本不兼用。网上老鸟们总结的原则有两条:
1. Export the data with the Export utility of the lowest database version involved.
2. Import the data with the Import utility of the target database.
试着换了更高版本的客户端11.1.0.6,还是报一样的错误。
再尝试用PL/SQL Developer的导出功能,成功导出成pde格式,但是导入时发生错误,原因并非BLOB数据,而是表中的字段名使用了Oracle的关键字,PL/SQL Developer似乎无法处理。即便事先创建好表,导入数据时不选择创建表,也不行。看来这条路走不通。
怎么办?突然想到insert into <Table> select * from <Table>和create table <Table> as select * from <Table>这两条SQL语句,应该能完成数据的复制。那么本机如何访问到服务器上的表,答曰数据链路(database link)。在本机建立访问服务器的数据链路,就能向访问本机表一样访问服务器表。在创建database link时还碰到一个小麻烦,使用已配置好的网络服务名:
create database link LOCALTEST
connect to TEST
using 'test';
死活不能连接上,但改成下面的方式:
create database link LOCALTEST
connect to TEST
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test)
)
)';
连接成功,原因不详。
接下来就很简单了,有表的用insert into <Table> select * from <User>.<Table>@<DbLink>,没表的用create table <Table> as select * from <User>.<Table>@<DbLink>。需要注意的是第二条语句创建的表将丢失主键、约束、索引,所以最好能先创建表,再用第一条语句导数据。还有一个疑问是此法能导多大量的数据,会不会造成Oracle游标数量过多出错。经测试至少每个表11W多条记录完全没有问题,当然得耐心等待一会。