[zt] 利用 SQL Server 中的 Linked Server 執行 Oracle 中之預儲函式、程式
說明
MSSQL 提供的 linked server 功能,讓我們可以連線到其所支援的異質資料庫引擎,執行各種 DML 相關的 SQL 指令。
我們可以利用這個功能,讓原先使用 MSSQL 滿足應用面需求的程式,在面對必須同時使用來自 Oracle 資料庫之資料,才能滿足的需求時,無需程式設計師自行連結到 Oracle 資料庫,即可讓設計師完成該需求之實作。
[FIXME:這樣做明顯的好處在哪裡?]
建立 Oracle linked server
關於如何在 MSSQL 中,建立連線到 Oracle 資料庫的 linked server ,其相關之步驟,我們可在 MSSQL 的線上檔案或是在網路檔案中,找到巨細靡遺的說明,在此 shortie 就不再浪費篇幅介紹,基本上包含以下兩個主要的步驟:
- 在 MSSQL 所在的機器上,安裝合適的 Oracle 使用者端程式,並設定好可以連線至目標 Oracle 資料庫的連線資訊。
- 利用 MSSQL 提供的 Enterprise Manager 管理介面或是 sp_addlinkedserver 預儲函式,建立 linked server 。
使用 Oracle linked server
建立好連線至 Oracle 的 linked server 之後,只要再注意以下幾個容易犯錯的地方,我們便可在 DML 中,輕鬆使用 Oracle 中的資料庫物件。
- Oracle 資料庫物件必須使用完整的四部式命名,即 OracleLinkedServerName..OwnerUserName.ObjectName 。
- 如果 Oracle 資料庫物件建立時,未使用 " 字元包住,使用全部大寫的 ObjectName 。
- 反之,則使用與建立時相同大小寫之 ObjectName 。
範例:
假設我們的 Oracle linked server 名稱為 OraTest ,使用者為 ERD ,物件名稱為 CODEREF 資料表,則以下的 DML SQL 指令,都可以正確的在 Query Analyzer 中執行:
SELECT * FROM OraTest..ERD.CODEREF WHERE REFID = '168'
UPDATE OraTest..ERD.CODEREF SET DESC = DESC + '168' WHERE REFID = '168'
INSERT INTO OraTest..ERD.CODEREF ( REFID, DESC, .... ) VALUES ( '538', '940', ... )
DELETE FROM OraTest..ERD.CODEREF WHERE REFID = '538'
大部分的需求都可以由這些 DML 來完成。
執行 Oracle linked server 中之預儲函式與程式
本文之標題重點就在這裡,而這也是屬於比較不容易完成的工作。
1. 首先,將 Oracle 中要開放給 MSSQL 呼叫的預儲函式,先用 Package 包裝起來:
Spec:
CREATE OR REPLACE PACKAGE pkg_MSSQL AS TYPE ReturnSerialTbl IS TABLE OF VARCHAR2 (20) /* The index is important, otherwise {resultset} doesn't work. */ INDEX BY BINARY_INTEGER; PROCEDURE pr_GetSerialNo ( ASerialType IN VARCHAR2, ASerialOwner IN VARCHAR2, ASerialNo OUT ReturnSerialTbl ); END pkg_MSSQL; /
Body:
CREATE OR REPLACE PACKAGE BODY pkg_MSSQL AS PROCEDURE pr_GetSerialNo ( ASerialType IN VARCHAR2, ASerialOwner IN VARCHAR2, ASerialNo OUT ReturnSerialTbl ) IS VSerialNo VARCHAR2 (20); BEGIN ERD.pr_GetSerialNo (ASerialType, ASerialOwner, VSerialNo); ASerialNo (1) := VSerialNo; END pr_GetSerialNo; END pkg_MSSQL; /
以上的例子,乃是將 Oracle 中的 pr_GetSerialNo 開放給 MSSQL 使用。
註:pr_GetSerialNo 是 shortie 常用的系統取號控制預儲程式。
2. 接著,從 MSSQL 利用 Dynamic SQL 呼叫 Oracle 中的預儲函式:
create table #serialtbl ( SerialNo VARCHAR(20) ) Declare @ASerialType VARCHAR(200), @ASerialOwner VARCHAR(200), @OracleCall VARCHAR(8000), @RetVal VARCHAR(20) SET @ASerialType = 'ID' SET @ASerialOwner = 'BB_BloodOrderId' SET @OracleCall = 'INSERT INTO #serialtbl ' SET @OracleCall = ' SELECT * ' SET @OracleCall = ' FROM OPENQUERY(MYORACLE , ''{CALL ERD.pkg_mssql.pr_getserialno( ' SET @OracleCall = @OracleCall + ''''''+ @ASerialType + '''''' SET @OracleCall = @OracleCall + ',' + '''''' + @ASerialOwner + '''''' SET @OracleCall = @OracleCall + ',{RESULTSET 25, ASerialNo})}'')' PRINT @ORACLECALL EXEC (@OracleCall) SELECT @RetVal = SerialNo FROM #SerialTbl DROP TABLE #SerialTbl PRINT @RetVal執行結果
INSERT INTO #serialtbl SELECT * FROM OPENQUERY(oratest_erd , '{CALL ERD.pkg_mssql.pr_getserialno(''ID'',''BB_BloodOrderId'',{RESULTSET 25, ASerialNo})}' ) (1 row(s) affected) O000000016
結果顯示執行成功,傳回的序號值為 '0000000016' 。
結論
本文說明在 Mircrosoft SQL Server 中,透過 Linked Server 連線至 Oracle ,然後呼叫 Oracle 中的 Stored Procedure/Function 。基本上,對 shortie 個人而言,知道這個做法純粹是滿足個人「知性」的需求,真正面臨到這個問題時, shortie 應該會使用其他的解決方案,因為大部分 shortie 碰到的 DBA 都會要求自己管理的 DBMS 要「守身如玉」,與其跟這些不入流的 DBA 去 Fight ,還不如繞開他們,山不轉路轉,路不轉人轉!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-605855/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL server儲存過程函式SQLServer儲存過程函式
- SQL Server中row_number函式的常見用法SQLServer函式
- SQL Server 2016 函式:CASTSQLServer函式AST
- SQL Server常用函式整理SQLServer函式
- 關於SQL Server中索引使用及維護簡介(zt)SQLServer索引
- SQL Server 2005效能調整一(zt)SQLServer
- SQL Server 2005效能調整二(zt)SQLServer
- SQL Server資料庫中Substring函式的用法例項詳解SQLServer資料庫函式
- 【SQL Server】常見系統函式SQLServer函式
- SQL Server 2008中Analysis Services的新特性——深入SQL Server 2008SQLServer
- SQL Server 連結伺服器(Linked Servers)SQLServer伺服器
- SQL Server 2008中的行壓縮(上)JUSQLServer
- 監控 SQL Server 的執行狀況SQLServer
- SQL Server 中的 ACID 屬性SQLServer
- Ms Sql Server查詢儲存過程中的內容SQLServer儲存過程
- SQL Server中GROUP BY(連結)SQLServer
- Microsoft SQL Server 2005中查詢優化器使用的統計資訊二(zt)ROSSQLServer優化
- Microsoft SQL Server 2005中查詢優化器使用的統計資訊一(zt)ROSSQLServer優化
- Microsoft SQL Server 2005中查詢優化器使用的統計資訊三(zt)ROSSQLServer優化
- SQL Server 查詢歷史執行的SQL語句SQLServer
- SQL 獲取SQL Server中兩個日期之間的所有日期SQLServer
- SQL Server 中的一些概念SQLServer
- SQL Server中的版本號如何理解SQLServer
- sql server 資料型別轉換函式SQLServer資料型別函式
- cmd命令列下用命令執行SQL指令碼到SQL Server資料庫中命令列SQL指令碼Server資料庫
- Sqlserver 如何truncate linked server的表SQLServer
- sql server中巢狀事務*SQLServer巢狀
- 查詢SQL Server的歷史執行記錄SQLServer
- .sql檔案匯入到sql server中SQLServer
- SQL Server中Table字典資料的查詢SQL示例程式碼SQLServer
- SQL Server建立使用者函式與應用SQLServer函式
- SQL Server中的日期和時間:DATEADD()SQLServer
- 淺談SQL Server中的快照問題SQLServer
- 關於SQL Server中儲存過程在C#中呼叫的簡單示例SQLServer儲存過程C#
- Postgresql Linked server遠端伺服器取資料的執行計劃原理SQLServer伺服器
- Q&A:在SQL Server 2005中編寫儲存過程RVSQLServer儲存過程
- 透過空間佔用和執行計劃瞭解SQL Server的行儲存索引SQLServer索引
- sqlserver建立linked server到redshift的方法SQLServer
- MySql/Oracle和SQL Server的分頁查MySqlOracleServer