posts - 89,  comments - 98,  trackbacks - 0

DB2 表复制方法介绍

Version:v1.0.0

Author xiedd

Mail:xiedd@icss.com.cn

CreateDate:2006-08-29

LastEditDate:2006-08-30

*         说明

本文描述如何将DB2数据库中的一些表复制到另一个数据库中,适用于表中的数据量比较大(如1万条记录以上)的情况。当表中的数据量较少,并且表的数量不多时,可直接使用db2控制中心的表复制功能实现。

*         适用条件

n         DB2 中表的跨库复制,两个数据库可以在一台机器上,也可以在不同的机器上。(以下假设两个数据库位于不同的机器上。)

n         单一表中的数据量较大,通常在1万条记录数以上;

n         表的个数比较多;

*         术语定义

n         源数据库:需要复制的表存在的数据库;

n         目标数据库:需要复制的表复制后存在的数据库;

n         DDL: 数据定义语言, 用于建立和删除数据库以及数据库实体的命令。

*         总体说明

表的复制一般情况下用到了db2的以下几个命令:

1.       EXPORT: 导出表中的数据到数据文件中。

2.       IMPORT: 导入数据文件中的数据到表中。

3.       LOAD :同IMPORT。区别是IMPORT需要写日志,而LOAD不需要,因此可以极大的提高数据的装载速度。

本文数据复制的思想是:首先通过DDL语言将源数据库中的表结构复制到目标数据库上,再通过批处理命令将源数据库中需要复制的表export成数据文件(IXF集成交换格式),然后将数据文件复制到目标数据库所在的机器上,通过load命令将数据文件装载到目标数据库中。

此过程主要使用了load命令以及避免了网络传输,可以极大提高数据的复制速度。而脚本的方式也提供了更好的扩展性,可对任意个数的表进行复制。同时针对某些复杂情况可使用程序支持对这些脚本的自动生成。

*         具体步骤

以下步骤假设:

l         源数据库为yndc

l         目标数据库为htdc

 

一、    创建生成DLL文件的批处理文件

本步骤创建文件dll.bat

其内容语法示例如下:

db2look -d <dbname> -t  <table1> <table2> <tableN>  -e -nofed -o dll.sql

<dbname>替换成源数据库的名称,<tableN>替换成具体的表名,多个表之间用空格分隔。如以下示例导出yndc数据库中的2个表DIM_GROUPDIM_PJ_MACH的库表结构。

db2look -d yndc -t  DIM_GROUP DIM_PJ_MACH  -e -nofed -o dll.sql

 

二、    执行DLL批处理文件,生成DLL文件

本步骤执行dll.bat

dll.bat复制到源数据库所在的机器上,在db2cmd环境中执行dll.bat,生成dll.sql

 

三、    执行DLL文件

本步骤执行dll.sql

执行之前,更改dll.sql中目标数据库名称,并输入用户名和密码。同时必要情况下,更改表所在的表空间。

-- CLP 文件是使用 DB2LOOK 版本创建的 8.2

-- 时间戳记: 2006-7-10 11:28:02

-- 数据库名称: YNDC          

-- 数据库管理器版本: DB2/NT Version 8.2.4         

-- 数据库代码页: 1386

-- 数据库整理顺序为: UNIQUE

 

 

CONNECT TO HTDC user db2admin using db2password;

 

------------------------------------------------

-- 表的 DDL 语句 "DB2ADMIN"."BC_FACCIGTEMPLATE"

------------------------------------------------

 

 CREATE TABLE "DB2ADMIN"."BC_FACCIGTEMPLATE"  (

       "CITYID" VARCHAR(30) NOT NULL ,

       "CIGID" VARCHAR(30) NOT NULL ,

       "CIGNAME" VARCHAR(50) NOT NULL ,

       "ISUPLOAD" SMALLINT )  

       IN "HTDC" ;

-- 表上的索引的 DDL 语句 "DB2ADMIN"."BC_FACCIGTEMPLATE"

 

CREATE INDEX "DB2ADMIN"."PK__BC_FACCIGTEMP1" ON "DB2ADMIN"."BC_FACCIGTEMPLATE"

     ("CITYID" ASC,

      "CIGID" ASC) CLUSTER ;

 

 

-- 表上主键的 DDL 语句 "DB2ADMIN"."BC_FACCIGTEMPLATE"

 

ALTER TABLE "DB2ADMIN"."BC_FACCIGTEMPLATE"

ADD CONSTRAINT "SQL051107160756210" PRIMARY KEY

     ("CITYID",

      "CIGID");

 

COMMIT WORK;

CONNECT RESET;

TERMINATE;

 

然后进入db2cmd环境,切换到dll.sql所在的目录,执行以下命令:

db2 -tvf dll.sql

注意查看执行结果是否正确。

 

四、    创建导出数据的EXPORT脚本

本步骤创建脚本export.bat

内容格式示例如下:

db2 connect to <dbname> user <username> using <password>

db2 "export to aa1.ixf of ixf select * from <table1>"

db2 "export to aa2.ixf of ixf select * from <table2>"

db2 "export to aa3.ixf of ixf select * from <table3>"

db2 connect reset

替换数据库名称、用户名、密码、表名。注意事项:多个表之间的集成交换格式文件按需要递增,如aa1.ixf,aa2.ixf,aa3.ixf...,并且要和后续的load脚本对应。

 

以下样例导出2个表的数据,样例如下:

db2 connect to yndc user db2admin using db2password

db2 "export to aa1.ixf of ixf select * from DIM_GROUP"

db2 "export to aa2.ixf of ixf select * from DIM_PJ_MACH"

db2 connect reset

 

五、    执行export脚本

本步骤执行export.bat

在源数据库所在的机器上,在db2cmd环境中执行export.batN个表将生成N个集成交换格式数据文件(后缀名.ixf)

 

六、    将导出的数据压缩复制到目标数据库所在机器,并解压缩

将数据文件打成rarzip包,复制到目标机器上,并解压缩。

 

七、    构建导入数据的LOAD脚本

本步骤在数据文件(IXF)所在的目录中创建load.bat

内容格式示例如下:

db2 connect to <dbname> user <username> using <password>

db2 "load from aa1.ixf of ixf  replace into <table1>  COPY NO  without prompting " > 1_<table1>.log

db2 "load from aa2.ixf of ixf  replace into <table2> COPY NO  without prompting " > 2_<table2>.log

db2 connect reset

替换数据库名称、用户名、密码、表名。注意事项:集成交换格式文件(ixf)对应的表名要和export时导出的表名对应。

 

以下样例导入2个表的数据,样例如下:

db2 connect to yndc user db2admin using db2password

db2 "load from aa1.ixf of ixf  replace into DIM_GROUP  COPY NO  without prompting " > 1_DIM_GROUP.log

db2 "load from aa2.ixf of ixf  replace into DIM_PJ_MACH  COPY NO  without prompting " > 2_DIM_PJ_MACH.log

db2 connect reset

       

八、    执行load脚本,检查执行结果

本步骤执行export.bat

db2cmd环境中切换到load.bat所在的目录,执行load.bat

执行完成之后N个表将生成Nlog文件,逐一检查这些log文件,以确定数据load是否正常。

所有步骤结束!

 

*         附录1:重命名表的名称

如果需要将表复制到目标数据库时使用不同的名称,可在以上步骤完成之后,再编辑一个脚本,执行表的重命名操作。示例如下:

db2 connect to <dbname> user <username> using <password>

db2 rename <table1_old> to <table2_new>

db2 rename <table2_old> to <table3_new>

...
db2 connect reset

*         附录2:使用程序生成脚本

当表的数量较多,手工编辑脚本比较复杂时,可通过java程序生成dll.batexport.batload.bat

示例如下:

/**

 * <p>Title: 数据库集成服务类,支持对yndc等数据库进行集成</p>

* @version 1.0

 */

public class DBEAIService {

    /**

     * 数据文件存放目录

     */

    private String DEST_DIR = Globals.ManagerHome + "/output";

 

    /**

     * 日志记录器

     */

    private static Logger log = Logger.getLogger(DBEAIService.class);

 

    public DBEAIService() {

 

    }

 

 

    /**

     * 创建导出脚本

     * @param conn

     * @param creator  表创建者

     * @param filePath

     */

    private void createExportFile(Connection conn, String creator,

                                  String filePath) throws Exception {

        DBBase dbBase = new DBBase(conn);

        String selectTableSql =

                "select name from sysibm.systables where creator = '"

                + creator + "' and type='T' order by name";

        try {

            dbBase.executeQuery(selectTableSql);

        } catch (Exception ex) {

            throw ex;

        } finally {

            dbBase.close();

        }

        DBResult result = dbBase.getSelectDBResult();

        List list = new ArrayList();

        while (result.next()) {

            String table = result.getString(1);

            list.add(table);

        }

        StringBuffer sb = new StringBuffer();

        String enterFlag = "\r\n";

        for (int i = 0; i < list.size(); i++) {

            String tableName = (String) list.get(i);

            sb.append("db2 \"export to aa" + String.valueOf(i + 1)

                      + ".ixf of ixf select * from " + tableName + "\"");

            sb.append(enterFlag);

        }

        String str = sb.toString();

        FileUtility.saveStringToFile(filePath, str, false);

    }

 

    /**

     * 创建装载脚本

     * @param conn

     * @param creator  表创建者

     * @param filePath

     */

    private void createLoadFile(Connection conn, String creator,

                                String filePath) throws

            Exception {

        DBBase dbBase = new DBBase(conn);

        String selectTableSql =

                "select name from sysibm.systables where creator = '"

                + creator + "' and type='T' order by name";

        try {

            dbBase.executeQuery(selectTableSql);

        } catch (Exception ex) {

            throw ex;

        } finally {

            dbBase.close();

        }

        DBResult result = dbBase.getSelectDBResult();

        List list = new ArrayList();

        while (result.next()) {

            String table = result.getString(1);

            list.add(table);

        }

        StringBuffer sb = new StringBuffer();

        String enterFlag = "\r\n";

        for (int i = 0; i < list.size(); i++) {

            String tableName = (String) list.get(i);

            sb.append("db2 \"load from aa" + String.valueOf(i + 1)

                      + ".ixf of ixf into " + tableName

                      + "  COPY NO  without prompting \"");

            sb.append(enterFlag);

        }

        String str = sb.toString();

        FileUtility.saveStringToFile(filePath, str, false);

    }

 

    /**

     * 获取某个数据库表明的列表

     * @param conn

     * @param creator  表创建者

     * @return

     * @throws Exception

     */

    private List getTableList(Connection conn, String creator) throws Exception {

        DBBase dbBase = new DBBase(conn);

        String selectTableSql =

                "select name from sysibm.systables where creator = '"

                + creator + "' and type='T' order by name";

        try {

            dbBase.executeQuery(selectTableSql);

        } catch (Exception ex) {

            throw ex;

        } finally {

            dbBase.close();

        }

        DBResult result = dbBase.getSelectDBResult();

        List list = new ArrayList();

        while (result.next()) {

            String table = result.getString(1);

            list.add(table);

        }

        return list;

    }

 

    /**

     * 将列表写入到文本文件中

     * @param list

     * @param filePath

     */

    public void saveListToFile(List list, String filePath) throws Exception {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < list.size(); i++) {

            String value = (String) list.get(i);

            sb.append(value);

            sb.append("\r\n");

        }

        String str = sb.toString();

        FileUtility.saveStringToFile(filePath, str, false);

    }

 
posted on 2006-09-14 09:55 水煮三国 阅读(2217) 评论(0)  编辑  收藏 所属分类: Database

只有注册用户登录后才能发表评论。


网站导航:
 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(4)

随笔分类(85)

随笔档案(89)

文章分类(14)

文章档案(42)

收藏夹(37)

java

oracle

Sybase

搜索

  •  

积分与排名

  • 积分 - 208908
  • 排名 - 267

最新评论

阅读排行榜

评论排行榜