| 導購 | 订阅 | 在线投稿
分享
 
 
 

外部程序使一切變得簡單

來源:互聯網  2008-05-31 22:07:58  評論

外部程序其實是儲存在DLL或是共享庫中的二進制程序,並且可以通過PL/SQL聲明從存儲程序中訪問得到它。這既使得它們成爲了存儲程序開發者們最強大的開發工具之一。

但是,事實上人們很少使用這些外部程序,也許是因爲人們覺得創建DLL和共享庫,安裝程序以及引用PL/SQL這一系列過程讓人覺得非常繁瑣。而對應的文檔並不能起到什麽幫助作用,因爲這些文檔提供的都是一些深奧的例子,它描述了使用的變量以及子程序使問題變得更加令人費解。

你可以在許多不同的程序編譯語言中來創建DLL以及共享庫,你也可通過轉化腳本語言爲二進制代碼來實現DLL以及共享庫的創建。DLL與共享庫作爲獨立與操作系統的一部分,其實就是像調用執行文件的一部分那樣被連接和調用的具有公共入口的二進制映像。這裏有一個用C描述的用于二進制處理的DLL:

/* bitop.c */

#ifdef WIN32

#define DLLEXP __declspec(dllexport)

#else

#define DLLEXP

#endif /* WIN32 */

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 (1<<b); }

DLLEXP int bitclr(int n,int b) { return n ^ (1<<b); }

DLLEXP int bittst(int n,int b) { return (n & (1<<b)) ? 1 : 0; }

其中唯一超出標准C範圍的就是DLLEXP宏,他爲Windows提供了這些函數名並且可能被UNIX所忽視。將這些資源代碼與你的編譯文檔相對照,從而你可以從中了解更多關于如何創建DLL的信息。在UNIX環境下使用GNU編譯器的話,則包括以下命令行:

GNU C/C++: cc -shared -o libbitop.so.1 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(24,56) from dual where bit_op.bit_tst(24,5) = 1;

假如你沒有建立好數據庫來接收外部指令請求,那麽你必須配置其他的監聽器來完成內部聯接。

外部程序請求將通過SQL*Net發送給專門的監聽服務。再Oracle8i中,許多這種過程都是手工處理的。而在Oracle9i中,大部分可以通過設置完成了。

即設在你的數據庫中存在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\ora81)

(PROGRAM = EXTPROC)

)

)

在Oracle9i數據庫中,EXTPROC_CONNECTION_DATA應該已經被定義用于連接PLSExtProc,並且能在你自己的外部請求中使用。但是,任何沒有在監聽方的環境變量EXTPROC_DLL 中明確指出的DLL,Oracle9i都拒絕了對其的訪問權,從而增加了一些附加安全定義。在外部過程中,這個變量需要使用SID_DESC中的ENV參數,具體代碼如下:

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

(SID_NAME = PLSExtProc)

(ORACLE_HOME = /u01/app/oracle/prodUCt/9.2.0)

(PROGRAM = extproc)

(ENVS="EXTPROC_DLLS=ANY")

)

(SID_DESC =

(GLOBAL_DBNAME = ikan.us.oracle.com)

(ORACLE_HOME = /u01/app/oracle/product/9.2.0)

(SID_NAME = ikan)

)

)

爲了得到更好的安全性,變量EXTPROC_DLLS可以設置爲DLL序列或是共享庫序列。也可以設爲ANY從而與敘訪問任何DLL和共享庫。你可以通過一下這條命令手工的進行連接測試:

  外部程序其實是儲存在DLL或是共享庫中的二進制程序,並且可以通過PL/SQL聲明從存儲程序中訪問得到它。這既使得它們成爲了存儲程序開發者們最強大的開發工具之一。      但是,事實上人們很少使用這些外部程序,也許是因爲人們覺得創建DLL和共享庫,安裝程序以及引用PL/SQL這一系列過程讓人覺得非常繁瑣。而對應的文檔並不能起到什麽幫助作用,因爲這些文檔提供的都是一些深奧的例子,它描述了使用的變量以及子程序使問題變得更加令人費解。      你可以在許多不同的程序編譯語言中來創建DLL以及共享庫,你也可通過轉化腳本語言爲二進制代碼來實現DLL以及共享庫的創建。DLL與共享庫作爲獨立與操作系統的一部分,其實就是像調用執行文件的一部分那樣被連接和調用的具有公共入口的二進制映像。這裏有一個用C描述的用于二進制處理的DLL:      /* bitop.c */   #ifdef WIN32   #define DLLEXP __declspec(dllexport)   #else   #define DLLEXP   #endif /* WIN32 */   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 (1<<b); }   DLLEXP int bitclr(int n,int b) { return n ^ (1<<b); }   DLLEXP int bittst(int n,int b) { return (n & (1<<b)) ? 1 : 0; }      其中唯一超出標准C範圍的就是DLLEXP宏,他爲Windows提供了這些函數名並且可能被UNIX所忽視。將這些資源代碼與你的編譯文檔相對照,從而你可以從中了解更多關于如何創建DLL的信息。在UNIX環境下使用GNU編譯器的話,則包括以下命令行:      GNU C/C++: cc -shared -o libbitop.so.1 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(24,56) from dual where bit_op.bit_tst(24,5) = 1;      假如你沒有建立好數據庫來接收外部指令請求,那麽你必須配置其他的監聽器來完成內部聯接。      外部程序請求將通過SQL*Net發送給專門的監聽服務。再Oracle8i中,許多這種過程都是手工處理的。而在Oracle9i中,大部分可以通過設置完成了。      即設在你的數據庫中存在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\ora81)      (PROGRAM = EXTPROC)     )    )      在Oracle9i數據庫中,EXTPROC_CONNECTION_DATA應該已經被定義用于連接PLSExtProc,並且能在你自己的外部請求中使用。但是,任何沒有在監聽方的環境變量EXTPROC_DLL 中明確指出的DLL,Oracle9i都拒絕了對其的訪問權,從而增加了一些附加安全定義。在外部過程中,這個變量需要使用SID_DESC中的ENV參數,具體代碼如下:      SID_LIST_LISTENER =    (SID_LIST =     (SID_DESC =      (SID_NAME = PLSExtProc)      (ORACLE_HOME = /u01/app/oracle/prodUCt/9.2.0)      (PROGRAM = extproc)      (ENVS="EXTPROC_DLLS=ANY")     )     (SID_DESC =      (GLOBAL_DBNAME = ikan.us.oracle.com)      (ORACLE_HOME = /u01/app/oracle/product/9.2.0)      (SID_NAME = ikan)     )    )      爲了得到更好的安全性,變量EXTPROC_DLLS可以設置爲DLL序列或是共享庫序列。也可以設爲ANY從而與敘訪問任何DLL和共享庫。你可以通過一下這條命令手工的進行連接測試:
󰈣󰈤
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
王朝網路微信公眾號
微信掃碼關註本站公眾號 wangchaonetcn
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有