Oracle 10g 引入 UTL_DBWS 套件,封裝 JPublisher 功能,讓 PL/SQL 開發者能以簡單 API 呼叫外部 Web Services。本文以呼叫 sayHello 服務為例,完整示範環境建置、程式撰寫與測試流程。
UTL_DBWS:
dbws-callout-utility.zipdbws-callout-utility-10R2.zip$ORACLE_HOME/sqlj/lib$ORACLE_HOME/bin/loadjava -u sys/password -r -v -f -s -grant public -noverify -genmissing $ORACLE_HOME/sqlj/lib/dbwsclient.jar
註:官方文件稱 10g 內建,但實測全新安裝仍缺少此套件,需手動載入。
假設已部署 WSDL 為 https://localhost:8888/hellows/helloService?WSDL 的服務,含 sayHello 操作。
CREATE OR REPLACE FUNCTION CALL_SAYHELLO (USERNAME IN VARCHAR2)
RETURN VARCHAR2 AS
L_SERVICE UTL_DBWS.SERVICE;
L_CALL UTL_DBWS.CALL;
L_RESULT ANYDATA;
L_WSDL_URL VARCHAR2(1024) := 'https://localhost:8888/hellows/helloService?WSDL';
L_SERVICE_NAME VARCHAR2(200) := 'helloService';
L_OPERATION VARCHAR2(200) := 'sayHello';
L_INPUT_PARAMS UTL_DBWS.ANYDATA_LIST;
BEGIN
-- 建立服務與呼叫控制代碼
L_SERVICE := UTL_DBWS.CREATE_SERVICE(
WSDL_DOCUMENT_LOCATION => URIFACTORY.GETURI(L_WSDL_URL),
SERVICE_NAME => L_SERVICE_NAME
);
L_CALL := UTL_DBWS.CREATE_CALL(
SERVICE_HANDLE => L_SERVICE,
PORT_NAME => NULL,
OPERATION_NAME => L_OPERATION
);
-- 設定輸入參數並呼叫
L_INPUT_PARAMS(1) := ANYDATA.CONVERTVARCHAR2(USERNAME);
L_RESULT := UTL_DBWS.INVOKE(
CALL_HANDLE => L_CALL,
INPUT_PARAMS => L_INPUT_PARAMS
);
-- 釋放資源並回傳
UTL_DBWS.RELEASE_CALL(L_CALL);
UTL_DBWS.RELEASE_SERVICE(L_SERVICE);
RETURN ANYDATA.ACCESSVARCHAR2(L_RESULT);
EXCEPTION
WHEN OTHERS THEN
UTL_DBWS.RELEASE_CALL(L_CALL);
UTL_DBWS.RELEASE_SERVICE(L_SERVICE);
RETURN NULL;
END CALL_SAYHELLO;
SELECT CALL_SAYHELLO('World') FROM DUAL;
-- 預期回傳: "Hello World"
| 物件/方法 | 用途 |
|---|---|
| UTL_DBWS.SERVICE | 服務控制代碼,對應 WSDL 服務定義 |
| UTL_DBWS.CALL | 呼叫控制代碼,對應特定操作 |
| UTL_DBWS.ANYDATA_LIST | 輸入參數陣列,支援多型資料 |
| ANYDATA.CONVERT* | 將標量轉為 ANYDATA |
| ANYDATA.ACCESS* | 從 ANYDATA 取回標量 |
| URIFACTORY.GETURI | 建立 URI 物件供 WSDL 定位 |
loadjava 成功載入所有 JAR,檢查 DBA_OBJECTS 中 JAVA CLASS 狀態UTL_HTTP 代理或防火牆規則,必要時調整 UTL_DBWS.SET_PROPERTY 逾時參數UTL_DBWS 讓資料庫直接參與服務導向架構,減少中介層跳轉,適合資料密集型整合場景。