qiaqia-liu

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

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

 

分类:

技术点:

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-11-05
  • 2022-02-04
  • 2022-03-01
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-12
  • 2021-05-06
  • 2021-08-14
  • 2021-11-06
  • 2021-10-18
相关资源
相似解决方案