存儲過程sql
在Oracle中,能夠在數據庫中定義子程序,這種程序塊稱爲存儲過程(procedure)。它存放在數據字典中,能夠在不一樣用戶和應用程序之間共享,並可實現程序的優化和重用。使用存儲過程的優勢是:
(1) 過程在服務器端運行,執行速度快。
(2) 過程執行一次後代碼就駐留在高速緩衝存儲器,在之後的操做中,只需從高速緩衝存儲器中調用已編譯代碼執行,提升了系統性能。
(3) 確保數據庫的安全。能夠不受權用戶直接訪問應用程序中的一些表,而是受權用戶執行訪問這些表的過程。非表的受權用戶除非經過過程,不然就不能訪問這些表。
(4) 自動完成須要預先執行的任務。過程能夠在系統啓動時自動執行,而沒必要在系統啓動後再進行手工操做,大大方便了用戶的使用,能夠自動完成一些須要預先執行的任務。
1. SQL命令建立存儲過程
數據庫
CREATE [OR REPLACE] PROCEDURE [schema.]procedure_name /*定義過程名*/ [ (parameter parameter_mode date_type , …n)] /*定義參數類型及屬性*/ IS | AS BEGIN sql_statement /*PL/SQL過程體,要執行的操做*/ END procedure_name
其中:
procedure_name:是過程名,必須符合標識符規則。關鍵字REPLACE表示在建立過程時,若是已存在同名的過程,則從新建立。若是使用CREATE關鍵字,則需將原有的過程刪除後才能建立。
schema.:是指定過程屬於的用戶方案。
parameter:是過程的參數。參數名必須符合標識符規則,建立過程時,能夠聲明一個或多個參數,執行過程時應提供相對應的參數。Parameter_mode是參數的類型,過程參數和函數參數同樣,也有3種類型,分別爲IN、OUT和IN OUT。
① IN:表示參數是輸入給過程的;
② OUT:表示參數在過程當中將被賦值,能夠傳給過程體的外部;
③ IN OUT:表示該類型的參數既能夠向過程體傳值,也能夠在過程體中賦值。
sql_statement:表明過程體包含的PL/SQL語句。
2. 調用存儲過程
直接輸入存儲過程的名字就能夠執行一個已定義的存儲過程。安全
EXEC[UTE] procedure_name[(parameter,…n)]
其中,procedure_name爲要調用的存儲過程的名字,parameter爲參數值。
【例1】從XSCJ數據庫的XS表中查詢某人的總學分,根據總學分寫評語。
服務器
CREATE OR REPLACE PROCEDURE update_info ( xm in char ) AS Xf number; BEGIN SELECT ZXF INTO XF FROM XS WHERE XM=xm; IF XF>60 THEN UPDATE XS SET BZ=’三好學生’ WHERE XM=xm; END IF; IF XF<35 THEN UPDATE XS SET BZ=’學分未修滿’ WHERE XM=xm; END IF; END update_info; update_info存儲過程執行: EXEC update_info(‘李明’);
【例2】統計表XS中男女同窗的人數,存儲過程使用了一個輸入參數和一個輸出參數。函數
CREATE OR REPLACE PROCEDURE count_num ( sex IN char, num OUT number ) AS BEGIN IF sex=’男’ THEN SELECT COUNT(XB) INTO num FROM XS WHERE XB=’男’; ELSE SELECT COUNT(XB) INTO num FROM XS WHERE XB=’女’; END IF; END count_num;
在調用過程count_num時,須要先定義OUT類型參數,調用以下:性能
DECLARE man_num NUMBER; BEGIN count_num(‘男’,man_num); END;
當某個過程再也不須要時,應將其從內存中刪除,以釋放它佔用的內存資源。
優化
DROP PROCEDURE [schema.] procedure_name;
其中,schema是包含過程的用戶;procedure_name是將要刪除的存儲過程名稱。spa
觸發器日誌
觸發器(trigger)是一些過程,與表關係密切,用於保護表中的數據,當一個基表被修改(INSERT、UPDATE或DELETE)時,觸發器自動執行,例如經過觸發器可實現多個表間數據的一致性和完整性。觸發器和應用程序無關。例如,對於XSCJ數據庫有XS表、XS_KC表和KC表,當插入某一學號的學生某一課程成績時,該學號應是XS表中已存在的,課程號應是KC表中已存在的,此時,可經過定義INSERT觸發器實現上述功能。
觸發器的類型有三種:
(1) DML觸發器。Oracle能夠在DML(數據操縱語句)語句進行觸發,能夠在DML操做前或操做後進行觸發,而且能夠在每一個行或該語句操做上進行觸發。
(2) 替代觸發器。因爲在Oracle中不能直接對有兩個以上的表創建的視圖進行操做,因此給出了替代觸發器。它是Oracle專門爲進行視圖操做的一種處理方法。
(3) 系統觸發器。在Oracle8i時,提供了第三種類型的觸發器叫系統觸發器。它能夠在Oracle數據庫系統的時間中進行觸發,如Oracle數據庫的關閉或打開等code
通常狀況下,對錶數據的操做有插入、修改、刪除,於是維護數據的觸發器也可分爲INSERT、UPDATE和DELETE。每張基表最多可創建12個觸發器,它們是:
(1) BEFORE INSERT;
(2) BEFORE INSERT FOR EACH ROW;
(3) AFTER INSERT;
(4) AFTER INSERT FOR EACH ROW;
(5) BEFORE UPDATE;
(6) BEFORE UPDATE FOR EACH ROW;
(7) AFTER UPDATE;
(8) AFTER UPDATE FOR EACH ROW;
(9) BEFORE DELETE;
(10) BEFORE DELETE FOR EACH ROW;
(11) AFTER DELETE;
(12) AFTER DELETE FOR EACH ROW。
1. 語法格式
CREATE OR REPLACE TRIGGER [schema.] trigger_name /*指定觸發器名稱*/ { BEFORE∣AFTER∣INSTEAD OF } { DELETE [OR INSERTE] [OR UPDATE [ OF column,…n ]] /*定義觸發器種類*/ ON [schema.] table_name∣view_name /*指定操做對象*/ [ FOR EACH ROW [ WHEN(condition) ] ] sql_statement[…n]
2. 建立觸發器的限制
(1) 代碼大小。觸發器代碼大小必須小於32K。
(2) 觸發器中有效語句能夠包括DML語句,但不能包括DDL語句。ROLLBACK、COMMIT、SAVEPOINT也不能使用。可是,對於系統觸發器(system trigger)可使用CREATE、ALTER、DROP TABLE和ALTER…COMPILE語句。
(3) LONG、LONG RAW和LOB的限制:
① 不能插入數據到LONG或LONG RAW;
② 來自LONG或LONG RAW的數據能夠轉換成字符型(如char、varchar2),可是不能超過32K;
③ 使用LONG或LONG RAW不能聲明變量;
④ 在LONG或LONG RAW列中不能使用:NEW和:PARENT;
⑤ 在LOB中的:NEW變量不能修改。
(4) 引用包變量的限制。若是UPDATE或DELETE語句檢測到當前的UPDATE衝突,則Oracle執行ROLLBACK到SAVEPOINT上並從新啓動更新,這樣可能須要屢次才能成功。
3. 觸發器觸發次序
Oracle對事件的觸發有16種,它們按照必定次序執行:
(1) 執行BEFORE語句的觸發器;
(2) 對於受語句影響的每一行:執行BEFORE語句行級觸發器à執行DML語句à執行AFTER行級觸發器。
(3) 執行AFTER語句級觸發器。
4. 建立DML觸發器
觸發器與過程名和包的名字不同,它有單獨的名字空間,於是觸發器名能夠和表名或過程名同名,但在同一個schema(方案)中的觸發器名不能相同。DML觸發器也叫表級觸發器,由於對某個表進行DML操做時會觸發該觸發器運行而得名。
【例1】假設XSCJ數據庫中增長一新表XS_HIS,表結構和表XS相同,用來存放從XS表中刪除的記錄。建立一個觸發器,當XS表被刪除一行,把刪除的記錄寫到日誌表XS_HIS中。
CREATE OR REPLACE TRIGGER del_xs BEFORE DELETE ON XS FOR EACH ROW BEGIN INSERT INTO XS_HIS (XH,XM,ZYM,XB,CSSJ,ZXF,BZ) VALUES(:OLD.XH,:OLD.XM, :OLD.ZYM, :OLD.XB, :OLD.CSSJ, :OLD.ZXF, :OLD.BZ); END del_xs;
OLD修飾訪問操做完成前列的值,NEW修飾訪問操做完成後列的值。
【例2】利用觸發器在數據庫XSCJ的XS表執行插入、更新和刪除3種操做後給出相應提示。
CREATE TRIGGER cue_xs AFTER INSERT OR UPDATE OR DELETE ON XS FOR EACH ROW DECLARE Infor char(10); BEGIN IF INSERTING THEN Infor:=’插入’; ELSIF UPDATING THEN Infor:=’更新’; ELSE Infor:=’刪除’; END IF; INSERT INTO SQL_INFO VALUES(infor); END cue_xs;
5. 建立系統觸發器
Oracle8i開始提供的系統觸發器能夠在DDL或數據庫系統上被觸發。DDL指的是數據定義語句,如CREATE、ALTER和DROP等。而數據庫系統事件包括數據庫服務器的啓動或關閉,用戶登陸與退出等。
CREATE OR REPLACE TRIGGER [scache.] trigger_name { BEFORE︱AFTER } { ddl_event_list︱databse_event_list } ON { DATABASE︱[schema.] SCHEMA } [when_clause] tigger_body
其中:
ddl_event_list:表示一個或多個DDL事件,事件間用OR分開。
database_event_list:表示一個或多個數據庫事件,事件間用OR分開。
DATABASE:表示是數據庫級觸發器,而scache表示是用戶級觸發器。Schema表示用戶方案。
Trigger_body:觸發器的PL/SQL語句。
6. 利用SQL命令刪除觸發器
DROP TRIGGER [schema.] trigger_name
其中:schema指定觸發器的用戶方案。Trigger_name指定要刪除的觸發器的名稱。