摘 要: 兼容Oracle PL/SQL V2.3 語言規(guī)范,基于國產數(shù)據庫管理系統(tǒng)" title="管理系統(tǒng)">管理系統(tǒng)GKD-Base" title="GKD-Base">GKD-Base內核與PL/SQL引擎,提出了Instead-Of視圖觸發(fā)器的編譯存儲和點火執(zhí)行算法,并設計實現(xiàn)了Instead-Of 視圖觸發(fā)器編譯及執(zhí)行處理模塊" title="處理模塊">處理模塊。從而在GKD-Base上實現(xiàn)了Instead-Of視圖觸發(fā)器機制,擴展了國產數(shù)據庫GKD-Base功能。
關鍵詞: PL/SQL引擎 Instead-Of觸發(fā)器
GKD-Base是一個具有自主知識產權的數(shù)據庫管理系統(tǒng),經過十幾年的發(fā)展和應用,該系統(tǒng)已經被證明是穩(wěn)定可靠的。但是,隨著應用需求向深度和廣度的發(fā)展,GKD-Base在很多方面都暴露出了不足,如不支持過程式SQL語言、不支持存儲過程和函數(shù)、缺少觸發(fā)器功能等,這都為GKD-Base數(shù)據庫管理系統(tǒng)的進一步推廣應用帶來了不小的障礙。
為此筆者開發(fā)了GKD-Base PL/SQL引擎,其兼容Oracle PL/SQLV2.3規(guī)范。進而在引擎的基礎上實現(xiàn)了GKD-Base DML觸發(fā)器功能[1]。但目前GKD-Base對于視圖更新的支持還很不夠,對于連接視圖的更新有著十分嚴格的限制。國外數(shù)據庫系統(tǒng)" title="數(shù)據庫系統(tǒng)">數(shù)據庫系統(tǒng)如Oracle[2]、SQL Server[3]、PostgreSQL[4]等都提供了所謂的Instead-Of視圖觸發(fā)器來支持視圖更新。定義有Instead-Of觸發(fā)器的視圖被DML語句操作時,相應的DML語句不執(zhí)行,而觸發(fā)器體被執(zhí)行,于是用戶可以按照自己定義的語義修改定義視圖的基本表,以達到修改視圖的目的。因此,為了使GKD-Base適應應用需求的發(fā)展,在GKD-Base PL/SQL引擎的基礎上實現(xiàn)了GKD-Base Instead-Of視圖觸發(fā)器功能[1]。
1 視圖更新歧義問題
視圖是虛擬的關系,數(shù)據庫系統(tǒng)中只存儲它的定義,不存儲元組數(shù)據。一個視圖可以看成一個臨時關系,視圖是產生這種臨時關系的查詢定義[5]。
由于視圖是虛擬的關系,對視圖的更新操作必須映射到對相應的基本表操作才能實現(xiàn)。完成視圖更新后的數(shù)據庫狀態(tài)由視圖定義導出一個新的視圖狀態(tài),新的視圖狀態(tài)對應由原視圖狀態(tài)直接完成視圖的更新操作。
如圖1所示,u是關系數(shù)據庫DB的視圖v(DB)的更新操作,T(u)是對視圖更新操作的變換,它作用到DB上產生新的數(shù)據庫狀態(tài)DB′、新的視圖狀態(tài)v(DB′)。正確的視圖更新操作使得u(v(DB))= v(DB′)。但是對視圖更新操作的變換T(u)并不總存在[6]。即使存在,也不總是惟一的。視圖的更新存在固有的歧義性,僅有上面的語義是不夠的。
并且,由于視圖本身的歧義性和語義不完整性[7],無法對于有著集合操作符(如:UNION、MINUS等)、聚集函數(shù)(如:SUM、AVE等)和GROUP BY子句的視圖更新提供支持。
2 Instead-Of觸發(fā)器設計實現(xiàn)
2.1 PL/SQL引擎體系結構
根據PL/SQL語言兼有過程式語句和SQL語句的特點,GKD-Base PL/SQL引擎把過程式語句和SQL語句分開處理。為了降低引擎實現(xiàn)的復雜程度,從功能性的角度將整個引擎劃分為前端編譯器和后端解釋執(zhí)行器" title="執(zhí)行器">執(zhí)行器,每個處理模塊盡量降低相互間的耦合程度。
前端編譯器包括語言預處理、SQL語句分析、過程語句分析以及中間代碼生成等功能。PL/SQL語句塊輸入后,由語言預處理功能分離成SQL語句和過程語句。對于SQL語句,由GKD-Base SQL引擎解析后,建立SQL語句結點,進行相應的變量綁定和語法檢查,檢查無誤后產生語法樹形式的中間代碼。對于過程語句,將語句成分進行語法分析,在分析中把聲明的變量和數(shù)據類型加入到名字空間和符號表中,同時產生語法樹形式的中間代碼。
后端解釋執(zhí)行器的功能就是對前端編譯器生成的中間代碼進行解釋執(zhí)行。因此在結構上,解釋執(zhí)行器與編譯器對應,也有過程語句執(zhí)行模塊和SQL語句執(zhí)行模塊,過程語句解釋執(zhí)行器解釋執(zhí)行過程語句的中間代碼,SQL命令則直接由SQL引擎執(zhí)行。另外,解釋器還包括例外處理模塊,負責檢查錯誤和報告錯誤[8]。
2.2 Instead-Of觸發(fā)器設計
2.2.1觸發(fā)器模型
GKD-Base DML觸發(fā)器采用傳統(tǒng)的ECA(Event-Condition-Action,事件—條件—動作)規(guī)則設計。與之類似的Instead-Of 視圖觸發(fā)器也采用了ECA規(guī)則。
為了適應觸發(fā)器的具體情況,在GKD-Base中,Instead-Of 視圖觸發(fā)器擴展為一個四元組模型:Trigger:=
E(Event):激發(fā)Instead-Of 視圖觸發(fā)器的事件。這里主要是指操作視圖的DML事件,包括Insert、 Delete和Update等。
C(Condition):定義觸發(fā)器時指定的條件。是一個一元謂詞表達式。
A(Action):當Event發(fā)生,并且Condition為真時,觸發(fā)的動作。
S(Status):觸發(fā)器有活躍和休眠兩種狀態(tài),觸發(fā)器處于活躍狀態(tài)時,才可被激發(fā)。
2.2.2 觸發(fā)器實現(xiàn)框架
觸發(fā)器實現(xiàn)框架如圖2所示。觸發(fā)器類別判決器是在系統(tǒng)執(zhí)行SQL語句之前,對SQL語句的操作對象進行判斷,如果是對基本表操作,則啟動DML觸發(fā)器的監(jiān)測功能;如果是對視圖進行操作,則啟動Instead-Of 視圖觸發(fā)器的監(jiān)測功能。事件監(jiān)視器是在有關的系統(tǒng)行為發(fā)生時,為各種預定的事件給觸發(fā)器調度器發(fā)送信號。觸發(fā)器調度器接收事件監(jiān)視器的信號,從數(shù)據字典中獲取該事件點火的所有觸發(fā)器,并且按照特定的順序排序,調用條件評價器檢查各觸發(fā)器的觸發(fā)條件是否滿足,若滿足則由觸發(fā)器調度器通知PL/SQL引擎解釋執(zhí)行該觸發(fā)器的動作代碼。條件評價器是用來檢查觸發(fā)條件是否滿足的部件。對于語句級觸發(fā)器,由于不存在觸發(fā)條件子句,所以觸發(fā)條件始終為真。對于行(元組)級觸發(fā)器,條件評價器可以將其觸發(fā)條件WHEN子句轉換成一個PL/SQL語言的IF語句,然后由PL/SQL引擎實現(xiàn)觸發(fā)器條件的計算。
2.3 Instead-Of觸發(fā)器實現(xiàn)
2.3.1 觸發(fā)器謂詞以及new和old元組的設計
觸發(fā)器謂詞是指觸發(fā)器內部用來標識激發(fā)觸發(fā)器動作的DML語句的布爾變量,為:INSERTING、UPDATING、DELETING。其分別對應于PL/SQL程序中的三個布爾變量,它們在編譯觸發(fā)器時被加載到符號表中,在調用PL/SQL引擎執(zhí)行觸發(fā)器動作體之前,它們的值被準備好,供PL/SQL引擎取用。
NEW和OLD元組作為PL/SQL程序中的記錄樣式加載到符號表中,被編譯器引用。其記錄域與新舊元組對應的表的各個屬性一一對應。在調用PL/SQL引擎執(zhí)行觸發(fā)器動作體之前,必須準備好NEW和OLD的值。但NEW和OLD元組是偽記錄類型,不能完全按照記錄的語法來訪問[12]。這一點必須在編譯時加入新的語義規(guī)則。
2.3.2 Instead-Of觸發(fā)器的編譯與存儲
功能:編譯觸發(fā)器定義語句后,將觸發(fā)器信息存儲于數(shù)據字典中。
輸入:一條用戶輸入的觸發(fā)器定義語句。
輸出:觸發(fā)器數(shù)據字典的元組。
(1)判斷當前事務是否存在,如果存在,則提交當前事務,并開始一個新事務;否則,直接開始一個新事務。
(2)用戶權限檢查。如果當前用戶無權執(zhí)行該操作,轉(12);否則轉(3)。
(3)檢查觸發(fā)表(視圖)名及觸發(fā)事件所涉及的屬性是否存在。在GKD-Base的數(shù)據字典SYS.TABLES中查找,如果觸發(fā)表或某個屬性不存在,轉(12);否則,轉(4)。
(4)觸發(fā)器名存在性檢查。如果當前定義的觸發(fā)器與以往定義的某個觸發(fā)器重名,轉(5);否則轉(7)。
(5)如果聲明語句中沒有包含 OR REPLACE選項,轉(12);否則,轉(6)。
(6)如果觸發(fā)表(視圖)不一致,轉(12);否則轉(7)(觸發(fā)表指定義了DML觸發(fā)器或Instead-Of 視圖觸發(fā)器的基本表或視圖)。
(7)檢查定義觸發(fā)器的合法性,DML觸發(fā)器只能定義在基本表上,而Instead-Of視圖觸發(fā)器只能定義在視圖上。檢查合法,轉(8),否則轉(12)。
(8)調用PL/SQL引擎編譯觸發(fā)器動作體,并且將觸發(fā)器的WHEN條件子句轉換成一個IF語句,這個IF語句的真值部分包括了觸發(fā)器動作體。如果觸發(fā)器動作體中出現(xiàn)語法或語義錯誤,轉(12);否則轉(9)。
(9)在數(shù)據字典SYS.TRIGGERS表中插入一個新元組,填入此觸發(fā)器的信息。如果出現(xiàn)磁盤I/O錯誤,轉(12);否則轉(10)。
(10)釋放所占資源。
(11)提交當前事務,正常結束。
(12)回滾當前事務,報錯退出。
2.3.3 Instead-Of視圖觸發(fā)器的點火執(zhí)行
與DML觸發(fā)器不同,Instead-Of 視圖觸發(fā)器在激發(fā)時,不必考慮各種觸發(fā)器(如語句級前觸發(fā)器和行級后觸發(fā)器)之間的相互纏結。其點火算法也相對簡單。 在觸發(fā)事件當前的事務中構造一條SQL查詢語句,從觸發(fā)器數(shù)據字典表中獲取與該觸發(fā)事件相關的處于活躍狀態(tài)的Instead-Of視圖觸發(fā)器元組。如果查詢結果不為空,將觸發(fā)器條件轉換成一個PL/SQL語言的IF語句,并將觸發(fā)事件當前所用到的元組值(新值和舊值)準備好,啟動PL/SQL引擎,對觸發(fā)器動作體的源代碼進行解釋執(zhí)行。釋放所占的資源,結束觸發(fā)器調用。
3 系統(tǒng)應用實例
3.1實驗數(shù)據
Rooms表如表1所示,Classes表如表2所示。在Classes表和Rooms表中Room_ID相等的連接條件上創(chuàng)建一個名為Classes_rooms的視圖,進行連接運算。Classes_rooms視圖如表3所示。
定義關于Classes_rooms 的Update語義:通過對Classes_rooms的Update操作,實現(xiàn)對一個班級某門課程占用教室的調整。通過Instead-Of觸發(fā)器實現(xiàn):如果修改了Classes_rooms的Dept和Course屬性,那么就修改Classes基本表的相應屬性,如果修改了Classes_rooms的Building和Room_Num屬性,那么就修改Rooms基本表的相應屬性。再適當調整兩個基本表的Room_ID。
3.2 實驗結果
執(zhí)行UPDATE classes_rooms SET Dept=‘NUT’, course = 307 WHERE building=‘Buidling 7’ AND room_num = 201; 查詢更新后的視圖,觀察Instead-Of觸發(fā)器對視圖的作用。
表4、表5、表6演示了本實驗的結果。由結果可知,通過Instead-Of觸發(fā)器,成功地對Classes_rooms視圖進行了修改,將歷史系101課的教室調整給了營養(yǎng)系307課程使用。通過以上應用實例驗證了Instead-Of觸發(fā)器帶給數(shù)據庫系統(tǒng)的視圖修改功能。
本文參照Oracle PL/SQL V2.3 語言規(guī)范,在數(shù)據庫管理系統(tǒng)GKD-Base 的PL/SQL引擎的基礎上,給出了Instead-Of 視圖觸發(fā)器的編譯存儲和點火執(zhí)行的相關算法,設計了Instead-Of視圖觸發(fā)器編譯及執(zhí)行處理模塊,從而在實現(xiàn)DML 觸發(fā)器的基礎上實現(xiàn)了Instead-Of 視圖觸發(fā)器,并在實際中得到了驗證。擴展了GKD-Base的功能,使其能夠應用于更多的領域。
參考文獻
1 Tom Portfolio. PL/SQL User′s Guide and Reference. Release 8.1.6. Oracle Corporation,1999
2 Ken Henderson. The Guru′s Guide to Transact-SQL. AddisonWesley Pub Co., 2000;2
3 PostgreSQL 7.4 Documentation.The PostgreSQL Global Development Group, 2003
4 景 寧. SQL查詢處理與實現(xiàn)技術研究.長沙:國防科技大學.工學博士學位論文,1990;4
5 E.F.Codd. Recent Investigations in a Relational Database System. North-Holland Publishing Company,1974
6 劉念祖. 數(shù)據庫系統(tǒng)中視圖問題的研究. 計算機工程,1997;12
7 陳火旺. 程序設計語言——編譯原理.北京:國防工業(yè)出版社,2000