一、建立sqlserver連結服務(sqlserver連結oracle)
首先sqlserver 連結oracle可以通過兩個通路接口:
“MSDAORA” 和“OraOLEDB.Oracle”
1、“MSDAORA”通路接口是由Microsoft OLE DB Provider for Oracle提供的,這裡建議不使用此接口進行連結。通過該通路接口建立的連結伺服器在進行查詢oracle表(帶資料類型CLOB、BLOB字段)時會報這個錯誤
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yM0QDM5MjN0UTL0IzMwITMxUTMyIjMxgTMwITL0MDN1MzLcJTM4EDMy8CX0MDN1MzLcd2bsJ2Lc12bj5ycn9Gbi52YugTMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
“連結伺服器""的 OLE DB 通路接口 "MSDAORA" 傳回了消息 "發生了一個 Oracle 錯誤,但無法從 Oracle 中檢索錯誤資訊。"。
連結伺服器""的 OLE DB 通路接口 "MSDAORA" 傳回了消息 "資料類型不被支援。"。
消息
7321,級别 16,狀态 2,第 1 行
準備對連結伺服器 "" 的 OLE DB 通路接口 "MSDAORA" 執行查詢"select * from
SYS_MESSAGE"時出錯。”
連結伺服器
"LINK2ORACLE" 的 OLE DB 通路接口 "MSDAORA" 為列提供的中繼資料不一緻。對象
""CMCC"."OS2_GIS_CELL"" 的列 "ISOPENED" (編譯時序号為 20)在編譯時有 130 的 "DBTYPE",但在運作時有錯。
2、“OraOLEDB.Oracle” 通路接口是由oracle 的Oracle Probider for OLE DB 驅動提供的。它解決了兩個資料庫類型不一緻的的問題。而且如果需要使用分布式事務,必須使用它來建立連結伺服器。後文會有詳細介紹。
在建立之前,在SQLSERVER中,連結伺服器->通路接口->OraOLEDB.Oracle->右鍵屬性,選中 "Allow
inprocess" (中文為:允許程序内)
這一步是使我們選擇的OraOLEDB.Oracle接口打開執行操作。如未設定會報如下錯誤:
“無法初始化連結伺服器 "null" 的 OLE DB 通路接口 "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 * FROM OraclePolice..TESTDB.TABLE_TEST
(連結伺服器别名..Oracle名.oracle表,注意使用大寫)
這種方式可以進行操作,優點是使用簡單,一目了然,而缺點是性能太差,查詢大資料量表很慢。效率太差。
2、SELECT * FROM openquery(OraclePolice,'SELECT * FROM TABLE_TEST')
經試驗,這種查詢方式速度幾乎和在Oralce中一樣快。并且我們可以将openquery() 當做表來用。例如
insert into openquery(OraclePolice,'SELECT * FROM TABLE_TEST')
values();--向oracle資料表插入資料
SELECT * FROM openquery(OraclePolice,'SELECT * FROM TABLE_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連結伺服器實作分布式事務
許許多多的同行就是在這一步中躺下的,因為這一步配置繁瑣,同時和sqlserver、oracle資料庫版本,甚至是作業系統版本等都有關,驅除睡意,和我一步步來進行配置吧。
1、首先必須安裝好
Oracle Services For Microsoft Transaction 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設定。
打開"管理工具--元件服務",依次打開"元件服務--計算機",在"我的電腦"上點選右鍵。在MSDTC頁籤中,點選"安全配置"按鈕,在安全配置視窗中做如下設定:
-->選中"網絡DTC通路";
-->在用戶端管理中選中"允許遠端用戶端""允許遠端管理";
-->在事務管理通訊中選"允許入站""允許出站""不要求進行驗證";
-->保證DTC登陸賬戶為:NT Authority\NetworkService ;
4、雙方啟動MSDTC服務
MSDTC服務提供分布式事務服務,如果要在資料庫中使用分布式事務,必須
在參與的雙方伺服器啟動MSDTC(Distributed Transaction Coordinator)服務。
5、打開雙方135端口
MSDTC服務依賴于RPC(Remote Procedure Call (RPC))服務,RPC使用135端口,保證RPC服務啟動,如果伺服器有防火牆,保證135端口不被防火牆擋住。
6、在事務開始前加入set xact_abort ON語句
對于大多數 OLE DB 提供程式(包括 SQL Server),必須将隐式或顯示事務中的資料修改語句中的 XACT_ABORT
設定為 ON。唯一不需要該選項的情況是在提供程式支援嵌套事務時。
7、伺服器名解析
在建立連結伺服器時@server或者@datasrc設定為sql server伺服器名時,需要做名稱解析,就是把伺服器名解析為ip位址。
在"C:\WINDOWS\system32\drivers\etc\hosts"檔案中增加一條記錄:
xxx.xxx.xxx.xxx 伺服器名
8、遠端伺服器上的名稱解析
分布式事務的參與伺服器是需要互相通路的,發起查詢的伺服器要根據機
器名或ip查找遠端伺服器的,同樣遠端伺服器也要查找發起伺服器,遠端伺服器通過發起伺服器的機器名查找伺服器,是以要保證遠端伺服器能夠通過發起伺服器的機器名通路到發起伺服器。一般的,兩個伺服器在同一網段機器名能就行很好的解析,但是也不保證都能很好的解析,是以比較保險的做法是:
在遠端伺服器的在"C:\WINDOWS\system32\drivers\etc\hosts"檔案中增加一條記錄:
xxx.xxx.xxx.xxx 發起伺服器名
通過以上的一些列操作應該差不多了,這期間的操作你會抓狂,時而崩潰,時而暴走,筆者唯一的建議就是:将試驗、探索堅持到底,因為筆者已經證明SQLSERVER通過連結伺服器到oracle能夠使用分布式事務。
1 -- 分布式事務測試
2 set xact_abort ON
3 begin tran
4 insert into openquery(OraclePolice,'SELECT * FROM ALINK_SERVER_TEST ') values('456000','TESTtest','');
5
6 if @@ERROR <>0
7 rollback tran;
8 else
9 commit TRAN;
10 -- 語句執行成功