DB2中的数据移动

数据移动的作用:
如果要在不同的数据库管理系统之间转移数据,数据移动通常是最实用的一种方法,
因为任何一种数据库管理系统都支持常用的几种文件格式,通过这个通用的接口,就很容易实现不同系统间数据的转移。
这三个命令中,Export最简单,因为从表中向文件转移数据,通常不会出现错误,也不会有非法的数据。
在讲解命令之前,首先介绍一下文件的格式,用于DB2数据移动的文件格式有四种:

1. ASC——非定界ASCII文件,是一个ASCII字符流。数据流中的行由行定界符分隔,而行中的每一列则通过起始和结束位置来定义。
例如:
10   Head Office     160   Corporate   New York
15   New England  50     Eastern       Boston
20   Mid Atlantic     10     Eastern       Washington
38   South Atlantic 30     Eastern       Atlanta
42   Great Lakes    100   Midwest      Chicago
51   Plains              140   Midwest      Dallas
66   Pacific              270   Western     San Francisco
84   Mountain         290   Western     Denver

2. DEL——定界ASCII文件,也是一个ASCII字符流。数据流中的行由行定界符分隔,行中的列值由列定界符分隔。
文件类型修饰符可用于修改这些定界符的默认值。例如:
10,"Head Office",160,"Corporate","New York"
15,"New England",50,"Eastern","Boston"
20,"Mid Atlantic",10,"Eastern","Washington"
38,"South Atlantic",30,"Eastern","Atlanta"
42,"Great Lakes",100,"Midwest","Chicago"
51,"Plains",140,"Midwest","Dallas"
66,"Pacific",270,"Western","San Francisco"
84,"Mountain",290,"Western","Denver"

3. WSF——(work sheet format)为工作表格式,用于与Lotus系列的软件进行数据交换。

4. PC/IXF——是集成交换格式(Integration Exchange Format,IXF)数据交换体系结构的改编版本,
由一些列可变长度的记录构成,包括头记录、表记录、表中每列的列描述符记录以及表中每行的一条或多条数据记录。
PC/IXF 文件记录由包含了字符数据的字段组成。

第一部分:数据的导出(Export)
例一:把employee表中的所有数据导出到文件C:/ORG.TXT中。
Export to D:/DB2/employee1.txt of del select * from employee
其中,of del表示导出到的文件的类型,在本例中导出到一个非定界文本文件中;
后面的select * from employee是一个SQL语句,该语句查询出来的结果就是要导出的数据。

例二:改变del格式文件的格式控制符
Export to D:/DB2/employee2.txt of del modified by coldel$ chardel'' decplusblank select * from employee
在该例中,modified子句用于控制各种符号,coldel表示字段之间的间隔符,默认情况为逗号,现在改为$号;
chardel表示字符串字段用什么符号引用,默认情况下为一对双引号括起来,现在改为用一对单引号括起来;
decplusblank表示对于十进制数据类型,用空格代替最前面的加号,因为默认情况下会在十进制数据前面加上正负号的。

例三:以ASC格式将数据导出到文件
Export命令是不支持ASC格式文件的,所以如果想导出ASC这样规整的格式,需要程序员自己进行转换操作,
思路是将各种数据类型都转换成定长字符串,然后把各个要导出的字段合并成为一个字段。
export to D:/DB2/employee3.txt of del select EMPNO||FIRSTNME||MIDINIT||LASTNAME||WORKDEPT||PHONENO||CHAR(HIREDATE,ISO)||JOB||CHAR(EDLEVEL)||SEX||CHAR(BIRTHDATE,ISO)||CHAR(SALARY)||CHAR(BONUS)||CHAR(COMM) FROM EMPLOYEE
这样导出的结果与ASC格式的文件非常类似,只是每一行的前后多出了一对双引号,对此我们可以使用文本工具(如写字板、记事本等)
把双引号删除掉,也可以置之不理,在以后导入的时候直接控制格式(忽略双引号) 在文件中的格式为:
"15         2004-10-2123.12.23abc  hh  3.52E1                  "
"5          2004-01-2103.12.23bc   hhh 3.5672E1                "

例四:把导出信息保存在消息文件中。
Export to D:/DB2/employee4.txt of ixf messages D:/DB2/message4.txt select * from employee
这个例子把employee表中的数据导出到D:/DB2/employee4.txt文件中,所有的导出信息都保存在D:/DB2/message4.txt
文件中(无论是成功、警告还是失败信息),这样,管理员可以通过观察信息文件找到问题所在。

例五:给导出数据列重命名。
export to D:/DB2/employee5.txt of ixf method n(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) select * from employee
在默认情况下,导出的每一列数据以表中对应的字段名自动命名,我们可以通过method n子句给每一列重新命名,
需要注意的是,这个子句只在ixf和wsf格式文件中有效,在文本文件中不能使用。

第二部分:数据的导入
 
例六:把d盘根目录下的D:/DB2/employee1.txt文件中的数据导入到employee1表中
create table employee1 like employee
import from D:/DB2/employee1.txt of del insert into employee1

导入命令和导出命令的格式基本上处于对应的关系,import对应export,from对应to,文件名和文件格式代表的含义相同,
但是导入命令支持ASC格式的文件,而导出命令不支持。另外,在导出命令的最后是一个SQL语句,
用于选择要导出的数据,而导入命令最后不是SQL语句,而是插入数据的方式以及目标表名称。

例七:把d盘根目录下的D:/DB2/employee2.txt文件中的数据导入到employee2表中
create table employee2 like employee
import from D:/DB2/employee2.txt of del modified by coldel$ chardel'' decplusblank insert into employee2

例八:从ASC格式文件中导入数据(实验不成功)
create table employee3 like employee
import from  D:/DB2/employee3.txt of asc method l(2 7,8 19,20 20,21 35,36 38,39 42,43 46,47 54,55 56,57 57,58 61,62 70,71 79,80 88) insert into employee3
其中 method l 子句用于指定文本文件中每一个字段的起始位置和终止位置,每个起始位置和终止位置间用空格分开,
字段之间用逗号分开。
除了l方法之外,还有n方法和p方法,下面会叙述。

例九:从ixf格式文件中导入数据
import from  D:/DB2/employee4.txt of ixf REPLACE_CREATE into employee4

例十:利用n方法导入数据,并且创建新表。
首先导出一个用例文件:
import from D:/DB2/employee5.txt of ixf method n(a1,a2,a3,a4,a5) REPLACE_CREATE into employee5
这样D:/DB2/employee5.txt文件中有五列数据,对应的列名分别为a1,a2,a3,a4,a5 

插入方式有:
INSERT 方式——在表中现有数据的基础之上追加新的数据。
INSERT_UPDATE 方式——这种方式只能用于有主键的表,如果插入的数据与原有数据主键不冲突,则直接插入,如果主键冲突,则用新的数据代替原有数据。
REPLACE 方式——先把表中现有的数据都删除,然后向空表中插入数据。
REPLACE_CREATE 方式——表示如果表存在,则先把表中的数据都删除,然后向空表中插入数据;如果表不存在,则先根据文件中的字段创建表,
然后再向表中插入数据。这种方式只能把IXF格式的文件中的数据插入到表中。

例十一:利用p方法导入数据
import from D:/DB2/employee5.txt of ixf method p(1,4,5) REPLACE_CREATE into employee6
该例子执行的效果和例九类似,只是把n方法换成了p方法,p方法后面的列表中指明列的序号即可,不需要指明列名。
另外,此例中使用了replace方式插入数据,这会把表中现有的数据都删除,然后向空表中插入数据。

例十二:关于空值的导入
对于ixf格式的文件,导入空值非常方便,因为里面已经记录了空值的信息。但是,对于ASC格式文件就有一定的难度了,
因为DB2会直接插入空格,而不是空值。为此,DB2提供了一个子句进行控制:NULL INDICATORS
import from  c:/org2.txt of asc MODIFIED BY nullindchar=# method l(1 5,6 19,20 25,26 37,38 50) NULL INDICATORS(0,0,0,0,38 ) replace into org
在这个例子中,NULL INDICATORS子句后面是一个列表,表示前面四个字段都不会存在空值,而第五个字段从38列开始,可能存在空值,
而 MODIFIED BY nullindchar=# 子句表示在文件中第五个字段如果遇到 # 号,则表示为空值。

:注问题 在用IMPORT命令向数据库插入大量数据时,如何避免日志空间满错误
解答 在执行IMPORT命令时, 如果使用循环日志, 有时会出现日志满错误,这时可用COMMITCOUNT参数来解决.
因为日志空间满往往是因为所有的日志均处于活动状态导致的.
而COMMIT执行后, 会释放所占据的资源, 其中包括日志 .
这样, 被当前事务使用的日志在COMMIT命令执行后, 即变成非活动状态了.

第三部分:装入(Load)

装入命令格式与导入类似,命令关键字是Load,但是后面的参数比导入命令多的多,详细用法可以自行参考DB2文档。
装入与导入类似,都是将输入文件中的数据移入到目标表中,二者的不同点将在实例中逐步解释。
在装入之前,目标表必须已经存在。
装入的性能比导入高,原因在后面结合实例详细解释。
装入操作不记录到日志中,所以不能使用日志文件进行前滚操作。
装入分为4个阶段:
1. 装入阶段
在这个阶段发生两件事:数据存储在表中,收集索引键并排序。在装入时,DBA可以指定多长时间生成一致点。
它是装入工具的检查点。如果装入在执行期间被打断,它可以从最后一个一致点处开始继续重新执行。
2. 构建阶段
在构建阶段,基于在装入阶段收集的索引键信息创建索引。如果在构建阶段发生错误,装入工具就重启,它将从构建阶段开始处重新开始构建。
3. 在删除阶段,所有违反唯一或主键约束的行都被删除并拷贝到一个异常表(如果在语句中指定相应选项)中。
当输入行被拒绝,消息文件中就生成消息。
4. 索引拷贝阶段
如果在装入操作期间为索引创建指定了系统临时表空间,并且选择了 READ ACCESS 选项,该索引数据将从系统临时表空间拷贝到原来的表空间。
装入过程的所有四个阶段都是操作的一部分,只有在所有的四个阶段都完成之后,
该装入操作才算完成。在每个阶段都将生成消息,一旦其中的某个阶段发生错误,这些消息可以帮助DBA分析并解决问题。
导入操作每次插入一行数据时都要检查是否满足约束条件,并且记入日志文件中。

例十二:
create table employee7 like employee
load from D:/DB2/employee2.txt of del modified by coldel$ chardel'' decplusblank insert into employee7

例十三:
load from D:/DB2/employee4.txt of ixf insert into employee7

例十三:
load from D:/DB2/employee5.txt of ixf method n(a1,a2,a3,a4,a5) insert into employee5

例十四:关于异常表
由用户定义的异常表可以用于存储不遵循唯一约束和主码约束的行。如果装入的时候没有指定异常表,
则违反唯一约束的行将被丢弃并且将不再有机会恢复或修改。
用SAMPLE数据库中的STAFF表做实验
1. 创建一个结构与STAFF表相同的表STAFF1
CREATE TABLE STAFF1 LIKE STAFF

2. 把STAFF表中的一部分数据插入到STAFF1中
INSERT INTO STAFF1 SELECT * FROM STAFF WHERE ID<=160

3. 再创建一个结构与STAFF1相同的表STAFFEXP,作为异常表
CREATE TABLE STAFFEXP LIKE STAFF1

4. 给该异常表添加一列,因为异常表和普通表相比,前面的结构都相同,就是最后多出一列或两列(列名任意),第一列是时间戳类型,记录异常记录插入的时间,第二列是大文本类型(至少为32K大小),保存导致该条记录被拒绝的特定约束信息。本例中只添加一个时间戳列。
ALTER TABLE STAFFEXP ADD COLUMN TIME TIMESTAMP

5. 为STAFF1表创建一个唯一索引
CREATE UNIQUE INDEX IDXSTAFF ON STAFF1(ID)

6. 先运行导出命令做出一个文本文件
EXPORT TO D:/STAFF.TXT OF DEL SELECT * FROM STAFF

7. 然后运行装入命令把数据再装入到STAFF1表中
LOAD FROM D:/STAFF.TXT OF DEL INSERT INTO STAFF1 FOR EXCEPTION STAFFEXP

由于表STAFF1中有唯一索引,所以会有一部分数据因为违反这个约束条件而不能插入到STAFF1表中,这些记录就会插入到异常表STAFFEXP中。

注意一点,异常表必须自己先定义好,装入命令不能够自动生成异常表,如果找不到指定的异常表,就会报错。

1. COPY YES/NO和Nonrecoverable
(1).Nonrecoverable(不可恢复的):指定装入操作不可恢复,并且不能由后续的前滚操作恢复。
前滚操作忽略事务并且标记正在装入数据的表为"无效"。
(2).Copy No(默认选项):在这种情况下,如果表所在数据库的归档日志处于启用状态,则装入完成后,
表所在的表空间将处于备份挂起状态,直到数据库或表空间备份完毕,该表空间才成为可写表空间。
原因是装入操作造成的变化没有被记录,所以要恢复装入操作完成后发生的故障,备份数据库或表空间是必要的。
(3)Copy Yes:在这种情况下,如果数据库的归档日志启用,装入操作的改变将被保存到磁带、目录或TSM服务器,
并且表空间将不再处于备份挂起状态。
(4)导入时间可以更改格式
dateformat="YYYYMMDD" timeformat="HHMMSS" timestampformat="YYYYMMDDHHMMSS"
(5)监控LOAD
load query table 表名
(6)提高IMPORT的性能
在利用 DB2 提供的 IMPORT 命令进行数据导入时,所有的约束都要被验证,所有装载的行都会记入日志,
且触发器也会被激活,因此在装载大量数据时,IMPORT 实用程序的性能会明显低于 DB2 的 LOAD 实用程序,
为提高 IMPORT 的性能,这里为用户提供两种方法。
针对 DB2 的 IMPORT 实用程序,使用 COMPOUND 选项或在 BIND db2uimpm.bnd 文件时加入缓冲区插入选项都可以使
IMPORT 的性能有较大的提高,且对多数情况下导入数据量都很大的分区式数据库,
这些方法对于 IMPORT 性能的提高尤为重要。
下面就介绍一下这两种方法的具体实现步骤:
1.使用 INSERT BUF 选项绑定 IMPORT 实用程序以启用缓冲区插入,即对 db2uimpm 程序包使用 INSERT BUF 选项重新绑定到数据库。
例如:
db2 connect to sampled
db2 =>bind /opt/IBM/db2/V8.1/bnd/db2uimpm.bnd insert buf
db2 =>import from ./2006-06-16.txt of del modified by coldel$ chardel'' timestampformat="YYYY-MM-DD H:MM:SS.UUUUUU" compound=100 insert into ldk_temp
2.发出导入数据的 IMPORT 命令时使用 COMPOUND 选项,如在 MODIFIED BY 语句后使用 COMPOUND=n,
以便将插入语句中的 n 行记录作为一组一起导入。对比逐行记录插入的方式,这种方式减少了网络的通信量。
COMPOUND 的范围为 1 - 100。
例如:
db2 =>
import from ./2006-06-16.txt of del modified by coldel$ chardel'' timestampformat="YYYY-MM-DD H:MM:SS.UUUUUU" compound=100 insert into ldk_temp

第四部分:DB2MOVE
db2move <database> <action> <option>
sn:模式名
io:import选项,必须与import一起使用,其后可以指定INSERT,INSERT_UPDATE,REPLACE,REPLACE_CREATE默认为REPLACE_CREATE.
lo:load选项,必须与load一起使用,其后可以指定INSERT,REPLACE默认为INSERT.
例:db2move sample export -sn administrator
生成如下文件
export.out   --export操作结果
db2move.lst  --创建了一个包含文件名和表名的文件
tabNNN.ixf   --ixf文件中包含了数据
tabNNN.msg   --此消息文件与每个导出表的操作有关
例:
db2move sample1 load
输入文件:
db2move.lst  --创建了一个包含文件名和表名的文件
tabNNN.ixf   --ixf文件中包含了数据
输出文件:
load.out     --export操作结果
tabNNN.msg   --此消息文件与每个导出表的操作有关 

上一篇:PLSQL连Oracle数据库Could not load \"……\\bin\\oci.dll\"


下一篇:阿里云基于OSS的云上统一数据保护方案2.0技术解析