簡介
WebSphere Federation Server(以前稱為 WebSphere Information Integrator)使用 “昵稱” 對遠程數據源上的數據集進行聯邦訪問。昵稱作為遠程表或類似於表的數據集的本地代理。
聯邦過程與昵稱的相似之處是它們允許訪問遠程存儲過程。它們似乎應該被稱為 “存儲過程昵稱”;但是,因為昵稱被看作具有表性質的對象,而不是過程,所以不這麼稱呼。在大多數情況下,創建和調用聯邦過程是一個非常簡單的過程。例如,假設希望調用遠程存儲過程 rem_proc 而且已經有一個服務器 s。以下兩個 SQL 語句創建一個聯邦過程 my_fed_proc 並用一個輸入參數和一個輸出參數調用它:
CREATE PROCEDURE my_fed_proc SOURCE rem_schema.rem_proc FOR SERVER s
CALL my_fed_proc(3,?)
當然,聯邦過程不只是如此,以下各節會為更高級的使用場景提供有用的信息:
為什麼使用聯邦過程? —— 描述使用這種對 SQL 語句進行聯邦的新方式的好處。
限制 —— 列出應用程序設計人員需要注意的限制。
聯邦過程的外部 —— 主要關注聯邦過程的外部。
示例 —— 提供示例。
判斷問題 —— 為排除問題提供一些有用的提示。
為什麼使用聯邦過程?
存儲過程的好處
存儲過程是為了解決分布式計算的問題而發明的。它們允許客戶機通過只發送一個消息在數據庫服務器上執行多個操作。還有一些重要的副作用:它們允許 DBA 對業務邏輯進行封裝、確保數據一致性以及促進代碼重用。在許多情況下,這些副作用是使用存儲過程的主要原因。換句話說,存儲過程提供以下關鍵好處:
性能 —— 存儲過程的性能提高主要來自於減少客戶機(常常在遠程計算機上)和數據庫服務器之間發送的消息數量。因此,這些提高常常在過程中有多個 SQL 語句時表現出來。
封裝 —— 存儲過程是實現最低的業務邏輯層的好方法。
安全性 —— 因為 SQL 允許控制表、視圖和過程等對象,DBA 可以通過禁止直接訪問底層表並迫使客戶機使用過程來執行特定的業務事務,從而將業務邏輯封裝起來。這樣就更容易確保安全性和數據一致性。
SQL 語義 —— 常規的 SQL 操作和存儲過程調用共享同一個客戶機庫以及 SQL 接口的事務、錯誤和安全模型。無論是與對 SQL 表的訪問一起使用,還是單獨使用,這都可以大大簡化應用程序開發。
從存儲過程到聯邦過程
到目前為止,本文討論的都是存儲過程。如果只需要用您熟悉的 SQL 方言訪問來自一個數據源的表和過程,那麼實際上不需要聯邦過程。但是,存儲過程和其他 SQL 對象常常存在於不同的數據源上,而且可能需要使用不同的 SQL 方言。這會使應用程序變得非常復雜。為了解決這個問題,WebSphere Federation Server V9.1 中出現了一個新特性:聯邦過程。聯邦過程結合了上面討論的存儲過程優點和下面這些聯邦優點:
位置無關性 —— 應用程序不需要知道各個對象的位置,可以在單一數據庫連接、單一事務甚至單一 SQL 語句中使用來自多個數據源的對象(昵稱、過程)。
透明性 —— 調用聯邦過程與調用本地 DB2 過程相似,都通過 DB2 客戶機接口使用共同的 SQL 方言和數據類型集合,而且采用同樣的方式來處理結果集。DB2 模型包括數據庫連接,它提供了分布式事務而且避免了對每個過程調用進行身份驗證。
異構性 —— 聯邦過程可以調用不同數據源上的過程。在當前版本中,選擇的范圍只限於 Sybase 和 Oracle 過程(本文的 限制 一節中將詳細討論當前的限制)。在許多情況下,聯邦服務器需要處理這些數據源實現的差異。這對於結果集的處理尤其重要,因為結果集的處理在不同數據源上有本質差異。
自治性 —— 聯邦過程不需要在數據源上進行設置、安裝或定制。可以按原樣使用數據源上的現有過程。
聯邦過程真的是必要的嗎?
上面討論的是聯邦過程的好處。本節考查一些替代方案,討論它們如何適應其他環境,比如 Web 服務。假設一個應用程序需要在一個工作單元中調用不同數據源上的兩個存儲過程。我們根據應用程序是否具有以下情況來比較幾個場景:
使用客戶機庫。
管理分布式事務。
管理分布式安全性。
了解不同數據源上對象的位置。
了解語義和數據類型方面的差異。
第一個選項是使用數據庫客戶機(比如 Java Database Connectivity[JDBC])來直接訪問每個數據源,而不使用聯邦過程。盡管對於簡單的應用程序這是非常有用的方法,但是應用程序需要自己處理上面提到的 5 個方面。對於 DB2 以及 WebSphere Federation Server,客戶機接口的選擇范圍包括嵌入式 SQL(不支持存儲過程的結果集)、CLI、Distributed Relational Database Architecture(DRDA)、Open Database Connectivity(ODBC)、JDBC 和 Structured Query Language for Java(SQLJ)。這些接口不允許 SQL 查詢或存儲過程同時使用多個數據源上的對象。圖 1 給出一個這樣的分布式應用程序:
異構性 —— 聯邦過程可以調用不同數據源上的過程。在當前版本中,選擇的范圍只限於 Sybase 和 Oracle 過程(本文的 限制 一節中將詳細討論當前的限制)。在許多情況下,聯邦服務器需要處理這些數據源實現的差異。這對於結果集的處理尤其重要,因為結果集的處理在不同數據源上有本質差異。
自治性 —— 聯邦過程不需要在數據源上進行設置、安裝或定制。可以按原樣使用數據源上的現有過程。
聯邦過程真的是必要的嗎?
上面討論的是聯邦過程的好處。本節考查一些替代方案,討論它們如何適應其他環境,比如 Web 服務。假設一個應用程序需要在一個工作單元中調用不同數據源上的兩個存儲過程。我們根據應用程序是否具有以下情況來比較幾個場景:
使用客戶機庫。
管理分布式事務。
管理分布式安全性。
了解不同數據源上對象的位置。
了解語義和數據類型方面的差異。
第一個選項是使用數據庫客戶機(比如 Java Database Connectivity[JDBC])來直接訪問每個數據源,而不使用聯邦過程。盡管對於簡單的應用程序這是非常有用的方法,但是應用程序需要自己處理上面提到的 5 個方面。對於 DB2 以及 WebSphere Federation Server,客戶機接口的選擇范圍包括嵌入式 SQL(不支持存儲過程的結果集)、CLI、Distributed Relational Database Architecture(DRDA)、Open Database Connectivity(ODBC)、JDBC 和 Structured Query Language for Java(SQLJ)。這些接口不允許 SQL 查詢或存儲過程同時使用多個數據源上的對象。圖 1 給出一個這樣的分布式應用程序:
圖 1. 使用客戶機接口的簡單應用程序
應用程序設計人員可能不希望使用數據庫客戶機接口。為了解決這個問題,可以使用每個數據源的 Web 服務提供者。現在,應用程序不再需要使用數據庫客戶機庫,但是仍然需要管理 上面列表 中的所有其他方面。
圖 2. 使用 Web 服務的應用程序
如果希望自動管理剛才提到的那些方面,可以使用聯邦服務器並將所有這些方面虛擬化成一個 SQL 接口。本文的其余部分將詳細討論這種方法。利用聯邦方法,就不再需要在應用程序中管理 上面列表 中的項目,但是第一項除外。
圖 3. 聯邦應用程序
如果應用程序使用 Web 服務接口而不是 SQL 客戶機庫,那麼它可以結合 Web 服務和聯邦概念的優點,通過 Web 服務訪問聯邦服務器,見 圖 4。
圖 4. 利用 Web 服務提供者的聯邦應用程序
現在,應用程序不再需要管理上面列出的任何項目了。當然,Web 服務提供的好處不只是避免使用客戶機庫。這種方式的其他變體包括使用聯邦服務器中的 Web 服務包裝器。正如前面提到的,本文的其余部分主要關注 圖 3 中的配置。
限制
在設計應用程序之前,應用程序設計人員需要了解在使用聯邦過程時的一些限制。這些限制的一部分應用於 DB2 過程或應用於聯邦,一些限制是聯邦過程所特有的:
數據源:
當前,只在以下數據源上支持聯邦過程:
Oracle
Sybase
fenced 包裝器支持:
聯邦過程不支持 fenced 包裝器。
調用聯邦過程:
從外部用戶定義函數調用的聯邦過程在聯邦服務器上必須不具有訪問級別 READS SQL DATA 或 MODIFIES SQL DATA(對聯邦語句的一般性限制)。
聯邦過程只支持 CALL RESOLUTION IMMEDIATE(CALL RESOLUTION DEFERRED 綁定選項是 DB2 中已經廢棄的特性)。
在 Oracle 中,可以定義輸出到緩沖區或標准輸出的函數。對於在這種函數上定義的聯邦過程,用戶不應該期望看到輸出(輸出可能會出現在數據源上,也可能不出現)。
數據類型支持:
聯邦過程支持昵稱所支持的所有數據類型,但是過程參數不能使用大對象(LOB)。
事務支持:
在觸發器、動態合成語句、標量、表、行函數和方法中不能調用具有訪問級別 MODIFIES SQL DATA 的聯邦過程。一旦發出 SAVEPOINT 語句,用戶就不能調用具有訪問級別 MODIFIES SQL DATA 的聯邦過程(對聯邦語句的一般性限制)。
聯邦過程所引用的遠程過程不能發出 COMMIT 或 ROLLBACK 語句。因為不能強制實施這一限制,如果遠程過程有 COMMIT 或 ROLLBACK 語句,就可能發生數據不一致(見下面的 CALL 語句的事務問題 一節)。
其他限制:
不支持 ALTER PROCEDURE。
對於 Sybase 服務器 12.0 版,所有參數都是 “輸入” 參數。因此,對於 Sybase 12.0 版數據源,不能返回輸出參數的值。這個限制對於更高的版本(比如 12.5 和 15)不存在(Sybase 12 編目限制)。
結果集:
只返回一個結果集。如果遠程過程返回多個結果集,那麼其他結果集被丟棄。
對於同時返回輸出參數和結果集的 Sybase 過程,結果集被丟棄。
返回結果集的 Sybase 過程總是返回 0 作為整數返回狀態,實際的返回狀態值被忽略。
不支持 Sybase 游標參數。不允許在客戶機操作中使用 Sybase 游標參數,因此不支持(Sybase 限制)。
不支持 REFCURSOR 類型的 Oracle 輸入參數(支持 REFCURSOR 類型的輸出參數,並映射為結果集)。
在遠程過程上不支持可更新、可持有和可滾動的游標。如果遠程過程定義了 WITH HOLD 和 SCROLLABLE 結果集,那麼游標屬性(WITH HOLD 和 SCROLLABLE)丟失,返回的結果集不是可持有或可滾動的,而且是只讀的。可持有結果集允許應用程序在隱式或顯式提交之後一直將游標打開著。可滾動結果集允許游標移動到結果集中的任意行。
聯邦過程的外部調用
正如簡介中提到的,聯邦過程提供了位置透明性。在創建聯邦過程之後,就可以像調用 DB2 過程那樣調用它們。它們遵循 DB2 過程模型並提供一個同質的接口,可以將數據源中的許多特殊特性映射到 DB2。可以使用 CREATE PROCEDURE (Sourced) 語句創建聯邦過程。在 簡介 一節中,您已經看到了一個使用必要子句的 CREATE PROCEDURE (Sourced) 語句示例。這裡討論可選的子句以及 CREATE PROCEDURE (Sourced) 語句行為的更多細節。CREATE PROCEDURE (Sourced) 語句提供下面這些功能:
在 Oracle 函數上創建過程。
返回值變成聯邦過程的第一個參數。它是名為 “DEFAULT” 的輸出參數。
支持包中的 Oracle 過程。
CREATE PROCEDURE 語句為包中的 Oracle 例程提供了特殊語法,即 SOURCE 子句中分三部分的名稱,其中中間的部分標識包。
Oracle REFCURSOR 輸出參數作為 DB2 結果集返回。
注: NUMBER OF PARAMETERS 子句中考慮這些參數,但是它們不作為聯邦過程的參數出現。
在重載的數據源過程上創建過程。
這可以用兩種方式實現:
如果兩個或更多的數據源過程具有相同的模式和過程名,但是參數數量不同,那麼可以在 CREATE PROCEDURE 語句中指定 NUMBER OF PARAMETERS。
注: 這是遠程過程的參數數量,包括 REFCURSOR 參數,但是不包括函數的返回值。創建的聯邦過程可以具有不同數量的參數。
如果多個數據源過程或函數具有同樣的名稱和參數數量,那麼需要指定 UNIQUE ID。對於 Sybase 過程,這是不必要的(也不支持)。對於 Oracle 例程,UNIQUE ID 值是 ALL_ARGUMENTS.OVERLOAD 列的(字符)值,它惟一地標識這個例程。
根據應用程序,聲明返回給客戶機/調用者的結果集。見下面的 結果集 一節。
指定過程的訪問級別、確定性、外部動作屬性。
因為聯邦過程所引用的遠程過程不由聯邦服務器進行管理,所以當過程在數據源上執行時無法強制實施選擇的級別。如果在用戶指定的訪問級別值與遠程過程在數據源上實際采用的級別之間有差異,那麼可能出現數據不一致。如果用戶指定了這些選項,但是與數據源上的選項值有沖突,那麼返回一個錯誤(SQL 1255N)。如果用戶沒有為這些選項指定任何值,那麼使用數據源上的值。如果這些選項在數據源上不可用,那麼默認值是 MODIFIES SQL DATA、NOT DETERMINISTIC 和 EXTERNAL ACTION。
結果集
存儲過程可以返回零個或更多的結果集,每個結果集由一組行組成。一個結果集中的所有行具有相同的列數量和列類型,而不同的結果集可以具有不同的列布局。不同的數據源在如何實現結果集方面有顯著的差異。
在 DB2 中,所有結果集的生成不需要將它們聲明為參數。有兩種結果集,“RETURN TO CLIENT” 和 “RETURN TO CALLER”。前一種類型繞過所有嵌套的過程,直接返回給最初的應用程序;而後一種類型只能由調用者使用。調用者可以是客戶機應用程序,也可以是另一個過程。
一般的 Sybase 結果集不聲明為參數,並具有與 DB2 中 “RETURN TO CLIENT” 結果集相似的語義。為了能夠在調用者中使用結果集,Sybase 添加了游標參數,但是這種參數只能在 Sybase 服務器中使用,而不能從 Sybase 客戶機接口(比如聯邦)使用。
在 Oracle 中,所有結果集顯式地聲明為 REFCURSOR 類型的參數。它們必須顯式傳遞給調用者和被調用者。
CREATE PROCEDURE 語句中的 WITH RETURN TO CALLER/CLIENT 子句幫助實現所需的 Sybase 和 Oracle 結果集行為。
聯邦過程參數和結果集的數據類型
在創建聯邦過程時,使用默認的轉發類型映射將遠程過程參數和結果集的列的數據類型映射為 DB2 數據類型。
對於 Oracle 中沒有精度、刻度或長度的數據類型,Oracle 數據類型被映射為具有最大長度的字符串或者 DB2 中的 DOUBLE,以便在執行 CREATE PROCEDURE 期間獲得最大的范圍。
用戶可以使用 CREATE TYPE MAPPING 語句覆蓋過程參數的默認類型映射。但是,結果集的類型映射不受用戶定義的類型映射影響。
聯邦過程編目
如果聯邦過程的簽名是未知的,那麼用戶可以使用下面列出的編目來查看簽名。下面的 “示例” 一節描述了執行編目查看的查詢。假設您知道聯邦過程的名稱和模式,SYSCAT.ROUTINEPARMS 是首先查詢的編目。可以在 示例 一節中找到一些查詢示例 。
SYSCAT.ROUTINESFEDERATED
包含關於定義的聯邦過程的信息,比如數據源名、遠程過程名、遠程模式名。
SYSCAT.ROUTINES —— 包含關於用戶定義例程(UDB 表函數、標量函數和聯邦過程)的信息。
SYSCAT.ROUTINEPARMS —— 包含關於 SYSCAT.ROUTINES 中定義的例程的例程參數信息。
SYSCAT.ROUTINEOPTIONS —— 包含關於聯邦過程選項值的信息,比如數據源名、遠程過程名、遠程模式名和遠程過程中的參數數量。在 Oracle 數據源的情況下,這個編目還包含 REFCURSOR 的數量。
SYSCAT.ROUTINEPARMOPTIONS —— 包含關於聯邦過程參數選項值的信息,比如遠程參數名和遠程參數類型名。
調用聯邦過程
使用 CALL 語句調用聯邦過程。整數返回碼映射為 GET DIAGNOSTICS 語句中的 DB2_RETURN_STATUS 變量。對於 Sybase,只在不返回結果集時接收整數返回碼。所需的特權和用戶映射與昵稱所需的相似:
用戶在數據源上需要 EXECUTE 授權和有效的用戶映射。即使在通過本地語句或過程間接調用聯邦過程時,也需要如此。
可以使用 GRANT/REVOKE (routine privileges) 語句授予聯邦過程上的特權。
刪除聯邦過程
可以使用 DROP 語句刪除聯邦過程。
刪除一個聯邦過程會從本地編目中刪除它,但是不會改變數據源上的編目。
依賴於這個過程的包會失效。
使用 DROP 語句的示例見 示例 一節。
對聯邦過程的工具支持
到目前為止,本文已經討論了聯邦過程的外部。現在,注意力轉移到對這個特性的用戶界面支持。有兩個界面:
控制中心 —— 控制中心提供以下功能:
創建和刪除聯邦過程。
授予和撤消聯邦過程上的特權。
根據遠程模式名、遠程包名和遠程過程名來發現遠程過程。
手工指定遠程過程的屬性。
DB2 Workbench —— DB2 Workbench 工具允許執行用控制中心創建的過程。用戶可以查看執行的狀態、輸出參數和結果集。
示例
您已經在 簡介 一節中見到了一個簡單的示例。以下示例演示如何處理重載的過程,以及如何在編目中查詢本地屬性。還演示如何在 CREATE PROCEDURE 語句中利用結果集語法。
股票經紀公司 XYZ 在 StockOptions 包中有以下 Oracle 存儲過程:
過程 StockInfo,輸入參數是 char 類型的用戶名;StockInfo (username IN char)。它返回一個結果集,其中包含用戶的股票持有量信息。結果集的每一行包含兩列:
給定用戶持有的一種股票的數量。
此股票的名稱。
在 Oracle 上,這個結果集常常由過程的調用者使用。
過程 StockInfo,輸入參數是帳號;StockInfo (accountNum IN integer)。帳號被設計為一個整數。它返回一個結果集,其中記錄:
給定帳號中一種股票的數量。
根據實時報價計算出的股票總市值。
此股票的名稱。
當從 Oracle 中調用這個過程時,調用者常常將結果集傳遞給客戶機。
這家股票經紀公司還定義了以下 Sybase 過程:
過程 StockQuote,輸入參數是股票名稱和日期;StockQuote(stockName IN char, transDate IN DATE)。它以輸出參數的形式返回給定股票在給定日期的報價。注意,因為 Sybase 過程允許用戶為 OUT 參數傳遞初始值,所以 DB2 將 Sybase OUT 參數作為 INOUT 參數對待。根據編寫過程的方式不同,可能需要指定輸入值,也可能不需要。