背景
在【Oracle移行到Sqlserver完美解决案】④sqluldr2+bulk 32H=>3H一文中,我们已经完整的实现了Oracle移行到Sqlserver。内存溢出,执行时间这些棘手的问题都得到了解决。这个案,有个大的前提,就是在Sqlserver服务器,要安装oracle的客户端,否则你无法在Sqlserver访问到Oracle数据库。
实现案分析
如果客户不想安装oracle客户端,我们如何来实现从oracle到SQLserver的移行。也就是我们不能使用dblink。我们可以将Oracle端的表数据=》文件,文件copy到sqlserver,文件=》Sqlserver。如下图:
这个案的大多的技术点,像sqluldr2,bulk insert我们在前面的一章中都已经提到了,特殊的就是Oracle中有blob字段,这个是存储大数据的字段类型,例如文件,图像等文件保存到数据库时,使用blob字段类型来存储,这个字段名,我们假设叫做IMAGE,便于后面的说明。移行到sqlserver对应的字段类型就是varbinary(MAX)。IMAGE字段的数据是可以通过sqluldr2来生成到文本文件中,但是内容不对,所以在bulk insert插入到sqlserver时会报错。
其实这个问题在④的案中也存在,因为含有blob字段的表比较少,数据量比较小,所以采用insert .. select 的方式进行插入。我们的项目4张表,不到一个小时插入完成,还算能够接受。但是对于⑤的案,没有oracle客户端,所以不能这么来实现,也成为这个案是否可行的瓶颈。通过实践,我们的解决案如下:
1,IMAGE字段的数据读出生成文件,文件名字是该行数据的ROWID+ROWNUM
因为oracle每次读取最大32767,所以需要循环读取,然后保存生成到文件,具体看代码
这里说明下,为什么生成的文件名用ROWID,因为ROWID唯一,你可以根据文件名查到是哪条数据,便于出问题时的排查,另外ROWID的值字母有大小写,但是window的文件名不区分大小写,所以还需要加ROWNUM来确定唯一性。
2,用生成的文件,更新sqlserver的IMAGE字段
我是事先将IMAGE字段保存ROWID的值,插入到sqlserver,然后sqlserver端,循环blob相关的表记录,根据IMAGE字段的ROWID,找到生成的文件,进行更新处理。具体代码如下:
主要的更新语句如下,使用OPENROWSET BULK的方式通过文件更新字段。
UPDATE LDBMUSRCNF SET IMAGE=BulkColumn FROM OPENROWSET(BULK N'文件路径', SINGLE_BLOB) AS file WHERE ....)
执行时间:
通过这种方式,Oracle端导出文件大小是25G(blob文件7G,Blob表以外18G),执行时间3小时多点。拷贝到Sqlserver服务器,通过bulk insert方式插入用了3个小时,blob文件更新到varbinary字段用了1个小时。合计用了将近8个小时。和上一个案3个小时相比,还是要花费更多的时间
反思:
到目前为止,2个实现案基本介绍完了,个人认为是比较通用的移行方案。不足之处,请多多指教。
对于解决案,我们主要围绕大数据量表,blob特殊字段表,容易出现性能问题的角度展开的,对于整体的实现,其实说明的还不足,例如2个数据库的对应表,字段个数,属性有差异,如何自动确认对应关系,之后会把这部分整理下,跟大家分享,感兴趣的给我留言啊
索引:
【Oracle移行到Sqlserver完美解决案】①Sqlserver内存溢出
【Oracle移行到Sqlserver完美解决案】②内存溢出时查看SQL