环境介绍:
有2个DB,一个SID是TEST1,一个SID是TEST2,因为业务关系,用户compard下的表,每隔固定的时间都需要同步一次,需要同步的表都有如下特点:
1.表上面都有一个主键或者唯一性索引。
2.与表相关的sequence以<表名>_seq命名,相关的栏位以ID命名。
我们可以把需要更新的表按照情况分类:
1.有外键的表的同步
2.同步的表中栏位与某个Sequence相关联
3.既满足1,又满足2
4.不含1,2,3的其他表
同步可以按照如下步骤:
一. 先产生同步的SQL,并给定执行的优先顺序来解决父子关系的同步
1.建立dblink,SQL如下:
create database link connect to compard identified by <pwd> using 'TEST2_DL';
2.对于情况4,可以使用如下SQL来同步:
找出表上有主键/唯一性索引相关的栏位,且不包含在特殊情况中,用如下SQL同步,并给定优先级为3:
insert into <Table_Name>
select * from <Table_Name>@TEST2_DL where <栏位列表> not in
(select <栏位列表> from <Table_Name>)
3.对于特殊情况1,可以使用如下SQL:
alter table <CH_Table_Name> disable constraint <外键名>;--该SQL的优先级为3
然后使用步骤2的SQL进行同步,SQL优先级为2。
最后执行alter table <CH_Table_Name> enable constraint <外键名>;--该SQL的优先级为1
4.如果有特殊情况2,可以用如下SQL进行同步,并给定优先级为3
<N所有栏位列表>:=replace(<所有栏位列表>,ID,<Table_Name>_Seq.nextval);
insert into <Table_Name>
select <N所有栏位列表>:= from <Table_Name>@TEST2_DL where <栏位列表> not in
(select <N栏位列表> from <Table_Name>);
5.如果有特殊情况3,这个情况比较复杂,需要更多的判断。
在更新的表为父表时,根据父子关系的view,需要提前产生2条SQL:
update <CH_Table_Name> set <CH_F栏位>=新值 where <CH_F栏位>=旧值 SQL的优先级为3,
然后使用步骤2的SQL进行同步,优先级为4,注意这个优先级最高。
父子关系的View在数据字典表中很容易建立,此处略去。
二. 直接将SQL排序执行即可
有兴趣的同学可以将排序后SQL按照功能列出来即可知道这个同步思路。如果把上面的思路写成代码写到button_click事件中即可实现数据库的一键同步。
附上由以上思路做的软件:
文档管理系统 :
使用Delphi+DBExpress+Oracle10GR2,文档导入/导出主要用了BLOB字段的相关操作
设想的环境为该系统的数据库放在公司,技术员可以将数据库拷贝一份安装到虚拟机中,出差时发现某些比较好的文档,就导入到数据库中保存起来。回到公司可以使用一键功能将你虚拟机中的文档同步到公司的数据库中。