使用 DB2 LOAD 实用程序的 FROM CURSOR 选项简化 DB2® for Linux®, UNIX®, and Windows® 的数据转移过程。本文介绍 LOAD FROM CURSOR 特性并提供两个接口 Command Line Processor 和 ADMIN_CMD 存储过程的使用示例。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES--> 简介
典型的 DB2 数据转移任务涉及三个步骤:
把数据以二进制或文本格式从源数据库导出到一个临时数据交换文件
在系统之间转移生成的文件
把数据从文件导入或装载到目标数据库中
在数据量很大的情况下,使用 EXPORT 实用程序生成数据交换文件常常要花费很长时间。另外,在把数据移入和移出数据库时,必须考虑不同的数据库编码页和操作系统。
可以使用 LOAD 实用程序的 FROM CURSOR 选项避免这些问题。当指定 FROM CURSOR 选项时,LOAD 实用程序直接把一个 SQL 查询的结果集作为数据装载操作的来源,这样就不需要生成临时数据交换文件。因此,LOAD FROM CURSOR 是在不同的表空间或数据库之间快速轻松地转移数据的方法。可以在命令行上执行 LOAD FROM CURSOR,也可以通过使用 DB2 的 ADMIN_CMD 存储过程在应用程序或存储过程中执行它。本文介绍 LOAD FROM CURSOR 特性并提供两个接口 Command Line Processor (CLP) 和 ADMIN_CMD 存储过程的使用示例。
把表转移到另一个表空间
首先,看看如何把表从一个表空间转移到另一个表空间。如果创建表的表空间的页面大小不合适,或者应该用另一个缓冲区池访问表,就可能需要执行这种数据转移。在 9.1 以前的 DB2 版本中,常常由于达到表空间的最大大小而在表空间之间转移表。但是,在 DB2 9.1 和更高版本中,这应该不再是问题了,因为表空间大小限制已经显著提高了(前提是使用大表空间,而不是以前使用的常规表空间)。
这个示例场景首先创建 DB2 SAMPLE 数据库。这可以通过在命令行上调用 db2sampl 命令来完成,见清单 1。
清单 1. 创建 SAMPLE 数据库
C:\>db2sampl
Creating database "SAMPLE"...
Connecting to database "SAMPLE"...
Creating tables and data in schema "FECHNER"...
'db2sampl' processing complete.
C:\>db2 "CONNECT TO SAMPLE"
Database Connection Information
Database server = DB2/NT 9.5.2
SQL authorization ID = FECHNER
Local database alias = SAMPLE
C:\>db2 "SELECT TABLES.TABSCHEMA, TABLES.TABNAME, TBSPACES.TBSPACE FROM SYSCAT.TABLES AS
TABLES, SYSCAT.TABLESPACES AS TBSPACES WHERE TABLES.TBSPACEID = TBSPACES.TBSPACEID AND
TABNAME = 'SALES'"
TABSCHEMA
TABNAME
TBSPACE
------------------------------------------------------------------------------------------
-------- ---------------------------------------------------------------------------------
----------------- ------------------------------------------------------------------------
--------------------------
FECHNER
SALES
USERSPACE1
C:\>db2 "LIST TABLESPACES"
Tablespaces for Current Database
Tablespace ID = 0
Name = SYSCATSPACE
Type = Database managed space
Contents = All permanent data. Regular table space.
State = 0x0000
Detailed explanation:
Normal
Tablespace ID = 1
Name = TEMPSPACE1
Type = System managed space
Contents = System Temporary data
State = 0x0000
Detailed explanation:
Normal
Tablespace ID = 2
Name = USERSPACE1
Type = Database managed space
Contents = All permanent data. Large table space.
State = 0x0000
Detailed explanation:
Normal
Tablespace ID = 3
Name = IBMDB2SAMPLEREL
Type = Database managed space
Contents = All permanent data. Large table space.
State = 0x0000
Detailed explanation:
Normal
在把 SALES 表的内容复制到 IBMDB2SAMPLEREL 表空间之前,必须在目标表空间中创建一个空表,此表的结构应该与 SALES 表相同。因为在同一个数据库模式中不可能有两个同名的表,所以临时用 SALES_TMP 这个名称创建新的表。通过在 CREATE TABLE 命令中指定 LIKE 选项,创建一个与现有表结构相同的空表(清单 4)。通过 IN 选项显式地定义新表 SALES_TMP 的表空间。
清单 4. 创建数据转移操作所需的目标表 SALES_TMP
C:\>db2 "CREATE TABLE FECHNER.SALES_TMP LIKE FECHNER.SALES IN IBMDB2SAMPLEREL"
DB20000I The SQL command completed successfully.
C:\>db2 "DECLARE C1 CURSOR FOR SELECT * FROM FECHNER.SALES"
DB20000I The SQL command completed successfully.
C:\>db2 "LOAD FROM C1 OF CURSOR MESSAGES C:\load_sales_tmp.msg INSERT INTO
FECHNER.SALES_TMP NONRECOVERABLE"
Number of rows read = 41
Number of rows skipped = 0
Number of rows loaded = 41
Number of rows rejected = 0
Number of rows deleted = 0
Number of rows committed = 41
C:\>db2 "UPDATE DBM CFG USING FEDERATED YES"
DB20000I The UPDATE DATABASE MANAGER CONFIGURATION command completed
successfully.
SQL1362W One or more of the parameters submitted for immediate modification
were not changed dynamically. Client changes will not be effective until the
next time the application is started or the TERMINATE command has been issued.
Server changes will not be effective until the next DB2START command.
C:\>db2stop
2008-09-22 14.55.36 0 0 SQL1064N DB2STOP processing was successful.
SQL1064N DB2STOP processing was successful.
C:\>db2start
2008-09-22 14.55.53 0 0 SQL1063N DB2START processing was successful.
SQL1063N DB2START processing was successful.
C:\>db2 "CREATE DATABASE MYSAMPLE"
DB20000I The CREATE DATABASE command completed successfully.
C:\>db2look -d sample -e -z fechner -t sales -o sales.ddl
-- USER is: FECHNER
-- Specified SCHEMA is: FECHNER
-- The db2look utility will consider only the specified tables
-- Creating DDL for table(s)
-- Schema name is ignored for the Federated Section
-- Output is sent to file: sales.ddl
-- Binding package automatically ...
-- Bind is successful
-- Binding package automatically ...
-- Bind is successful
-- This CLP file was created using DB2LOOK Version 9.5
-- Timestamp: 23.09.2008 07:35:10
-- Database Name: SAMPLE
-- Database Manager Version: DB2/NT Version 9.5.2
-- Database Codepage: 1208
-- Database Collating Sequence is: IDENTITY
CONNECT TO SAMPLE;
------------------------------------------------
-- DDL Statements for table "FECHNER "."SALES"
------------------------------------------------
CREATE TABLE "FECHNER "."SALES" (
"SALES_DATE" DATE ,
"SALES_PERSON" VARCHAR(15) ,
"REGION" VARCHAR(15) ,
"SALES" INTEGER )
IN "IBMDB2SAMPLEREL" ;
C:\>db2 "CATALOG TCPIP NODE SRCNODE REMOTE localhost SERVER 50000"
DB20000I The CATALOG TCPIP NODE command completed successfully.
DB21056W Directory changes may not be effective until the directory cache is
refreshed.
C:\>db2 "CATALOG DATABASE SAMPLE AS SRCDB AT NODE SRCNODE AUTHENTICATION SERVER"
DB20000I The CATALOG DATABASE command completed successfully.
DB21056W Directory changes may not be effective until the directory cache is
refreshed.
C:\>db2 "TERMINATE"
DB20000I The TERMINATE command completed successfully.
C:\>db2 "CONNECT TO MYSAMPLE"
Database Connection Information
Database server = DB2/NT 9.5.2
SQL authorization ID = FECHNER
Local database alias = MYSAMPLE
C:\>db2 "CREATE WRAPPER DRDA"
DB20000I The SQL command completed successfully.
C:\>db2 "CREATE SERVER SRCSRV TYPE DB2/UDB VERSION 9.5 WRAPPER DRDA AUTHORIZATION
\"fechner\" PASSWORD \"password\" OPTIONS (DBNAME 'SRCDB')"
DB20000I The SQL command completed successfully.
C:\>db2 "CREATE USER MAPPING FOR fechner SERVER SRCSRV OPTIONS (REMOTE_AUTHID 'fechner',
REMOTE_PASSWORD 'password')"
DB20000I The SQL command completed successfully.
C:\>db2 "CREATE NICKNAME FECHNER.SRCTAB FOR SRCSRV.FECHNER.SALES"
DB20000I The SQL command completed successfully.
注意:这里描述的设置联邦访问所需的步骤完全独立于 LOAD FROM CURSOR 功能。这意味着这些是为远程数据库中的表创建别名的通用步骤。
配置了对源数据库表的联邦访问之后,就可以像前面一样执行 LOAD FROM CURSOR 操作。首先,定义一个游标,它使用上面创建的别名读取远程表中的所有行。然后,在 LOAD 命令中引用这个游标。
清单 15. 使用别名执行远程 LOAD FROM CURSOR 操作
C:\>db2 "DECLARE C1 CURSOR FOR SELECT * FROM FECHNER.SRCTAB"
DB20000I The SQL command completed successfully.
C:\>db2 "LOAD FROM C1 OF CURSOR MESSAGES C:\load_sales.msg INSERT INTO FECHNER.SALES
NONRECOVERABLE"
Number of rows read = 41
Number of rows skipped = 0
Number of rows loaded = 41
Number of rows rejected = 0
Number of rows deleted = 0
Number of rows committed = 41
C:\>db2 "TERMINATE"
DB20000I The TERMINATE command completed successfully.
正如前面提到的,与方法 2 相比,结合使用 LOAD FROM CURSOR 操作和联邦访问需要做的配置工作比较多。但是,联邦访问的主要优点是可以从非 DB2 数据源装载数据。通过使用联邦方式,可以访问 Oracle、SQL Server 等数据源以及其他许多关系和非关系数据源,通过创建别名并执行引用别名的 LOAD FROM CURSOR 操作来复制内容。WebSphere Federation Server 产品提供访问非 DB2 数据源所需的包装器。
在另一个数据库中创建表拷贝的简便方法
既然已经了解了使用别名的远程 LOAD FROM CURSOR 操作方法,现在看看另一种比较简便的方法。为此,首先删除刚才在目标数据库 MYSAMPLE 中的 SALES 表中导入的所有行,见清单 16。
清单 16. 删除目标表中的所有行,以便再次执行 LOAD FROM CURSOR 操作
C:\>db2 "CONNECT TO MYSAMPLE"
Database Connection Information
Database server = DB2/NT 9.5.2
SQL authorization ID = FECHNER
Local database alias = MYSAMPLE
C:\>db2 "DELETE FROM FECHNER.SALES"
DB20000I The SQL command completed successfully.
C:\>db2 "DECLARE C1 CURSOR DATABASE SRCDB USER fechner USING password FOR SELECT * FROM
FECHNER.SALES"
DB20000I The SQL command completed successfully.
C:\>db2 "LOAD FROM C1 OF CURSOR MESSAGES C:\load_sales_2.msg INSERT INTO FECHNER.SALES
NONRECOVERABLE"
Number of rows read = 41
Number of rows skipped = 0
Number of rows loaded = 41
Number of rows rejected = 0
Number of rows deleted = 0
Number of rows committed = 41
C:\>db2 "TERMINATE"
DB20000I The TERMINATE command completed successfully.
CREATE PROCEDURE FECHNER.REMOTE_LOAD_FROM_CURSOR ()
SPECIFIC REMOTE_LOAD_FROM_CURSOR
LANGUAGE SQL
BEGIN
DELETE FROM FECHNER.SALES;--
CALL SYSPROC.ADMIN_CMD ('LOAD FROM (DATABASE SRCDB SELECT * FROM FECHNER.SALES) OF
CURSOR INSERT INTO FECHNER.SALES NONRECOVERABLE');--
END;
存储过程中的第一个语句是 DELETE,它删除本地目标表 SALES 中现有的行。接下来,用适当的 LOAD 命令调用 ADMIN_CMD,从而执行远程 LOAD FROM CURSOR 操作。这种方式与从命令行执行 LOAD FROM CURSOR 操作的差异如下:
C:\>db2 "CONNECT TO MYSAMPLE"
Database Connection Information
Database server = DB2/NT 9.5.2
SQL authorization ID = FECHNER
Local database alias = MYSAMPLE
C:\>db2 -tf create_load_routine.sql
DB20000I The SQL command completed successfully.
通过 ADMIN_CMD 执行的远程 LOAD FROM CURSOR 操作的这一特点(无法指定远程访问所用的用户)还有一个影响:当前连接本地数据库的用户必须用相同的授权 ID 访问远程数据库。在使用联邦方法访问远程数据库时,没有这一限制,因为必须以用户映射的形式定义额外的抽象层。
既然找到了错误的原因,就可以重新连接本地数据库,这一次显式地指定用户名和密码。对存储过程的第二次调用应该会成功 (Return Status = 0),见清单 21。
清单 21. 对示例存储过程的第二次测试成功
C:\>db2 "CONNECT TO MYSAMPLE USER fechner"
Enter current password for fechner:
Database Connection Information
Database server = DB2/NT 9.5.2
SQL authorization ID = FECHNER
Local database alias = MYSAMPLE
C:\>db2 "CALL FECHNER.REMOTE_LOAD_FROM_CURSOR"
Return Status = 0
C:\>db2 "TERMINATE"
DB20000I The TERMINATE command completed successfully.
结束语
本文通过示例场景演示了如何使用 DB2 的 LOAD FROM CURSOR 特性在一个数据库中以及不同的数据库之间快速轻松地复制数据。还解释了通过 ADMIN_CMD 存储过程在应用程序代码中执行 LOAD FROM CURSOR 操作时的特殊问题。另外,还讲解了如何为另一个数据库配置联邦访问,从而像访问本地表或视图一样透明地读写远程数据库中的表和视图。
参考资料 学习
您可以参阅本文在 developerWorks 全球网站上的 英文原文。
阅读 Moving data using the CURSOR file type,进一步了解本文讨论的主题。
访问 DB2 9.5 Information Center for Linux, UNIX, and Windows,获取完整的 HTML 格式的 DB2 9.5 LUW 在线文档。
可以在 DB2 9 for Linux UNIX and Windows Support Site 上搜索 APAR、下载补丁包、获取 PDF 格式的 DB2 LUW 文档等等。
阅读 Best practices for DB2 for Linux, UNIX, and Windows。这些文件为最常见的 DB2 9 产品配置提供实用指南。通过应用这些建议,可以提高 DB2 数据服务器的价值,及时跟上 DB2 的发展步伐。这些文件是由 IBM 开发和咨询团队中的高级专家撰写的,并且经过全面测试。
在 技术书店 浏览关于这些主题和其他技术主题的图书。
获得产品和技术
下载 IBM 产品评估版,试用这些来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
参与论坛讨论。
参与 developerWorks blogs 并加入 developerWorks 社区。
关于作者
Dirk Fechner 在 IBM Software Group 中担任 IT 服务专家。他的专长领域是分布式平台上 DB2 UDB 的管理和应用程序开发。他拥有 5 年 DB2 UDB 方面的经验,也是一名 IBM 认证的高级 DBA 和 IBM 认证的应用程序开发人员。目前,他在 DaimlerChrysler 为管理员、开发人员和最终用户就各种 DB2 主题提供支持,包括管理任务、应用程序开发以及问题判别。