一、子程序
子程序是已命名的PL/SQL塊,它們存儲在數據庫中,可以Wie它們指定參數,可以從任何數據庫客戶端和應用程序中調用它們。子程序包括存儲過程和函數。
子程序包括:
1、聲明部分:聲明部分包括類型、游標、常量、變量、異常和嵌套子程序的聲明。這些項都是局部的,在退出后就不復存在。
2、可執行部分:可執行部分包括賦值、控制執行過程以及操縱ORacle數據的語句。
3、異常處理部分: 異常處理部分包括異常處理程序,負責處理執行存儲過程中出現的異常。
子程序的有點:
1、模塊化:通過子程序,可以將程序分解為可管理的、明確的邏輯模塊。
2、可重用性:子程序在創建並執行后,就可以再任意數目的應用程序中使用。
3、可維護性:子程序可以簡化維護操作,因為如果一個子程序受到影響,則只需修改該子程序的定義。
4、安全性:用戶可以設置權限,使得訪問數據的唯一方式就是通過用戶提供的存儲過程和函數。不僅可以讓數據更安全,而且可以保證它的正確性。
二、存儲過程
存儲過程是執行某些操作的子程序,是執行特定任務的模塊。從根本上講,存儲過程就是明明的PLSQL塊,它可以被賦予參數,存儲在數據庫中,然后由一個應用程序或其他PLSQL程序調用。
1、創建存儲過程:
語法:
CREATE [OR REPLACE] PROCEDURE procedure_name
[(paraameter_list)]
{IS/AS}
[local_declarations]
BEGIN
executable_statements;
[EXCEPTION]
[exception_handlers]
END [procedure_name]
說明:
procedure_name:為存儲過程的名字;
paraameter_list:參數列表,參數中可以使用in和out表示輸入和輸出參數。可選
AS表示其他變量聲明,IS表示顯示游標聲明
local_declarations:局部聲明,可選
executable_statements:可執行語句
exception_handlers:異常處理語句,可選
OR REPLACE:可選。如果不包含,創建存儲過程如果存在會報錯,包含存在會替換。
例:添加員工信息
--添加員工信息 create or replace procedure add_emp( eno number, ename varchar2, job varchar2, mgr NUMBER, salary number, hiredate DATE, com NUMBER, dno number) is BEGIN dbms_output.put_line('添加員工信息'); INSERT INTO emp VALUES(eno,ename,job,mgr,hiredate,salary,com,dno); EXCEPTION WHEN OTHERS THEN dbms_output.put_line('添加員工失敗'); end add_emp;
注意:
存儲過程中只聲明類型,不指定長度。
AS后的變量聲明以;結束。
2、調用存儲過程:
語法:
exec[ute] procedure_name (parameters_list);
說明:
execute:執行命令,可以縮寫為exec。
procedure_name:存儲過程的名稱。
parameters_list:存儲過程的參數列表。c
調用存儲過程有兩種方式,命令行方式和PL/SQL方式。
1)命令行方式:打開命令行直接輸入存儲過程名稱進行調用。
EXEC ADD_EMP(8888,'zhangsan','clerk',7902,2000,SYSDATE,500,30);
2)PLSQL方式:必須在pl/sql塊中調用存儲過程,不使用EXEC關鍵字,直接存儲過程名稱即可。
BEGIN --PL/SQL方式,不需要使用exec add_emp(8989,'LISI','clerk',7902,1000,SYSDATE,NULL,30); END;
參數的傳遞方式:
1)按位置傳遞:
按照參數的書序,依次寫入參數內容。調用的參數順序和定義的參數順序必須一一對應。
EXEC ADD_EMP(8888,'zhangsan','clerk',7902,2000,SYSDATE,500,30);
2)按名稱傳遞:
按名稱調用時按名稱對應,名稱對應的關系最重要,次序不重要。
EXEC add_emp(ENO => 8989,ENAME => 'LISI',JOB => 'clerk',MGR => 7902,SALARY => 1000,HIREDATE => SYSDATE,COM => NULL,DNO => 30);
3)混合方式傳遞:
同時使用位置傳遞和參數傳遞,采用這種方式必須將位置參數放在名稱參數的前面,只要第一個采用了名稱傳遞法,后面所有的參數必須使用名稱傳遞法。
EXEC add_emp(8989,'LISI',JOB => 'clerk',MGR => 7902,SALARY => 1000,HIREDATE => SYSDATE,COM => NULL,DNO => 30);
3、存儲過程的參數模式:
存儲過程參數有三種模式:IN、OUT和IN OUT,即輸入、輸出、輸入/輸出。
定義存儲過程參數語法:
parameter_name [IN|OUT|IN OUT] dateType [{:= | default} expression]
注意:
1)參數IN模式是默認模式。如果未指定參數模式,則默認為IN。對於OUT和IN OUT參數,必須明確指定。
2)可以再參數列表中為IN參數指定默認值,OUT和IN OUT不可用。
帶OUT參數的存儲過程:
例:根據empno查詢員工信息返回。
CREATE OR REPLACE PROCEDURE QUERY_EMP( V_EMPNO IN EMP.EMPNO%TYPE, --輸入參數 V_ENAME OUT EMP.ENAME%TYPE, --輸出參數 V_SAL OUT EMP.SAL%TYPE) IS --輸出參數 BEGIN SELECT ename,sal INTO v_ename,v_sal FROM emp WHERE empno = v_empno; dbms_output.put_line('數據已查到'); END QUERY_EMP;
調用帶輸出參數的存儲過程,首先定義兩個變量保存輸出參數返回的內容。
DECLARE v_name emp.ename%TYPE; v_sal emp.sal%TYPE; BEGIN query_emp(7788,v_name,v_sal); dbms_output.put_line('name:'||v_name||' sal:'||v_sal); END;
帶IN OUT參數的存儲過程:
數據交換;
CREATE OR REPLACE PROCEDURE swap( v_num1 IN OUT NUMBER, v_num2 IN OUT NUMBER ) AS v_temp NUMBER; BEGIN v_temp := v_num1; v_num1 := v_num2; v_num2 := v_temp; END;
--調用 DECLARE v_n1 NUMBER := 10; v_n2 NUMBER := 20; BEGIN swap(v_n1,v_n2); dbms_output.put_line(v_n1||' '||v_n2); END;
4、存儲過程的訪問權限
存儲過程創建后,只有創建該存儲過程的用戶和管理員才能有權執行。其他用戶如果要調用該存儲過程,需要得到存儲過程的EXECUTE權限。
例:
--將swap的執行權限授予user1 GRANT EXECUTE ON swap TO user1; --將swap的執行權限授予user1,並且user1可以對其他用戶進行授權。 GRANT EXECUTE ON swap TO user1 WITH GRANT OPTION; --撤銷user1用戶的執行swap權限。 REVOKE EXECUTE ON swap FROM user1
5、刪除存儲過程
DROP procedure swap;
三、總結:
優點:
1、存儲過程增強了PL-SQL的功能和靈活性。
2、存儲過程保證了數據的完整性和安全性。
3、提高了sql語句的性能。
4、降低了網絡的通訊量。
缺點:
1、移植問題,不同的數據庫存儲過程語法不同。
2、重新編譯問題。更改有依賴的存儲過程也會重新編譯。
3、需求變更的問題。