熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

使用IBMDB2例程簡化遷移的步驟

2013-11-13 16:05:21  來源: Oracle 

  當使用來自於不同供應商的不同數據庫系統時用戶和數據庫管理員將不可避免地碰到在這些產品中各不相同的特性和功能通常可在以下方面發現這些差異

  ◆受支持的 SQL 方言中的不同語法

  ◆數據庫管理器應用程序界面

  ◆不同的管理工具及其用法

  為了使得將數據庫和應用程序從 OracleSybase 或 Microsoft SQL Server 等數據庫產品遷移到 IBM DB Universal Database(UDB)更容易本文將展示一些可行的 DB UDB 功能實現而且這些功能在其他數據庫系統中也可獲得這些實現將涉及創建存儲過程和用戶定義函數(UDF)以實現那些常常被請求的功能

  在下載小節中您將找到這些過程和函數的源代碼以及包含了 CREATE PROCEDURE 和 CREATE FUNCTION 語句的 SQL 腳本如果您對確切的實現細節很感興趣就請查閱這些代碼一旦編譯並鏈接了源代碼(或安裝了預編譯的庫)以及在數據庫中注冊了這些過程和函數之後您就可以按本文實例所演示的那樣來使用它們了另外值得注意的是這些過程和函數可用於 DB UDB 版本 和版本

  清除表

  當從 Oracle 遷移到 DB所碰到的一個普遍問題就是 TRUNCATE 命令在 Oracle 中執行時該命令不用借助一個或多個 DELETE 操作就可快速地清除表中所有內容 DELETE 操作需要進行大量的日志記錄

  DB 的 IMPORT 功能提供了完成相同功能的方法只要使用 REPLACE INTO 子句以及將一個空文件指定為數據源在該情況下表中所有的行都將被快速清除並且只使用一條日志記錄接著就從給定的文件中導入新的數據而對於一個空文件就不會導入任何內容從而在該操作結束時清除了該表

  要實現該功能我們可以利用 DB 定義的叫做 sqluimpr() 的 C API 函數來以程序的方式將數據導入數據庫的表中我們將這個 API 包裝到存儲過程中以便可通過 SQL 接口用於所有的應用程序而無需考慮編程的語言清單 中展示了存儲過程 TRUNCATE_TABLE 的簽名

  清單 過程 TRUNCATE_TABLE的簽名          >>TRUNCATE_TABLE(schema_nametable_name)><

  VARCHAR() 類型的參數 schema_name 指定模式用以在其中找到表如果模式名外加了雙引號就將其看成定界名稱(混合大小寫的和特殊的字符)如果模式名為 空 即未指定模式那麼則要查閱 CURRENT SCHEMA 專用寄存器來確定所要使用的模式 VARCHAR() 類型的參數 table_name指定將被清除的表的未限定名稱加上顯式或隱式定義的模式名就可惟一地識別出表如果表名外加了雙引號就將其看成定界名稱(混合大小寫的和特殊的字符)

  如果輸入參數 schema_name 為 空 則由該過程的邏輯來確定默認模式否則就刪除現有模式名上的雙引號或者將未加引號的模式名轉換為大寫體對於表名同樣如此比如最後表名上的雙引號會被刪除或者未加引號的表名會被轉換為大寫體接著我們通過查詢 DB 目錄視圖 SYSCATTABLES 來證實該表是否存在現在就可以啟動導入了先准備好必要的參數其中使用的文件是 /dev/null(Windows 上的 NUL 文件)因為它總是存在並且不包含任何內容也就是可用作數據源的空文件同樣/dev/null(Windows 上的 NUL 文件)將用於進行導入所需的消息文件如果成功地啟動了導入該過程就會成功返回如果碰到錯誤則與消息文本一起返回 SQLSTATE 以指示錯誤清單 演示了過程 TRUNCATE_TABLE 的執行可以在下載小節中找到該腳本( truncate_exampledb)的源代碼

  清單 測試過程 TRUNCATE_TABLE          /* create and insert some values into the table tab */
          CREATE TABLE tab (col INTEGER NOT NULL PRIMARY KEY col VARCHAR() )
          DBI The SQL command completed successfully
          INSERT INTO tab VALUES ( some data ) ( NULL )
          DBI The SQL command completed successfully
          /* verify the current contents of table tab */
          SELECT * FROM tab
          COL COL
          
          some data
          
          record(s) selected
          /* Call the truncate stored procedure for the DBINST schema and the table tab */
          CALL truncate(DBINST tab)
          Return Status =
          /* Verify that the table contents have been truncated */
          SELECT * FROM tab
          COL COL
          
          record(s) selected
          /* Insert some new values into the tab table */
          INSERT INTO tab VALUES ( some new data ) ( NULL )
          DBI The SQL command completed successfully
          SELECT * FROM tab
          COL COL
          
          some new data
          
          record(s) selected
          /* Call the truncate procedure with a NULL schema */
          CALL truncate(NULL tab)
          Return Status =
          /* Verify that the table contents have been truncated */
          SELECT * FROM tab
          COL COL
          
          record(s) selected
          Sybase 的 host_name 函數

  Sybase 數據庫中的 host_name( ) 函數返回的是 客戶機進程(非 Adaptive Server 進程)的當前主機名也就是運行該應用程序的計算機的主機名而非數據庫服務器的主機名

  清單中展示了用戶定義函數 HOST_NAME 的簽名          >>HOST_NAME( )><

  該函數訪問存儲在 DBINFO 結構中的應用程序 ID 並解碼客戶機的 IP 地址(它是應用程序 ID 的一部分)然後便使用 C 庫函數gethostbyaddr來解析該 IP 地址的名稱該函數在必要時將訪問名稱服務器或其他源(比如 /etc/hosts)

  IP 地址是應用程序 ID 中前面 字節的編碼或者使用 *LOCAL 來代表本地連接對於本地連接解析的是 IP 地址為 的主機名

  注意

  由於 DRDA 的需求如果非本地 IP 地址的第一個字符初始為就將之映射到字母GP而在該名稱查找之前要將該映射反過來進行

  清單 演示了 HOST_NAME 函數的執行可以在下載小節中找到該腳本 host_name_exampledb 的源代碼

  清單 測試函數 HOST_NAME( )

  下面這個例子測試演示了用以獲取本地連接主機名的函數的執行

  在該場景中DB 數據庫駐留在一個本地 AIX 機器上

  地址 在 /etc/hosts 文件中被映射到計算機名 demoaix          /* connect to the local database */
          connect to sample
          Database Connection Information
          Database server = DB/
          SQL authorization ID = DBINST
          Local database alias = SAMPLE
          /* execute the host_name function */
          values host_name()
          
          
          demoaix
           record(s) selected

  下一個例子測試演示了遠程連接上的函數的執行

  在該場景中DB 數據庫與上面一樣駐留在同一 AIX 機器上

  到 AIX 上數據庫的連接是由一個 Windows 客戶機建立的;

  該客戶機的名字為 mycomputer          /* The database samplaix is an alias for the SAMPLE database on AIX */
          connect to samplaix
          Database Connection Information
          Database server = DB/
          SQL authorization ID = DBINST
          Local database alias = SAMPLAIX
          /* execute the host_name UDF against the remote database 鈥?
          it returns the name of the computer of the client connection */
          values host_name()
          
          
          mycomputer

  通過觸發器或用戶定義函數調用存儲過程的 UDF

  當遷移到 DB碰到的另一個普遍問題就是其他 RDBMS 可以通過觸發器或函數調用存儲過程雖然 DB 已經承諾在未來版本中包含該功能但是我們將展示如何使用 DB 的當前版本來實現該功能即通過創建一個將對存儲過程發出調用的 UDF 來實現

  清單中展示了用於該目的的用戶定義函數 CALL_PROCEDURE 的簽名

  清單 用戶定義函數 CALL_PROCEDURE 的簽名          >>CALL_PROCEDURE(procedure_nameparameter_list>
        >database_nameuser_namepassword)><

  VARCHAR() 類型的參數 procedure_name 指定要被調用的存儲過程的全限定名 —— 在傳遞多個參數時要用逗號進行分隔該字符串將被粘貼到用於調用過程的 CALL 語句中因此其語法需要符合 SQL CALL 語句的要求 VARCHAR() 類型的參數 database_name 指定要執行該存儲過程的數據庫的別名存儲過程不一定要駐留在同一數據庫中 VARCHAR() 類型的參數 user_name 和 VARCHAR() 類型的參數 password 用於確定連接數據庫以及執行該過程時所使用的注冊信息

  該函數調用當前數據庫中的存儲過程它建立新的連接之後就通過過程名和作為輸入參數而提供的參數來執行 CALL 語句該 UDF 返回 (零)表明 CALL 語句(以及相應的 CONNECT 和 CONNECT RESET 語句)執行成功否則將返回 DB 命令行處理器(Command Line ProcessorCLP)的返回碼和一條提供了更多信息的出錯消息清單 演示了函數 CREATE_PROCEDURE 的執行可以在下載小節中找到該腳本( trig_calls_procdb)的源代碼

  清單 測試函數 CREATE_PROCEDURE( )

  下面這個例子測試演示了從觸發器調用包含一個參數的存儲過程

  在該示例中我們創建 t 和 t 這兩個表帶有一個輸入參數(p)

  的過程(abc)以及一個觸發器(ins)在執行觸發器時它將調用該過程

  然後過程將會將 num 列的新值(ll)插入到表 t

  這可以通過以下操作來測試在表 t 上執行插入後對 t 發出 select

  來檢驗該表內容 —— 進而檢驗該過程是否成功執行           create table t ( col int)
          DBI The SQL command completed successfully
          create table t ( col int )
          DBI The SQL command completed successfully
          create procedure abc(in p int) begin insert into t values(p); end
          DBI The SQL command completed successfully
          create trigger ins after insert on t referencing NEW as new for EACH ROW MODE
          DBSQL BEGIN ATOMIC values ( call_procedure(DBINSTABC char(l * )
          SAMPLE DBINST dbinst) ); END
          DBI The SQL command completed successfully
          insert into t values
          DBI The SQL command completed successfully
          /* validate that the trigger has fired it should update t */
          select * from t
          COL
          
          
           record(s) selected

  下一個例子演示了在 UDF 中調用包含了兩個參數的存儲過程在該例中我們創建表( c )帶有兩個輸入參數的存儲過程( abc )以及帶有兩個參數(parmparm)的 UDF( udf_withcall )當執行該 UDF 時它將調用存儲過程然後該存儲過程會將由 UDF 傳遞給它的值插入表 c對表 c 進行 select 將驗證表 c 的內容以及存儲過程是否執行成功可以在下載小節中找到該腳本( udf_calls_procdb)的源代碼          create table c ( a int check (a <> ) a int )
          DBI The SQL command completed successfully
          create procedure abc(in p int in p int) begin insert into c values(pp); end
          DBI The SQL command completed successfully
          create function udf_withcall (parm int parm int)
          returns int
          Language SQL
          not deterministic
          external action
          return call_procedure(DBINSTABC char(parm) |||| char(parm) SAMPLE DBINST dbinst))
          DBI The SQL command completed successfully
          select udf_withcall() from sysibmsysdummy
          
          
          
           record(s) selected
          /* verify that the UDF has called the procedure and updated the table */
          select * from c
          A A
          
          
          
           record(s) selected

  構建例程

  為了構建 C 例程(UDF 或 存儲過程)必須首先對其進行預編譯編譯以及鏈接該過程可通過批文件 bldrtn (UNIX/LINUX 上)或 bldrtnbat (Windows 上)自動完成該文件包含在隨 DB 一同安裝的樣本中可以在 UNIX/LINUX 上的 /sqllib/samples/c 目錄或 Windows 上的          bldrtn [dbname userid password]

  如果未提供 dbname那麼批文件會將之默認為 SAMPLE 而 userid 和 password 則被默認為當前會話的用戶 ID 和口令


From:http://tw.wingwit.com/Article/program/Oracle/201311/17791.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.