外部程序其實是儲存在DLL或是共享庫中的二進制程序
並且可以通過PL/SQL聲明從存儲程序中訪問得到它
這既使得它們成為了存儲程序開發者們最強大的開發工具之一
但是
事實上人們很少使用這些外部程序
也許是因為人們覺得創建DLL和共享庫
安裝程序以及引用PL/SQL這一系列過程讓人覺得非常繁瑣
而對應的文檔並不能起到什麼幫助作用
因為這些文檔提供的都是一些深奧的例子
它描述了使用的變量以及子程序使問題變得更加令人費解
你可以在許多不同的程序編譯語言中來創建DLL以及共享庫
你也可通過轉化腳本語言為二進制代碼來實現DLL以及共享庫的創建
DLL與共享庫作為獨立與操作系統的一部分
其實就是像調用執行文件的一部分那樣被連接和調用的具有公共入口的二進制映像
這裡有一個用C描述的用於二進制處理的DLL
/* bitop
c */
#ifdef WIN
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP
#endif /* WIN
*/
DLLEXP int bitand(int r
int l) { return r & l; }
DLLEXP int bitor(int r
int l) { return r | l; }
DLLEXP int bitxor(int r
int l) { return r ^ l; }
DLLEXP int bitshr(int n
int s) { return n << s; }
DLLEXP int bitshl(int n
int s) { return n >> s; }
DLLEXP int bitset(int n
int b) { return n | (
<<b); }
DLLEXP int bitclr(int n
int b) { return n ^ (
<<b); }
DLLEXP int bittst(int n
int b) { return (n & (
<<b)) ?
:
; }
其中唯一超出標准C范圍的就是DLLEXP宏
他為Windows提供了這些函數名並且可能被UNIX所忽視
將這些資源代碼與你的編譯文檔相對照
從而你可以從中了解更多關於如何創建DLL的信息
在UNIX環境下使用GNU編譯器的話
則包括以下命令行
GNU C/C++: cc
shared
o libbitop
so
bitop
c
從數據庫中調用DLL和共享庫的下一步就是使用CREATE LIBRARY命令
並給出完整的路徑
例如
CREATE OR REPLACE LIBRARY SCOTT
bitop AS
/home/scott/bitop/libbitop
so
通常只有DBA賬號擁有執行這個命令的權限
但此命令可通過其他用戶的行為發出
然後
這個用戶能調用PL/SQL和外部程序來調用任何DLL和共享庫
代碼如下
create or replace package bit_op
as
function bit_and(l pls_integer
r pls_integer) return pls_integer
as language c name
bitand
library bitop;
function bit_or(r pls_integer
l pls_integer) return pls_integer
as language c name
bitor
library bitop;
function bit_xor(r pls_integer
l pls_integer) return pls_integer
as language c name
bitxor
library bitop;
function bit_shr(n pls_integer
s pls_integer) return pls_integer
as language c name
bitshr
library bitop;
function bit_shl(n pls_integer
s pls_integer) return pls_integer
as language c name
bitshl
library bitop;
function bit_set(n pls_integer
b pls_integer) return pls_integer
as language c name
bitset
library bitop;
function bit_clr(n pls_integer
b pls_integer) return pls_integer
as language c name
bitclr
library bitop;
function bit_tst(n pls_integer
b pls_integer) return pls_integer
as language c name
bittst
library bitop;
end bit_op;
/
注意這個過程不需要程序包
如果數據庫已經設立好可以接受通過監聽器發出的外部程序請求
那麼這個過程就完成了
然後你就可以使用以下的查詢命令
select bit_op
bit_and(
) from dual where bit_op
bit_tst(
) =
;
如果你沒有建立好數據庫來接收外部指令請求
那麼你必須配置其他的監聽器來完成內部聯接
外部程序請求將通過SQL*Net發送給專門的監聽服務
再Oracle
i中
許多這種過程都是手工處理的
而在Oracle
i中
大部分可以通過設置完成了
即設在你的數據庫中存在tnsnames
ora這樣一個文件
你要確保你有能告訴客戶端怎樣聯接到數據庫並發出外部請求的設置
設置如下
EXTPROC_CONNECTION_DATA
world =
(DESCRIPTION=
(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_KEY))
(CONNECT_DATA=(SID=EXTPROC_AGENT))
)
請注意
EXTPROC_CONNECTION_DATA
這個名字是強制不變的
而
world則需要設置為與你的數據庫具有相同的域
同時EXTPROC_KEY和EXTPROC_AGENT則必須與你的listener
ora文件中的設置相匹配
其中listener
ora文件設置如下
EXTERNAL_PROCEDURE_LISTENER =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL=IPC)(KEY=EXTPROC_KEY))
)
SID_LIST_EXTERNAL_PROCEDURE_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME=EXTPROC_AGENT)
(ORACLE_HOME = c:\oracle\ora
)
(PROGRAM = EXTPROC)
)
)
在Oracle
i數據庫中
EXTPROC_CONNECTION_DATA應該已經被定義用於連接PLSExtProc
並且能在你自己的外部請求中使用
但是
任何沒有在監聽方的環境變量EXTPROC_DLL 中明確指出的DLL
Oracle
i都拒絕了對其的訪問權
從而增加了一些附加安全定義
在外部過程中
這個變量需要使用SID_DESC中的ENV參數
具體代碼如下
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u
/app/oracle/product/
)
(PROGRAM = extproc)
(ENVS=
EXTPROC_DLLS=ANY
)
)
(SID_DESC =
(GLOBAL_DBNAME = )
(ORACLE_HOME = /u
/app/oracle/product/
)
(SID_NAME = ikan)
)
)
為了得到更好的安全性
變量EXTPROC_DLLS可以設置為DLL序列或是共享庫序列
也可以設為ANY從而與敘訪問任何DLL和共享庫
你可以通過一下這條命令手工的進行連接測試
From:http://tw.wingwit.com/Article/program/Oracle/201311/17309.html