深度数据对接 链接服务器 数据传输

1.场景介绍

公司最近接了个客户,客户自有ERP技术C++ oracle,公司提供MES\APS等系统,因为客户很有钱,所以客户买了很好的服务器,因为有个很好的服务器,所以客户就只有一种类型的数据源就是oracle.

又因为数据源上有很重要的客户资料和营收信息,客户方经理以物理隔离为由让我们离他们的数据源远一点.只能通过接口访问,这个可以理解.然后我说是用webservice还是用webAPI,因为要深度对接

正考虑这么做要被搞死以后,客户技术经理说,这些太麻烦我们用链接服务器.我开放增删改查给你们. (゚Д゚#)  (゚Д゚#)  (゚Д゚#)  (゚Д゚#) .嗯! 果然离的很远.

因为是ERP和MES对接,对于订单\BOM\人员\工艺\运行参数\叠构图\工序\排班\产能等模块都需要深度对接,要承接过来,并且客户做的修改必须及时反馈到各个系统上.关键是工艺和运行参数,如果这些在

ERP上修改了必须及时反馈到MES上,否则生产的产品有可能直接就报废了.本来纠结的事情随着使用链接服务器直接排除.

2.链接服务器搭建

--建立链接服务器
exec sp_addlinkedserver 'MY_LINK_SERVER','SQLSERVER','SQLOLEDB','192.168.1.1'
exec sp_addlinkedsrvlogin 'MY_LINK_SERVER','false',null,'sa','123'
EXEC sp_serveroption @server='MY_LINK_SERVER' , @optname= 'rpc', @optvalue ='TRUE'
EXEC sp_serveroption @server='MY_LINK_SERVER' , @optname= 'rpc out', @optvalue='TRUE'
--删除链接服务器
exec sp_dropserver 'MY_LINK_SERVER','droplogins'
--查询所有可以使用的服务器
exec sp_helpserver

开启了rpc rpc out可以直接调用存储过程了,我觉得一些非涉及钱的业务,使用事务是给自己添堵,因为用事务占用表\占用锁比较多,如果是多人开发使用相同的模块,因为沟通和个人业务使用的不一致

死锁漫天飞,即造成了服务器资源的浪费又造成逻辑修改麻烦,我们项目组一般是使用业务数据验证来避免部分提交.就是提交完成后,检查下数据如果不符删了重来.所以我们在本地都很少用事务,更不要

说用远程分布式事务了.靠人不如靠自己.大家用业务检查的方式避免数据缺失.

3.使用远程数据

(1) 对于同是SQLserver 的数据库,可以直接使用 

select * from MY_LINK_SERVER.TestDB.dbo.TestTable where file = 1

 前面加个远程服务名,跟使用本地数据库一样,增删改查用的一样, rpc \  rpc out  两边配置相同,可以相互调用存储过程.这个使用起来没啥好讲的都一样.跟本地库操作差不多.

(2) 对于Oracle数据库使用起来没有那么方便,因为客户不给数据库名和各种信息,所以只能使用另外一种使用方式

select * from  OPENQUERY(LINK_ERP,'SELECT * FROM  TestTable')
or
select * from LINK_ERP.. S00.TESTTABLE

 

数据库内容访问对于  OPENQUERY(LINK_ERP,'SELECT * FROM TestDB') 是一个表集合 .类似一个临时的表集合.对于这个表过滤和使用跟其他内容一样,可使用查询排序功能类型这样

select * from  OPENQUERY(LINK_ERP,'SELECT * FROM TestTable ') where file=1 order by file desc

(3) 对于这样使用方法,如果是表的体积比较小,或者数据比较少没有问题,如果表的数据比较多. 这种方式就有问题, 我们是testTable表中的所有数据从远程数据库中取完然后再本地建立的临时集合

然后过滤本地的临时数据然后输出结果.受远程表的影响\受网络传输的影响\受本地数据库性能影响,这样太不OK了.能不能跟使用本地表一样是用远程ORACLE数据库的表.对于这个问题,目前没有

良好的方法,我们试着把where 条件写到里面.

-- 所有条件入查询
select * from  OPENQUERY(LINK_ERP,'SELECT * FROM  TestTable where file = 1  order by file desc ');

--所有条件入查询字符串
select * from  OPENQUERY(LINK_ERP,'SELECT * FROM  TestTable where fileName = ''test''  order by file desc ');

可以使用恒定值入表达式当成带条件的筛选了.字符串类型的需要添加转义符对传入的字符串进行转义,比如要表达出'test',在里面就得使用''test''这样的结构来表达出正确的.

这样减少返回的信息量,减少带宽的压力,减少本地缓存临时表的占用量.

(4) 很多同步数据和验证变量的时候往往并不使用常量来带入公式,需要使用变量来查询出来值.这时就需要根据对应的操作来实现这一操作.

declare @P_Control1 varchar(200)
declare @P_Control2 int
declare @execSQL varchar(2000)
set @P_Control1  = 'justtest'
set @P_Control2 = 2
-- 所有条件入查询
set @execSQL = 'select * from  OPENQUERY(LINK_ERP,''SELECT * FROM  TestTable where file = '+@P_Control2+'  order by file desc '');'
exec (@execSQL);
-------------------------------------------------------------------------
--所有条件入查询字符串
set @execSQL = 'select * from  OPENQUERY(LINK_ERP,''SELECT * FROM  TestTable where fileName = '''''+@P_Control1 +'''''  order by file desc '')';
exec(@execSQL);
-------------------------------------------------------------------------
--中转临时表
set @execSQL = 'insert into localTestTable select * from  OPENQUERY(LINK_ERP,''SELECT * FROM  TestTable where fileName = '''''+@P_Control1 +'''''  order by file desc '')';
exec(@execSQL);
select * from localTestTable

 

分别是变量int\字符串\中转到本地临时表.都可以,这样使用变量特定的抓取.最后一个写字符串的反正就是加一层多家一个字符串.写到吐血.老实说目前只发现这种,如果谁有其他好的对接变量的可以分享一下.

这样写很考验耐心,而且容易出错.不过数据对接这样还是这样搞吧.

 

posted on 2019-04-16 20:48  black2bi  阅读(489)  评论(0编辑  收藏  举报