存儲在數據庫中供所有用戶程序調用的子程序叫做 存儲過程是在大型數據庫系統中,用PL/SQL語言編寫的能完成一定處理功能的存儲在數據庫字典中的程序,它是一個命名的 PL/SQL 塊,經編譯后存儲在數據庫中,用戶通過指定存儲過程的名字并給出參數(如果該存儲過程帶有參數)來執行它。 存儲過程是數據庫中的一個重要對象,任何一個設計良好的數據庫應用程序都應該用到存儲過程。 為保證調用多個存儲過程中處在同一個事務中,所以一般不在存儲過程或者存儲函數中,commit或rollback; | |||||||
語 法 |
其中參數IN表示輸入參數,是參數的默認模式。 OUT表示返回值參數,類型可以使用任意Oracle中的合法類型。 OUT模式定義的參數只能在過程體內部賦值,表示該參數可以將某個值傳遞回調用他的過程 IN OUT表示該參數可以向該過程中傳遞值,也可以將某個值傳出去。 存儲過程參數不帶取值范圍,in表示傳入,out表示輸出; 變量帶取值范圍,后面接分號; 在判斷語句前最好先用count(*)函數判斷是否存在該條操作記錄; 用select … into … 給變量賦值; 在代碼中拋異常用 raise+異常名; | ||||||
調用存儲過程的兩種方式 |
| ||||||
將過程的 執行權限 授予其他 用戶 | SQL> GRANT EXECUTE ON find_emp TO MARTIN; SQL> GRANT EXECUTE ON swap TO PUBLIC; | ||||||
和函 數 區別 | 一般來講,過程和函數的區別在于函數可以有一個返回值;而過程沒有返回值。但過程和函數都可以通過 out 指定一個或多個輸出參數。我們可以利用 out 參數,在過程和函數中實現返回多個值 1 如果存儲過程想實現有返回值的業務,我們就必須使用out類型的參數。 如果只有一個返回值,用存儲函數;否則,就用存儲過程 過程和函數都可以通過
| ||||||
1.在oracle中,數據表別名不能加as,如: select a.appname from appinfo a;-- 正確 select a.appname from appinfo as a;-- 錯誤 2.在存儲過程中,select某一字段時,后面必須緊跟into,如果select整個記錄,利用游標的話就另當別論了。 3.在利用select…into…語法時,必須先確保數據庫中有該條記錄,否則會報出”no data found”異常。 4.在存儲過程中,別名不能和字段名稱相同,否則雖然編譯可以通過,但在運行階段會報錯 5.select sum(vcount) into fcount from A where bid='xxxxxx'; 如果A表中不存在bid=”xxxxxx”的記錄,則fcount=null(即使fcount定義時設置了默認值, 如:fcount number(8):=0依然無效,fcount還是會變成null), 這樣以后使用fcount時就可能有問題,所以在這里最好先判斷一下: if fcount is null then ? ? fcount:=0; end if; | |||||||
觸發器 觸發器是一種特殊的存儲過程,觸發器在數據庫里以獨立的對象存儲,它與存儲過程和函數不同的是,存儲過程與函數需要用戶顯示調用才執行,而觸發器是由一個事件來啟動運行。即觸發器是當某個事件發生時自動地隱式運行。并且,觸發器不能接收參數。所以運行觸發器就叫觸發或點火(firing)。ORACLE事件指的是對數據庫的表進行的INSERT、UPDATE及DELETE操作或對視圖進行類似的操作。ORACLE將觸發器的功能擴展到了觸發ORACLE,如數據庫的啟動與關閉等。所以觸發器常用來完成由數據庫的完整性約束難以完成的復雜業務規則的約束,或用來監視對數據庫的各種操作,實現審計的功能。? 1、觸發器類型 主要有DML觸發器、替代觸發器、系統事件觸發器和DDL觸發器。 DML觸發器:ORACLE可以在DML語句進行觸發,可以在DML操作前(BEFORE觸發器)或操作后(AFTER觸發器)進行觸發,并且可以對每個行或語句操作上進行觸發(行級觸發器和語句級觸發器)。? INSTEAD OF觸發器:又稱為替代觸發器,用于執行一個替代操作來代替觸發事件的操作,?由于在ORACLE里,不能直接對由兩個以上的表建立的視圖進行操作。所以給出了替代觸發器。 系統事件觸發器:在發生如數據庫啟動或者關閉等系統事件時觸發。 DDL觸發器:由DDL語句觸發,例如CREATE、ALTER和DROP語句。可分為BEFORE觸發器和AFTER觸發器。 2、創建觸發器 使用CREATE TRIGGER語句,語法如下: CREATE?[ OR?REPLACE ]?TRIGGER?trigger_name { BEFORE?|?AFTER?| INSTEAD?OF } { INSERT?|?DELETE?|?UPDATE?[ OF?column?[,?column?… ] ] } ?#tigger_event [ OR?{ INSERT?|?DELETE?|?UPDATE?[OF?column?[,?column?… ] ] } ... ] ON?[ schema. ] table_name?|?[ schema.] view_name?| [ DATAASE ] [ REFERENCING??{ OLD?[ AS ]?old?|?NEW?[ AS ] ?new |?PARENT?as?parent } ] [ FOR?EACH?ROW?] [ WHEN?trigger_condition ] [ DECLARE declaration_statements ; ] BEGIN trigger_body ; END [ trigger_name ] PL/SQL_BLOCK?|?CALL?procedure_name; 語法說明: trigger_name:觸發器名稱。 BEFORE?|?AFTER | INSTEAD OF:BEFORE和AFTER表示觸發器執行的時間在觸發事件的前后,INSTEAD OF表示觸發器中的事件代替觸發事件執行。 tigger_event:激活觸發器的事件,例如 INSERT、DELETE、UPDATE?。 ON?[ schema. ] table_name?|?[ schema.] view_name?| [ DATABASE ]:table_name為DML觸發器所針對的表,如果是替代觸發器則需要指定視圖名稱(view_name),如果是DDL觸發器或者系統事件觸發器,則使用ON DATABASE。 REFERENCING:說明相關名稱,在行觸發器的PL/SQL塊和WHEN?子句中可以使用相關名稱參照當前的新、舊列值,默認的相關名稱分別為OLD和NEW。觸發器的PL/SQL塊中應用相關名稱時,必須在它們之前加冒號(:),但在WHEN子句中則不能加冒號。 FOR?EACH?ROW:表示是行級觸發器,如果未指定則為語句級觸發器。 WHEN?trigger_condition:為觸發的運行指定限制條件。 trigger_body:觸發器體,包含觸發器的內容。 3、DML觸發器 DML觸發器由DML語句觸發,對應的tigger_event為: { INSERT | DELEATE | UPDATE [ OF column [ , ... ] ] } 說明: DML操作主要包括INSERT、DELETE和UPDATE操作,通過根據針對的事件,可分為INSERT觸發器、DELETE觸發器和UPDATE觸發器。 可以將DML操作細化到列,即針對某列進行DML操作時激活觸發器。 任何DML都可按照觸發時間分為BEFORE和AFTER。 在行級觸發器中,為了獲得某列在操作前后的數據,提供兩種特殊標識符:OLD和:NEW,通過:OLD.column_name的形式可以獲取該列的舊數據,而通過:NEW.colum_name可以獲取該列的新數據,INSERT觸發器只能用:NEW,DELETE觸發器只能用:OLD,UPDATE觸發器可以用:OLD和:NEW。 注意:如果創建時,不指定FOR EACH ROW,則為與語句級觸發器,所有受影響的數據只處罰一次,因此無法使用:NEW和:OLD獲取某列的新舊數據。 4、INSTEAD OF觸發器 執行一個替代操作來代替觸發事件的操作,而觸發事件本身不會被執行。不過oracle中的INSTEAD OF觸發器不能針對表,只能針對視圖。 5、系統事件觸發器 系統事件觸發器是指由數據庫系統事件觸發的觸發器,支持的系統事件如下: 系統事件 說明 LOGOFF 用戶從數據庫注銷 LOGON 用戶登錄數據庫 SERVERERROR 服務器發生錯誤 SHUTDOWN 關閉數據庫實例 STARTUP 打開數據庫實例 注:對于LOGOFF和SHUTDOWN事件只能創建BEFORE觸發器,對于LOGON、SERVERERROR和STARTUP事件只能創建AFTER觸發器。 創建系統觸發器需要使用ON DATABASE子句,表示創建的觸發器是數據庫級觸發器。創建系統事件觸發器需要用戶具有DBA權限。 6、DDL觸發器 DDL觸發器由DDL語句觸發,可分為:BEFORE觸發器和AFTER觸發器,針對事件包含CREATE、ALTER、DROP、ANALYZE、GRANT、COMMENT、REVOKE、RENAME、TRUNCATE、AUDIT、NOTAUDIT、ASSOCIATE STATISTICS和DISASSOCIATE STATISTICS。 創建DDL觸發器需要用戶具有DBA權限。 7、禁用與啟用觸發器 創建時使用ENABLE與DISABLE關鍵字制定觸發器初始裝填為啟用或禁用,默認為ENABLE。需要時也可使用ALTER TRIGGER語句修改觸發器的狀態,如下: ALTER TRIGGER trigger_name ENABLE | DISABLE ; 如果修改某個表上所有觸發器的狀態,可用如下形式: ALTER TABLE table_name ENABLE | DISABLE ALL TRIGGERS ; 8、修改與刪除觸發器 修改刪除觸發器只需要在 CREATE TRIGGER語句中添加OR REPLACE關鍵字。 刪除觸發器需要使用DROP TRIGGER語句,具體如下: DROP TRIGGER trigger_name; 包 1、創建包 程序包是對相關過程、函數、變量、游標和異常等對象的封裝,程序包由規范和主體兩部分組成,程序包規范:聲明類型、變量、常量、異常、游標和子程序等元素條目(不包含這些元素的實際代碼);程序包主體:用于實現在程序包規范中定義的游標、子程序(包含了元素的實際代碼)。包規范中的條目為共有項目,可供所有的數據庫用戶訪問;而包體中創建的規范中沒有提到的項目,屬于私有項目,只能在包體中使用。 1)、創建包規范 創建包規范使用CREATE PACKAGE語句,如下: CREATE [ OR REPLACE ] PACKAGE package_name { IS | AS } package_specification ; END package_name; 說明: package_name:創建的包名 package_specification:用于列出用戶可以使用的公共存儲過程、函數、類型和對象。 2)、創建包體 創建包體需要使用CREATE PACKAGE BODY語句,并且在創建的時候需要指定已創建的包,如下: CREATE [ OR REPLACE ] PACKAGE BOODY package_name { IS | AS } package_body ; END package_name ; 2、調用包 調用程序包中的元素時,采用如下形式: package_name.[ element_name ] ; element_name:表示元素名稱,可以使存儲過程名、函數名、變量名和常量名等。 注:程序包中可以定義公有常量和變量,使用的DBMS_OUTPUT.PUT_LINE輸出結果語句,DBMS_OUTPUT是系統定義的包,PUT_LINE是該包的存儲過程。 3、刪除包 使用DEOP PACKAGE語句,如果程序包被刪除,則包體也被自動刪除。如下: DROP PACKAGE package_name ; ? | |||||||
? | |||||||
? | |||||||
? |
?