Sql server至oracle历史数据迁移

目标:

新系统上线时需要老系统中的数据,把老数据库中数据按新数据库的要求转入新数据库中。且要求此过程尽量短,保证新老系统切换满足要求。

分析:

必须做的事情

整理出新系统中表对应老系统的sql,

辅助事情

1,为缩短迁移时间,把一些表迁移分二次进行,因此,找出有时间间隔不进行老数据更新的表。

2,源数据库表中有分区且数据量大的表进行折分迁移。

3,对抽取的数据进行一些验证,如条数、对应字段的总和…..

采用方式

由于不涉及采购一些抽取工具,且尽量采用简单的方式。

由于sql脚本是一个大的工作量,且可能经常调整,因此,决定采用一配制模板来定义。内容大概如下:

目标用户

表名

源脚本

参数

源验证字段

目标验证字段

增全量

 

 

目标用户是由于oralce中有多个用户,

源脚本为对应源的sql,为追求简单要求表字段顺序与sql相同。

参数是为了在sql中加入参数然后通过参数定义的内容进行替换,此内容以逗号分隔,最终产生多次导出。

源验证字段为源表sql中的字段,与目标验证字段对应。

增全量是为了比较灵活的配制成是否需要先初始化。

 

假设以上内容完成后,其实,我们可以采用很多种方式来达到迁移,比如直接自己写java,在此为了效率,确定sql server采用bcp命令导出数据,再ftp上传目标,再采用外部表方式进行。此处有说外部表方式比sql loader慢很多,但经测试外部表速度可以接受,且比较简单,因此采用外部表方式。

产生bcp脚本

产生两份BCP脚本,一初始化,一增量。

假设源sql是这样的。

SELECT

c.[SalesId]

.........其它字段

FROM

[#PARAM#].[dbo].SbSelections a,

[#PARAM#].dbo.SbSales c,

where a.PoolId=b.PoolId

and

a.SalesId=c.SalesId 

#{and a.BusinessDate &INIT

and   a.BusinessDate = c.BusinessDate

 

这个时候,可以把参数替换PARAM产生一sql,而对于配制了增量的内容,则#{and a.BusinessDate &INIT}此部分内容,初始化部分会替换为 BusinessDate 增量会替换为BusinessDate >='''+@paramdate+'''而当配制为全量时#{and a.BusinessDate &INIT}内容替换为空。

     在这个时候,产生bcp命令的同时,我们要记录一下这条sql产生的行及验证字段的和,因此,要产生以下两内容(以下内容是定义于存储过程内),

set @Sql ='bcp "SELECT convert( varchar,BusinessDate,112 ) ,ProvincialCentreId ,DistrictId ,SportsType ,case when PoolType in (''CHP'',''GPW'',''FNL'') then ''TRN'' ELSE SportsType + ''MA'' END POOL_GROUP ,PoolType  ,IsFixedOdds ,AupBetType ,BetAupBetType ,BetAupFormula ,GrossSales ,CancelAmount ,ConcludedSales ,PayableDividend ,PaidDividend ,ExpiredDividend FROM BisDS.dbo.SbAupDistrict WHERE BusinessDate >='''+@paramdate+''' "  queryout '+@outpath+'T_DISTRICT_BET_AUP_101.txt  -t "," -c -T'

exec master..xp_cmdshell @Sql

set  @exetime=dateDiff(ss,@exeDate,getdate())

insert into ##tab_bcp2582 select  'T_DISTRICT_BET_AUP',101,count(1),  @exetime,sum([GrossSales]),'GROSS_SALES_AMOUNT' from  BisDS.dbo.SbAupDistrict WHERE BusinessDate >=convert(datetime,@paramdate)

set @exeDate=getdate()

第二条插入语句是为了记录这个文件名,行数,验证和字段,目录验证字段,最后

set @Sql ='bcp "SELECT  * from tempdb..##tab_bcp2582"  queryout '+@outpath+'INIT_ALL_BCP.txt  -t "," -c -T'

exec master..xp_cmdshell @Sql

这样就可把这部分内容也记录于文件中。

注:以上内容生成时注意sql换成一行,且要去除一些注释之类,第二sql且采用去掉字段从from 开始再加上自己要的内容。

编写bat调用bcp

假设上面两存储过程文件通过解析自动生成后,这时编写bat调用

先设定一个参数文件parameter.cfg

#数据库服务器名的参数配置

ServerName=CSLJC-358DBD6CB=

#增量分隔时间

initdate=2013-01-01=

#bcp输出路径

outpath=E:\share\bisdata\=

ftp_id=192.168.109.133=

ftp_user=root=

ftp_pass=@WSX1qaz=

ftp_path=/app/g2bis/bisdata=

初始化bat,内容大致如下:

@echo off

rem 把文件中内容写入变量

set logfilename=errorlog.txt

echo off

for /f "tokens=1,2 delims=="  %%i  in (config/parameter.cfg) do (

set  %%i=%%j

)

 

set batpath=%~dp0

cd %batpath:~0,3%

cd %batpath%

del *.txt

 

sqlcmd -S %ServerName% -E -b -i "%batpath%Sp\ext_init_bcp.sql" >nul 2>&1

 

if %errorlevel% neq 0 (

  echo.

  set errMsg=创建存储过程失败!

  echo. >> %logfilename%

  echo 创建存储过程失败!>> %logfilename%

  echo. >> %logfilename%

  echo.

  goto :exit_here

)

echo 创建存储过程成功!

 

 

rem execute procedure

 

set sql=exec BisInterfaceDb.dbo.spData_init_bcp '%initdate%','%outpath%'

 

sqlcmd -S %ServerName% -E -b -Q "%sql%" >nul 2>&1

 

if %errorlevel% neq 0 (

  echo.

  set errMsg=执行存储过程失败!

  echo. >> %logfilename%

  echo 执行存储过程失败!>> %logfilename%

  echo. >> %logfilename%

  echo.

  goto :exit_here

)

 

echo 执行存储过程成功!

rem delete procedure

 

 

set sql=if exists ( select 1 from sysobjects where name = 'spData_init_bcp' and type = 'P' )

set sql=%sql% drop procedure spData_init_bcp

sqlcmd -S %ServerName% -E -b -Q "%sql%" >nul 2>&1

if %errorlevel% neq 0 (

  echo.

  set errMsg=删除存储过程失败!

  echo. >> %logfilename%

  echo 删除存储过程失败!>> %logfilename%

  echo. >> %logfilename%

  echo.

  goto :exit_here

)

echo 删除存储过程成功!

:exit_here

内容就是先把存储过程装入,再执行,再删除。

这样执行后会在指定的目录生成数据文件

ftp.bat内容大概如下

echo off

rem 把文件中内容写入变量

set logfilename=errorlog.txt

echo off

for /f "tokens=1,2 delims=="  %%i  in (config/parameter.cfg) do (

set  %%i=%%j

)

 

set batpath=%~dp0

echo open %ftp_id%>info.ftp

echo %ftp_user%>>info.ftp

echo %ftp_pass%>>info.ftp

echo cd %ftp_path%>>info.ftp

echo prompt>>info.ftp

echo mput %outpath%*.txt>>info.ftp

echo quit>>info.ftp

cd %batpath:~0,3%

ftp -s:%batpath%info.ftp >%batpath%ftp.log

echo 发送完成

pause

内容不解释,自己一看就清楚,增量的bat及初始化一样,无非就是执行不同的存储过程。

目标脚本

 目录要做的事情就是以外部表方式装载数据。

建立路径

create or replace directory DIR_TRANS_EXT_DATA

  as '/app/g2bis/bisdata';

建立一对应全表的外部表

create table BIS_TRANS.INIT_EXT_EXECUTE

(

  ext_name         VARCHAR2(128),

  ext_param        VARCHAR2(128),

  ext_source_row   VARCHAR2(128),

  ext_source_time  VARCHAR2(128),

  ext_source_total VARCHAR2(128),

  ext_targ_col     VARCHAR2(128),

  ext_targ_row     VARCHAR2(128),

  ext_targ_time    VARCHAR2(128)

)

organization external

(

  type ORACLE_LOADER

  default directory DIR_TRANS_EXT_DATA

  access parameters

  (

    records delimited by newline

    badfile 'INIT_ALL_BCP.bad'

    logfile 'INIT_ALL_BCP.log'

    fields terminated by ","

    missing field values are null

  )

  location ('ADD_ALL_BCP.txt','INIT_ALL_BCP.txt')

)

reject limit UNLIMITED;

 

对于创建外部表,可以根据oracle内容字典生成执行,也比较简单。

而对于插入,也采用根据oracle字典表自动生成语句,每次执行时,动态改表外部表对应的文件名。由于本次迁移字段比较简单,一般为字符、数据、时间,因此,只把为时间行的进行to_timestamp转换,由于ftp后,行后回车字符进行了改变,因此,最后一字段进行去除chr(13)

最后对目录数据库与源信息进行验证。程序执行尽量考虑可重复执行,出错修改简单===

结束

以上内容虽然是一实例的描述,但希望只是一个思路,因为其中涉及的东西不可能相同,但,我们的信念是,让程序做复杂的事,让人做简单的事,做好事件的分工。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/134308/viewspace-761203/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/134308/viewspace-761203/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值