LOAD 实用程序是用于为表填充数据的另一种方法。该实用程序将格式化的页面直接写入到数据库中。这种机制允许比 IMPORT 实用程序更有效地移动数据。然而,有些操作,例如参照约束或表约束检查和触发器的调用,是不能用 IMPORT 实用程序执行的。
下面是 LOAD 命令的核心。其他受支持的选项和修饰符将在本节中后面几屏中介绍。为了成功地执行这个命令,必须拥有 SYSADM/DBADM 或 LOAD 权限,或者拥有装载操作涉及的表上的 INSERT 和/或 DELETE 特权。为了将数据装载到包含受保护列的表中,必须拥有允许对表中所有受保护列进行写访问的 LBAC 凭证。为了将数据装载到受保护的行中,必须被授予允许写访问的安全标签,作为保护表的安全策略的一部分。
LOAD FROM input_source OF input_type
MESSAGES message_file
[ INSERT REPLACE TERMINATE RESTART ]
INTO target_tablename
用于 LOAD 的源输入的格式可以是 DEL、ASC、PC/IXF 或 CURSOR。游标是一个 SELECT 语句返回的结果集。下面是使用 CURSOR 作为装载输入的一个例子:
DECLARE mycursor CURSOR FOR SELECT col1, col2, col3 FROM tab1;
LOAD FROM mycursor OF CURSOR INSERT INTO newtab;
在开始装载实用程序之前,装载目标必须已经存在。装载目标可以是一个表、一个类型化表或一个表的别名。将数据装载到包含 XML 列的表、系统表和临时表是不受支持的。
使用 MESSAGES 选项可以捕获装载期间遇到的错误、警告和包含有用信息的消息。
LOAD 可以以四种不同的模式执行:
- INSERT 模式将输入数据添加到一个表中,而不更改已有的表数据。
- REPLACE 模式删除表中所有已有的数据,然后用输入数据填充这个表。
- TERMINATE 模式终止装载操作,并回滚到它开始时所在的时间点。一个例外是,如果指定了 REPLACE 模式,那么表将被删节。
- RESTART 模式用于重新开始之前被中断的装载命令。它将自动从最近的一致点继续。要使用这个模式,可以指定与前一个 LOAD 命令相同的选项,但是这一次加上 RESTART。它使实用程序可以发现在装载处理中生成的所有需要的临时表。因此,千万不要手动删除装载命令所生成的任何临时文件,除非您确信不再需要这些临时文件。一旦装载成功完成,这些临时文件将自动被删除。默认情况下,这些临时文件是在当前的工作目录中创建的。也可以使用 TEMPFILES PATH 选项指定存放临时文件的目录。
装载过程的四个阶段
一个完整的装载过程包括四个不同的阶段。
1、装载阶段:
- 将数据装载到表中。
- 收集索引键和表统计信息。
- 记录一致点。
- 将无效的数据放在转储文件中,并在消息文件中记录消息。当数据行不符合表定义时,这些数据就被当作无效数据,并且被拒绝(不装载到表中)。可以使用 dumpfile 修饰符来指定用于记录被拒绝行的文件的文件名和位置。
2、构建阶段:
基于装载阶段收集到的键创建索引。如果指定了 STATISTICS USE PROFILE,则还要根据为目标表定义的概要文件(profile)收集统计信息。这个概要文件必须在装载执行之前创建,否则将返回一个警告,并且无法收集到统计信息。
3、删除阶段:
- 删除导致违反惟一键的行,并将它们放在异常表中。除了前面描述的不符合目标表定义的数据外,还有一些通过了装载阶段但是违反表中定义的惟一性约束的数据。注意,这里只有违反惟一键的行被当作不良数据;这一次不会检查其他约束。由于这种类型的数据已经被装载到表中,因此 LOAD 实用程序将在这个阶段删除不符合要求的行。这里可以使用一个异常表来存储被删除的行,以便装载操作完成后决定如何处理它们。如果没有指定异常表,则不符合要求的行就完全被删除,而没有被跟踪。后面将更详细地讨论异常表。
- 将消息记录在消息文件中。
4、索引复制阶段:
- 如果指定了 ALLOW READ ACCESS 和 USE TABLESPACE 选项,那么这个阶段会将索引数据从系统临时表空间中复制到这些索引应该处在的表空间中。
异常表 是一种用户定义的表,它必须具有与被装载的目标表相同的列定义。如果至少有一个列在异常表中没有出现,那么不符合要求的行将被丢弃。只有两个附加的列可以添加到表的后面:一个是用于记录一个行何时被插入的时间戳列,另一个是用于存放一个行之所以被当作坏行的原因(或消息)的 CLOB 列。
您将注意到,这一屏中给出的一些概念还没有被详细谈到。在这一节剩下的部分中,我们将使用一些例子,并将这些概念串起来讲。
一个装载的例子
看看下面这个例子,它演示了一个装载过程中涉及的步骤:
LOAD FROM emp.ixf OF IXF
MESSAGES msg.out
MODIFIED BY DUMPFILE=c:\emp.dmp
TEMPFILES PATH d:\tmp
INSERT INTO employee
FOR EXCEPTION empexp
在上面的图中,(1) 显示了输入源文件的内容。
(2) 中显示的目标表 EMPLOYEE 是用以下列定义创建的:
第一列必须是惟一的。
最后一列是一个数值列,且不能为 NULL。
(3) 中显示的异常表 EMPEXP 是使用和 EMPLOYEE 相同的列,再加上时间戳和消息列创建的。
在装载阶段,输入文件中的所有数据被装载到 EMPLOYEE 中 —— 除了标为粉色的两个行,因为它们不符合 NOT NULL 和 NUMERIC 列定义。由于指定了 DUMPFILE 修饰符,因此这两行的数据被记录在 C:\emp.dmp 文件中。
在删除阶段,标为黄色的两个行被从 EMPLOYEE 中删除,并插入到异常表 EMPEXP 中。这是因为它们违反了 EMPLOYEE 表中第一列的惟一性约束造成的。
在装载的最后,您应该检查消息文件、转储文件和异常表,然后决定如何处理被拒绝的行。如果装载成功完成,那么在 D:\tmp 中生成的临时表将被删除。
装载选项和文件类型修饰符
前一屏中已经介绍了一些装载选项和文件类型修饰符。这里再讨论一些。
装载选项:
ROWCOUNT n: 允许用户指定只装载输入文件中的前 n 个记录。
SAVECOUNT n: 每装载 n 行后建立一致点。消息文件中将生成和记录一些消息,用于表明在保存点所在时间上有多少输入行被成功地装载。当输入文件类型是 CURSOR 时,不会出现这种情况。
WARNINGCOUNT n: 在发生 n 次警告后停止装载。
INDEXING MODE [ REBUILD INCREMENTAL AUTOSELECT DEFERRED ]: 在构建阶段构建索引。这个选项指定 LOAD 实用程序是重新构建索引,还是以增量的方式扩展索引。这里支持四中不同的模式:
- REBUILD 模式强制重新构建所有索引。
- INCREMENTAL 模式只向索引中添加新的数据。
- AUTOSELECT 模式允许实用程序在 REBUILD 和 INCREMENTAL 之间作出选择。
- DEFERRED 模式意味着在装载期间不会创建索引。涉及的索引上会作出标记,但是需要刷新。当重新启动数据库或者第一次访问那些索引时,才会重新构建那些索引。
STATISTICS USE PROFILE: 执行装载后,之前的目标表统计信息很可能已经无效了,因为表中添加了更多的数据。您可以选择在构建阶段根据为目标表定义的概要文件来收集统计信息。
文件类型修饰符。 文件类型修饰符是用 MODIFIED BY 子句指定的。下面是一些可能对您有用的文件类型修饰符:
- fastparse: 减少对被装载数据的语法检查,以提高性能。
- identityignore、identitymissing 和 identityoverride: 分别用于忽略列数据、表明缺少列数据或覆盖相同的列数据。
- indexfreespace n、pagefreespace n 和 totalfreespace n: 保留索引中指定数量的空闲页和数据页。
- norowwarnings: 禁止发出行警告。
- lobsinfile: 表明要装载 LOB 文件。看看用于 LOB 路径的 LOBS FROM 选项。
装载期间的表访问
当一个表被装载时,LOAD 实用程序用一个排它锁将它锁定。在装载完成之前,对表的其他访问是不允许的。这是 ALLOW NO ACCESS 选项的默认行为。在那样的装载期间,表处于 LOAD IN PROGRESS 状态。有一个很方便的命令可以检查装载操作的状态和返回表状态:
LOAD QUERY TABLE table_name
您也许会猜想有一个选项会允许表访问。ALLOW READ ACCESS 选项导致被装载的表以共享的方式锁定。读者可以访问表中已有的数据,但是不能访问新装载的那部分数据。在装载完成之前,不能访问正在装载的数据。这个选项使正在装载数据的表处于 LOAD IN PROGRESS 状态和 READ ACCESS ONLY 状态。
如前一屏中提到的那样,在构建阶段,可以重新构建一个完整的索引,也可以用新的数据扩展索引。对于 ALLOW READ ACCESS 选项,如果重新构建完整的索引,那么将创建索引的一个影子副本。当 LOAD 实用程序进入索引复制阶段(见 装载过程的四个阶段)时,目标表将离线,新的索引被复制到目标表空间。
无论指定哪种表访问选项,装载操作都需要得到各种不同的锁才能继续。如果某个应用程序已经锁住了目标表,那么 LOAD 实用程序就必须等到这些锁被释放。为了不必等到一个锁释放出来,可以使用 LOAD 命令中的 LOCK WITH FORCE 选项,使持有有冲突的锁的其他应用程序离开。
设置 Integrity Pending 表状态
到目前为止,我们知道不符合目标表定义的输入数据不会被装载到表中。在装载阶段,那样的数据会被拒绝,并记录在消息文件中。在删除阶段,LOAD 实用程序删除违反惟一性约束的行。如果指定了相关选项,则不符合要求的行将被插入到一个异常表中。那么,对于表上可能定义的其他约束,例如参照完整性约束和检查约束,又是如何处理的呢?LOAD 实用程序不会检查这些约束。表将处于 SET INTEGRITY PENDING 状态,因此,在可以访问表之前,必须手动地检查数据完整性。可以使用前一屏中讨论的 LOAD QUERY 命令来查询表的状态。系统编目表 SYSCAT.TABLES 中的 CONST_CHECKED 列也表明了表中定义的每种约束的状态。
要手动关闭一个或多个表的完整性检查,可以使用 SET INTEGRITY 命令。这里给出一些例子来演示这个命令的一些选项。为了立即为 EMPLOYEE 和 STAFF 表的附加选项检查完整性,可以使用命令:
SET INTEGRITY FOR employee, staff IMMEDIATE CHECKED INCREMENTAL
为了避免对 EMPLOYEE 表进行外键检查,可以使用 IMMEDIATE UNCHECKED 选项:
SET INTEGRITY FOR employee FOREIGN KEY IMMEDIATE UNCHECKED
在某些情况下,您可能想在装载完成后使目标表和与之有外键关系的子表处于 SET INTEGRITY PENDING 状态。这样可以确保对所有这些表的访问都受到控制,直到执行了手动的完整性检查。装载选项是 SET INTEGRITY PENDING CASCADE IMMEDIATE,这表明外键约束的 check pending 状态被立即扩展到有外键关系的所有子表中。默认情况下,只有被装载的表处于 check pending 状态。这是装载选项 SET INTEGRITY PENDING CASCADE DEFERRED 的行为。
表空间状态
由于 LOAD 实用程序直接将格式化的页写到数据库中,因此不会执行数据库日志记录来记录被装载的新数据。对于可恢复数据库(即打开了 LOGREATIN 和/或 USEREXIT 选项),DB2 需要确保那个数据库在装载完成后仍然是可恢复的。为了保¯可恢复性,用于存放表的表空间将被置于 BACKUP PENDING 模式。这意味着表空间在被访问之前必须先作备份。
这是使表空间在装载操作完成之后可以被访问的默认方法。另一种方法是在装载运行时,使用 COPY YES 选项备份被装载的数据。在装载结束时,将创建一个备份文件。
如果想避免在装载完成后立即备份表空间,那么可以考虑另外一种选择。装载选项 NONRECOVERABLE 将被装载的表标记为不可恢复。在装载完成后,相关的表空间可以完全访问。DB2 不会阻止您查询和修改表数据。但是,如果以后需要恢复表空间并且回滚到 NONRECOVERABLE 装载选项之后的某个时间点,这个被装载的表是不可恢复的。恢复过程忽略所有与表相关的日志。您只能删除并重新创建表。因此,建议在方便的时候为表作备份,使已有的数据和被装载的数据都保存在备份中。
使用 Control Center 执行装载
Control Center 为执行装载操作提供了易于使用的图形化界面。如下图所示,高级选项都用提示作了描述。使用 Control Center 很容易设置这些选项。
IMPORT 与 LOAD
下面是 IMPORT 和 LOAD 实用程序之间的比较: