异构数据库数据同步(从Progress到MySQL)

一直想写点东西,但却迟迟没有开始,今天无意中回到ERP100这个网站,发现有了QAD的专区,于是,一时热血沸腾,写了点东西,就借此机会将内容也发到这里吧,呵呵。

 

其实内容都是本人写的,不过为了图方便,在ERP100中写完了,然后直接Copy到这里,偷了点懒,呵呵。

以下是正文,在ERP100中的地址是

http://bbs.erp100.com/forum.php?mod=viewthread&tid=74269&page=1&extra=#pid438182

 

由于小弟接触QAD也只有短短几年时间,目前也只是刚刚入门的菜鸟级别,希望借此机会与熟悉QAD软件的前辈一起交流,呵呵。

 

注:欢迎大家转载,但请注明出处,谢谢http://blog.csdn.net/xinghun61/archive/2010/05/27/5629293.aspx

 

项目名称:
异构数据库数据同步(从Progress到MySQL)

背景介绍:
我现在公司使用的QAD版本很老,是85g的,于是,要升级到eb2.1,但由于有很多水晶报表是直接连到QAD后台取数的,而eb2.1对连接数限制在1个,因此,公司决定将QAD的数据同步导入到MySQL数据库中,这样,只要将水晶报表的连接重新指向MySQL,就可以正常使用了。

实现思路:
要实现实时同步,最直接的就是触发器了,通过在触发器中分析各字段的值,生成SQL语句,并存入文本文件中,然后,定期调用一段Java程序,读取文本中的SQL语句,将数据插入MySQL数据库中。
注:当时在项目分析阶段,实际还有1套方案,也是通过触发器记录被修改的数据,然后写入一个自定义表的Raw字段,然后,定时执行一段Progress程序,将修改写入到MySQL中,但由于这个方案需要多占用一个Licence,因此,最终被放弃。

实现方法:
1. 设置Trigger
进入Data Dictionary(数据字典),点 Edit -> Modify Table,在弹出的窗口中输入要建Trigger的表名,例如 pt_mstr,然后,在之后的窗口中,在最下面的按钮中可以找到 Trigger 的按钮,进去之后就到了Trigger的设置界面了,这里我们主要在 Write 和 Delete 上面设置(其实,QAD的参考手册上好像是推荐的Replication-Write 和 Replication-Delete,但当时测试的时候好像有点问题,因此,没有使用。另外,Create不用管,因为,触发了Create之后一定会触发Write的),在第一个栏位填入Trigger要执行的程序(一般以.t结尾),将后面的CRC检验设置为no(否则,程序在执行时会报错),设置完后点F4退出,并在弹出的窗口中点击保存,这样,Trigger就设好了。

2. 编写Trigger代码
先看下面的代码:
TRIGGER PROCEDURE FOR WRITE OF PT_MSTR OLD BUFFER OLD_PT_MSTR./*修改数据时的Trigger*/
TRIGGER PROCEDURE FOR DELETE OF PT_MSTR./*删除数据时的Trigger*/
如果Trigger设置OK,则.t文件最上面就会有上面的这行代码(其分别与 Write 和 Delete 对应),其表示当前被处理的这行记录,以第1行代码为例,PT_MSTR表示修改后pt_mstr中存的数据,而OLD_PT_MSTR表示在修改前pt_mstr中存的数据,后面要谈到的所有分析工作,都是针对这些数据进行的。

3. 系统表的结构
记得当时为了分析各字段的值,在这里花了不少的时间,主要是没有系统表的详细资料,呵呵。
_File:
主要用到_File-Name、_Prime-Index的值
_Field:
主要用到_File-Recid、_Extent、_Field-Name、_Data-Type、_Order的值

两个系统表的连接方式如下:
FOR EACH _File NO-LOCK WHERE _File._File-Name = "PT_MSTR",
    EACH _Field NO-LOCK WHERE RECID(_File) = _Field._File-Recid
    BREAK BY _Field._Order:
    ......
END.

注:其实后面还会用到_Index-Field这个存储索引的表,这里就不详细讲了。

4. 如何提取各字段的值
有2种方法:
方法1,通过RAW-TRANSFER将数据存入Raw类型的变量中,然后,通过GET-BYTE来分析每个字节的含义,但这种方式很多都是基于猜测,没有参考资料对Raw类型数据的结构进行说明,因此,具体方法就不讲了。
方法2,利用EXPORT函数将数据导出到文本文件,然后,通过分析文本文件中的数据,来提取各字段的值,代码如下:
EXPORT DELIMITER "|" PT_MSTR.
由于我们一般不会输入“|”这个字符,因此,这里用这个字符作为字段间的分隔符。

5. 注意事项
a. 用EXPORT导出的数据会以_Field._Order的顺序进行排列,这也就是我们在第3步中进行排序的原因。
b. 对于数组类型的字段,在系统表中只会表示成一条记录,但在EXPORT中却会将每个值用“|”(我们在EXPORT代码中定义的分隔符)连接在一起进行输出,因此,需要辅助使用_Field._Extent这个字段。
c. 由于事务处理的影响,这套方案其实是有个很严重的Bug,就是F4问题,也就是说如果用户数据输入一半就按F4退出了,那么这套方案也会将取消前的数据导入到MySQL中,导致数据差异(其实,在前面实现思路的注释部分所提到的第2套方案,理论上应该可以解决这个问题)。

 

 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭