程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 在IBM DB2通用數據庫中實現會話間的警告

在IBM DB2通用數據庫中實現會話間的警告

編輯:DB2教程

您是否正將您的數據庫從Oracle遷移至 IBM® DB2® Universal Database™?您是否認為可能會丟失 Oracle 的某個特殊功能?DB2 UDB 就是這樣一種十分靈活的數據庫,它可以滿足您的許多需要。在本文中,我將介紹一下如何實現一個稱為警告的功能。警告用於允許多重會話之間的通信。

警告概述

如圖1中所顯示,警告是為在會話間傳遞消息而設計的。警告標識、會話標識和消息存儲在表中(這裡是 alerts.dbms_alert_info)。消息由一個會話發送再由另一個會話讀取,這個過程由一個在指定表中設置的標志來控制。在設計參數(像列長度、主機變量長度、輪詢時間間隔等)時需要了解 Oracle 到 DB2 的遷移情況。您可以根據需要增加警告名和消息長度的大小。

圖 1. 警告在會話間發送消息

在IBM DB2通用數據庫中實現會話間的警告

設計概述

以下對象在實現類似 Oracle 具有的警告功能時都是必需的。所有對象都包含在本文的 下載部分中:

存儲警告信息的表: alerts.dbms_alert_info

注冊警告的存儲過程: alerts.register

刪除警告的存儲過程: alerts.remove和 alerts.delete

發送警告消息的存儲過程:alerts.signal

接收警告消息的存儲過程: alerts.waitone和 alerts.waitany

實現延遲的 UDF: alerts.delay

實現會話標識的 UDF: alerts.session_id

您可以更改我的設計以滿足自己的特殊要求。所有對象都使用了一個共同的模式,即警告。設計存儲過程以便您可以擴展它們來捕獲 SQLCODE、SQLSTATE 和 ERROR_MESSAGE。大量的異常處理在上面列出的所有存儲過程中實現,但是這裡並沒有使用到。您可以取消樣本代碼中異常處理部分的注釋然後再使用該部分。它們也可以返回相應的返回碼,以便用主語言實現必需的操作。游標可以在所有存儲過程中實現,但是在一些地方您可能希望更改為 fullselect。所有警告對象都被授予了公共執行(Public execute)許可權。您應該使用 DBADM 或 SYSADM 權限創建所有這些對象。

存儲警告信息:alerts.dbms._alert_info

目標:該表存儲警告標識、會話標識、消息和標志。該標志是一個指示符,表明一條消息是否已經由所有者會話放置在表中。

該表有四列:

NAME

該列(主鍵)存儲了警告名的名稱。在 Oracle 中,name 是一個可變長度為 30 個字符的字段,然而這裡我們將它定義為 varchar(60)。當然您可以擴展您的命名模式。

SID

這是會話標識。使用一個用戶定義的函數(session_id())來標識會話標識。

MESSAGE

用戶會話發送的警告消息正文,這個用戶會話需要和其他會話進行通信。它定義為使用 1800 個字符,但是如果您希望的話,可以擴展它的長度。

CHANGED

這是前面描述的指示符標志。缺省值是“N”。

授權:授予 PUBLIC 的權限包括:SELECT、INSERT、UPDATE、DELETE

  CREATE TABLE ALERTS.DBMS_ALERT_INFO (
  NAME VARCHAR(60) NOT NULL ,
  SID VARCHAR(50) NOT NULL,
  MESSAGE VARCHAR(1800) ,
  CHANGED CHAR(1) NOT NULL WITH DEFAULT 'N',
  CONSTRAINT PK_DBMS_ALERT_INFO PRIMARY KEY (NAME),
  CONSTRAINT CC_DBMS_ALERT_INFO CHECK (CHANGED IN ('Y','N','y','n')));

注冊警告:alerts.register

目標:該存儲過程注冊警告名。

相關性:session_id() UDF

輸入參數:警告名(最大長度為 60 個字符)

輸出參數:SQLCODE、SQLSTATE 和 ERROR_MESSAGE(以備擴展使用)

授權:將 EXECUTE 授權給 PUBLIC

功能行為:該存儲過程注冊警告名和會話標識並存儲這些內容。它將 MESSAGE 字段設置為 null 並將 CHANGED 字段設置為“N”。成功的話返回 0;否則返回 -1。

等待並讀取特定警告:alerts.waitone

目標:存儲過程等待並從指定警告名中讀取警告消息。

相關性:delay() UDF

輸入參數:警告名(最大長度為 60 個字符)

輸出參數:SQLCODE、SQLSTATE、ERROR_MESSAGE(以備擴展使用)、警告消息和超時狀態。

授權:將 EXECUTE 授權給 PUBLIC

功能行為:該存儲過程首先檢查指定警告名是否存在以及其標志是否設置為“Y”。這個標志意味著此會話可以從一個注冊警告接收警告消息,因為另一個會話已經發送了一條消息,而此會話正在查找來自那個會話的消息。

這個存儲過程等待警告消息。如果該警告沒有消息,它將等待一個預定義的時間間隔然後再檢查。缺省輪詢時間間隔是 5 秒,但是如果超時輸入參數設置為少於 5 秒或不是 5 秒的倍數,則輪詢時間間隔將設置為 1 秒。閱讀完消息以後,此存儲過程清除消息字段並將標志重新設置為“N”以使其不會阻塞其它會話。現在其它會話可以使用注冊警告發送消息。如果成功的話返回 0;否則返回 -1。

等待並讀取任何警告消息:alerts.waitany

目標:等待並從任意警告名中讀取警告消息的存儲過程。

相關性:delay() UDF

輸入參數:超時值,按秒計。

輸出參數:SQLCODE、SQLSTATE、ERROR_MESSAGE(以備擴展使用)、發出消息的警告名、消息和超時狀態。

授權:將 EXECUTE 授權給 PUBLIC

功能行為:waitone 和 waitany 存儲過程的差別在於,waitany 從 任何警告名中查找消息並將該警告名作為輸出參數返回。waitone 從指定警告名查找消息。

這兩個存儲過程的另一個不同就是輪詢時間間隔。對於 waitany,默認的輪詢時間間隔設置為 1 秒並且在每個輪詢周期中按指數級增加。如果超時時間間隔小於某個輪詢周期,則在開始此輪詢周期之前,此存儲過程將以該超時狀態結束。如果成功的話返回 0;否則返回 -1。

延遲執行:alerts.delay

目標:DB2 UDB 中沒有任何諸如“delay”或是“sleep”的系統調用,因此我們無法通過它們來將執行暫掛一段指定時間。該 UDF 通過運行一個在 Java™ 中實現的稱為“sleep”的系統調用,以在執行中實現延遲。

相關性:無

輸入參數:延遲時間,以秒計。

輸出參數:0(成功),-1(失敗)

授權:將 EXECUTE 授權給 PUBLIC

功能行為:該函數使用 OS 調用來實現延遲,這比其它任何一種類型的實現都更加高效。

目錄語句: CREATE FUNCTION delay(INTEGER)

  RETURNS INTEGER
  EXTERNAL NAME 'delayUDFjar:delayUDF.DELAY(INTEGER)'
  LANGUAGE Java
  PARAMETER STYLE Java
  NOT DETERMINISTIC
  NO SQL
  FENCED
  RETURNS NULL ON NULL INPUT
  EXTERNAL ACTION;

捕獲會話標識:alerts.session_id

目標:捕獲會話標識的用戶定義的函數。

相關性:無

輸入參數:延遲時間,以秒計。

輸出參數:0(成功),-1(失敗)

授權:將 EXECUTE 授權給 PUBLIC

功能行為:該函數捕獲存儲在 SQLUDF_DBINFO 內部結構中的會話標識。

目錄語句: CREATE FUNCTION SESSION_ID() RETURNS CHAR(34)

  EXTERNAL NAME 'sessionUDF!SESSION_ID'
  FENCED
  LANGUAGE C
  PARAMETER STYLE DB2SQL
  NOT VARIANT
  NO SQL
  NO EXTERNAL ACTION
  DBINFO;

安裝警告樣本

必備軟件:Microsoft VC++ v6.0 和 JDK v1.3.1。必須在操作系統環境設置中啟用這兩個編譯器路徑。

1.將文件 alert.zip 解壓縮至一個文件夾中,例如 C:tempalert

2.打開 alertsetup.bat 批處理文件並用適當的值編輯以下兩行。

·在 DB2HOMEPATH=C:SQLLIB 中,適當地更改 SQLLIB 路徑。

·在以下行中,更改路徑至 C:tempalertdelayUDF.jar :

DB2 CALL SQLJ.INSTALL_JAR('file:C:Documents and SettingssudiptaMy Documentsdb2KnowledgeBasearticlealertdelayUDF.jar','delayUDFjar')

3.在 DB2 Command Window 中運行批處理文件:

alertsetup.bat

例如: C:tempalert>alertsetup.bat SAMPLE TEST TEST01

DB2 UDB V8 測試過程

1.打開兩個 DB2 COMMAND WINDOW 會話(啟用了 DB2 環境的命令窗口)。讓我們將一個會話表示為“會話 A”,另一個表示為“會話 B”。

2.在兩個會話中,連接至 SAMPLE 數據庫。

3.在會話 A 中執行:

db2 call alerts.register('abc')

4.在會話 A 中執行:

db2 call alerts.signal('abc','Hello World from Session A.....')

5.在會話 B 中執行:

db2 call alerts.waitone('abc',?, ?, 30)

6.在會話 A 中執行:

db2 call alerts.register('xyz')

7.在會話 A 中執行:

db2 call alerts.signal('xyz','Message through alert xyz....')

8.在會話 B 中執行:

db2 call alerts.waitany(?,?,?,30)

9.在會話 B 中執行:

db2 call alerts.remove('abc')

這條語句將失敗,因為會話 B 不是名為“abc”的警告的創建者。

10.在會話 A 中執行同樣的命令:

db2 call alerts.remove('abc')

這次將成功。

11.在會話 B 中執行:

db2 call alerts.delete('xyz')

這次將成功,因為 alerts.delete 設計為可以從任何會話刪除任何注冊警告。

12.在兩個 CLP 會話中執行 db2 terminate 以終止連接。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved