最近的项目,要批量导出源库的数据,在批量导入到中间库,在中间库用存储过程加工后,批量插入到目标库。用到一些东西做分享。
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
-
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;
3. 导入方法
由于导出的文件格式统一,导入ORACLE就可以使用统一的方法。由于SQLLDR加载的方式有多种,优先使用TRUNCATE。性能更高。根据数据源为了导入可以任务并行,任务自己多线程,临时表建议使用分区表,或者动态建表,设置为NOLOGGING。目的都一样是为了多线程/并行过程中不锁表,推荐使用分区表,因为后续写存储过程不需要拼接表名,代码可读性更强。
基本逻辑
第一步:生成控制文件CTL
unrecoverable
load 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
-
sqlldr 用户/密码@数据库 control=控制文件 log=日志文件 skip=0 errors=0 direct=true readsize=20971520 bindsize=20971520;
skip的作用是跳过行数,有些CSV表格,有表头就需要跳过第一行。
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博客 ” ,链接:https://blog.itpub.net/28897986/viewspace-1727585/
,如需转载,请注明出处,否则将追究法律责任。