最近的项目,要批量导出源库的数据,在批量导入到中间库,在中间库用存储过程加工后,批量插入到目标库。用到一些东西做分享。
1. 基本的结构
1.1 逻辑:数据处理平台(类ETL工具),定时任务调用DLL(封装各类数据处理函数),DLL调用数据库底层工具和ORACLE存储过程包。
1.2 工具:DB2的批量导出工具DB2CMD-EXPORT命令。SQLSERVER的批导工具BCP,ORACLE的批导工具SPOOL和SQLLDR
2.导出方法
所有导出文件都是文件文件(CSV/TXT),CSV文件由于可以用记事本和EXCEL打开,核对数据比较方便,是首选。
2.1 DB2
生成BAT文件
导入完成后的任务,就是存储过程来了。后续再分享。
---------------------------------------------------------------------------------------------------------------
1. 基本的结构
1.1 逻辑:数据处理平台(类ETL工具),定时任务调用DLL(封装各类数据处理函数),DLL调用数据库底层工具和ORACLE存储过程包。
1.2 工具:DB2的批量导出工具DB2CMD-EXPORT命令。SQLSERVER的批导工具BCP,ORACLE的批导工具SPOOL和SQLLDR
2.导出方法
所有导出文件都是文件文件(CSV/TXT),CSV文件由于可以用记事本和EXCEL打开,核对数据比较方便,是首选。
2.1 DB2
生成BAT文件
@echo off
@db2 connect to BX user db2admin using abc#12345
@db2 "EXPORT TO D:\TLvouch.csv OF DEL MODIFIED BY DECPLUSBLANK STRIPLZEROS MESSAGES D:\TLvouch_exp.log SELECT FDATE FROM TVOUCH"
@db2 connect reset
@exit
在用WIN API导出即可
2.2 SQLSERVER
直接调用就好了
sQuery:查询SQL; sFile:目标文件;sLogFile:日志文件;sUser:数据库用户;sPassWord:密码;sDataSource:数据库
sCMDStr := 'BCP "' + sQuery + '" queryout ' + sFile + ' -c -t "," -o ' + sLogFile + ' -U ' + sUser + ' -P ' + sPassWord + ' -S '+ sDataSource;
ExecuteAndWait(sCMDStr);//函数在最下方
2.3 ORACLE
导出工具是SPOOL
3. 导入方法
由于导出的文件格式统一,导入ORACLE就可以使用统一的方法。由于SQLLDR加载的方式有多种,优先使用TRUNCATE。性能更高。根据数据源为了导入可以任务并行,任务自己多线程,临时表建议使用分区表,或者动态建表,设置为NOLOGGING。目的都一样是为了多线程/并行过程中不锁表,推荐使用分区表,因为后续写存储过程不需要拼接表名,代码可读性更强。
基本逻辑
第一步:生成控制文件CTL
2.2 SQLSERVER
直接调用就好了
sQuery:查询SQL; sFile:目标文件;sLogFile:日志文件;sUser:数据库用户;sPassWord:密码;sDataSource:数据库
sCMDStr := 'BCP "' + sQuery + '" queryout ' + sFile + ' -c -t "," -o ' + sLogFile + ' -U ' + sUser + ' -P ' + sPassWord + ' -S '+ sDataSource;
ExecuteAndWait(sCMDStr);//函数在最下方
2.3 ORACLE
导出工具是SPOOL
点击(此处)折叠或打开
- set echo on
- set feedback off
- rows selected set heading off
- set verify off
- filset trimspool off
- set pagesize 1000
- set linesize 100
- define fil=\'D:\\exp.csv\'
- spool &fil
- select s.s_id||\',\'||s.snum||\',\'||s.sname from spool_test s;
- spool off;
由于导出的文件格式统一,导入ORACLE就可以使用统一的方法。由于SQLLDR加载的方式有多种,优先使用TRUNCATE。性能更高。根据数据源为了导入可以任务并行,任务自己多线程,临时表建议使用分区表,或者动态建表,设置为NOLOGGING。目的都一样是为了多线程/并行过程中不锁表,推荐使用分区表,因为后续写存储过程不需要拼接表名,代码可读性更强。
基本逻辑
第一步:生成控制文件CTL
unrecoverableload data infile 'D:\TLvalue.csv' //导入CSV文件badfile 'D:\TLvalue.bad' //错误文件discardfile 'D:\TLvalue.dis' //作废文件truncate into table TTMP_VALUE // truncate导入,如果是分区表改成 truncate into table TTMP_VALUE partition(分区名称)fields terminated by "," //逗号分隔optionally enclosed by '"' //字符串引号
TRAILING NULLCOLS (VC_VALUE,VC_TYPE) //目标列名
第二步:调用SQLLDR
skip的作用是跳过行数,有些CSV表格,有表头就需要跳过第一行。
errors的作用是出现错误的次数。我设置为0,不能有一行有错误。一旦报错就退出导入。
后面的参数是为了多线程和批量导入设置。
点击(此处)折叠或打开
- sqlldr 用户/密码@数据库 control=控制文件 log=日志文件 skip=0 errors=0 direct=true readsize=20971520 bindsize=20971520;
errors的作用是出现错误的次数。我设置为0,不能有一行有错误。一旦报错就退出导入。
后面的参数是为了多线程和批量导入设置。
导入完成后的任务,就是存储过程来了。后续再分享。
---------------------------------------------------------------------------------------------------------------
点击(此处)折叠或打开
- function ExecuteAndWait(const CommandLine: string): cardinal;
- var
- tSI : TStartupInfo;
- tPI : TProcessInformation;
- dwI : DWORD;
- begin
- Result := 0;
- FillChar(tSI, sizeof(TStartupInfo),0);
- tSI.cb := sizeof(TStartupInfo);
- tSI.dwFlags := STARTF_USESHOWWINDOW;
- tSI.wShowWindow := SW_HIDE;
- if (CreateProcess(nil,pchar(CommandLine),nil,nil,False,0,nil,nil,tSI,tPI)) then
- begin
- dwI := WaitForSingleObject(tPI.hProcess,INFINITE);
-
- if (dwI = WAIT_OBJECT_0) then
- if (GetExitCodeProcess(tPI.hProcess,dwI)) then
- Result := dwI;
- CloseHandle(tPI.hProcess);
- CloseHandle(tPI.hThread);
- end;
- end;
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28897986/viewspace-1727585/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/28897986/viewspace-1727585/