本文转自:
http://blog.sina.com.cn/s/blog_517cae3c01017n2s.html
一、创建sqlserver链接服务(sqlserver链接oracle)
“MSDAORA” 和“OraOLEDB.Oracle”
1、“MSDAORA”访问接口是由Microsoft OLE DB Provider forOracle提供的,这里建议不使用此接口进行链接。通过该访问接口建立的链接服务器在进行查询oracle表(带数据类型CLOB、BLOB字段)时会报这个错误
“
链接服务器""的 OLE DB 访问接口 "MSDAORA" 返回了消息 "发生了一个 Oracle 错误,但无法从 Oracle中检索错误信息。"。
链接服务器""的 OLE DB 访问接口 "MSDAORA" 返回了消息 "数据类型不被支持。"。
消息 7321,级别 16,状态 2,第 1 行
准备对链接服务器 "" 的 OLE DB 访问接口 "MSDAORA" 执行查询"select * fromSYS_MESSAGE"时出错。”
链接服务器 "LINK2ORACLE" 的 OLE DB 访问接口"MSDAORA" 为列提供的元数据不一致。对象 ""CMCC"."OS2_GIS_CELL"" 的列 "ISOPENED"(编译时序号为 20)在编译时有 130 的 "DBTYPE",但在运行时有错。
2、“OraOLEDB.Oracle” 访问接口是由oracle 的Oracle Probiderfor OLE DB驱动提供的。它解决了两个数据库类型不一致的的问题。而且如果需要使用分布式事务,必须使用它来创建链接服务器。后文会有详细介绍。
在创建之前,在SQLSERVER中,链接服务器->访问接口->OraOLEDB.Oracle->右键属性,选中"Allow inprocess"(中文为:允许进程内)
这一步是使我们选择的OraOLEDB.Oracle接口打开执行操作。如未设置会报如下错误:
使用Oracle Probider for OLE DB驱动创建sqlserver链接服务器的代码:
1: --建立数据库链接服务器
2: EXEC sp_addlinkedserver
3: @server =N'OraclePolice', --要创建的链接服务器别名
4: @srvproduct=N'Oracle', --产品名称
5: @provider=N'OraOLEDB.Oracle', --OLE DB 驱动名称
6: @datasrc=N'ORCL' --数据源oracle"ora10g"network"admin"tnsnames.ora查看
7:
8: EXEC sp_addlinkedsrvlogin
9: 'OraclePolice', --已建立的链接服务器名
10: 'false', -- 固定 */
11: NULL, --为每个登陆SQL SERVER的用户使用此链接服务器,则写用户名*/
12: 'TESTDB', --帐号(oracle)
13: 'TESTDB123' --密码
14:
15: exec sp_serveroption 'OraclePolice','rpc out','true'
16: exec sp_serveroption 'OraclePolice','rpc','true'
17: --这两个是打开rpc,rpc out的,默认为False,打开后可以支持远程更改分布式事务。(如有分布式事务操作必须要设置)
这样我们就建好了链接服务器,已经可以通过它对oracle数据库进行查询,这里有两种查询方式。
1、SELECT * FROMOraclePolice..TESTDB.TABLE_TEST
(链接服务器别名..Oracle名.oracle表,注意使用大写)
这种方式可以进行操作,优点是使用简单,一目了然,而缺点是性能太差,查询大数据量表很慢。效率太差。
2、SELECT * FROMopenquery(OraclePolice,'SELECT *FROM
经试验,这种查询方式速度几乎和在Oralce中一样快。并且我们可以将openquery()当做表来用。例如
insert into openquery(OraclePolice,'SELECT * FROMTABLE_TEST')
values();--向oracle数据表插入数据
SELECT * FROM openquery(OraclePolice,'SELECT * FROMTABLE_TEST')
where TEST_NAME=''(TEST_NAME为TABLE_TEST表中的字段)
故推荐这种查询方式。
二、通过sqlserver链接服务器调用oracle存储过程
在oracle里数据库里写了一个测试存储过程,需要一个传入参数和传出参数。
下面是创建和调用这个存储过程的代码:
1: -- oracle 中创建存储过程
2: create or replace procedure A_TEST_NQ
3: (
4: namecode varchar2,
5: namevalue out varchar2
6: )
7: is
8: c varchar2(200);
9: begin
10: c:='';
11: select NAME_VALUE into c FROM ALINK_SERVER_TEST WHERE NAME_CODE=namecode;
12: namevalue:=c;
13: end;
14:
15: -- ----------------------------------------------
16: -- 邪恶的分割线
17: -- ----------------------------------------------
18:
19: -- sqlserver 中调用存储过程
20: declare @namecode varchar(200)-- 传入参数
21: declare @namevalue varchar(5000)-- 传出参数
22:
23: set @namecode='01'
24: -- 调用存储过程
25: EXEC('begin A_TEST_PRC(?,?);end;',@namecode,@namevalue output) at OraclePolice
这里要注意传出参数,一定要加上Output,不然会报错。
“链接服务器"OraclePolice"的 OLE DB 访问接口 "OraOLEDB.Oracle" 返回了消息"ORA-06502: PL/SQL: 数字或值错误 :
ORA-06512: 在 "SACON.A_TEST_NQ", line 11
ORA-06512: 在 line 1"。
消息 7215,级别 17,状态 1,第 6 行
无法在远程服务器 'OraclePolice' 上执行语句。”
三、通过sqlserver链接服务器实现分布式事务
Oracle Services For MicrosoftTransaction Server
(版本与你的oracle版本一致)它是ODAC中的一部分,因为oracle本身是不支持分布式事务的,通过这个驱动开放与微软的事务服务。 我想绝大多数人配置好MSDTC并解析好名称后仍会报“无法启动分布式服务”就是因为这个驱动没装。
消息 7391,级别 16,状态 2,第 5 行
无法执行该操作,因为链接服务器 "oracletest" 的 OLE DB 访问接口 "OraOLEDB.Oracle"无法启动分布式事务。
2、必须用Oracle Probider for OLE DB驱动提供的OraOLEDB.Oracle访问接口来创建链接服务。(这个可能是因为microsoft提供的访问接口并不存在oracle事务机制,所以只能通过oracle提供的访问接口)
3、MSDTC设置。
4、双方启动MSDTC服务
在参与的双方服务器启动MSDTC(Distributed TransactionCoordinator)服务。
5、打开双方135端口
6、在事务开始前加入set xact_abort ON语句
7、服务器名解析
在"C:WINDOWSsystem32driverset
8、远程服务器上的名称解析
在远程服务器的在"C:WINDOWSsystem32driverset
通过以上的一些列操作应该差不多了,这期间的操作你会抓狂,时而崩溃,时而暴走,笔者唯一的建议就是:将试验、探索坚持到底,因为笔者已经证实SQLSERVER通过链接服务器到oracle能够使用分布式事务。
1: -- 分布式事务测试
2: set xact_abort ON
3: begin tran
4:
5: insert into openquery(OraclePolice,'SELECT * FROM ALINK_SERVER_TEST ') values ('456000','TESTtest','');
6:
7: if @@ERROR <>0
8:
9: rollback tran;
10: else
11:
12: commit TRAN;
13: -- 语句执行成功
本人通过以下网址获得灵感,感谢原作者。
http://blog.youkuaiyun.com/akuoma/archive/2010/01/29/5269496.aspx
http://mlj04.blog.163.com/blog/static/5448108220101855248191/
http://www.chinaitpower.com/A/2004-06-13/83416.html
http://www.cnblogs.com/huanghai223/archive/2010/12/28/1919073.html