<!-- /* Font Definitions */ @font-face {font-family:宋體; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋體"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:564801337; mso-list-type:hybrid; mso-list-template-ids:900353054 1025824976 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt;} @list l1 {mso-list-id:779495279; mso-list-type:hybrid; mso-list-template-ids:1660293484 -122231848 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l1:level1 {mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt;} @list l2 {mso-list-id:2133163782; mso-list-type:hybrid; mso-list-template-ids:1230665714 1538167440 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l2:level1 {mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->
一:開發過程。
過程用於執行特定操作,可以指定輸入參數,也可以指定輸出參數。
1.建立過程帶有IN參數。不指定默認爲IN參數。
CREATE OR REPLACE PROCEDURE add_employee
(eno NUMBER,name VARCHAR2,sal NUMBER,job VARCHAR2 DEFAULT 'CLERK',dno NUMBER)
IS
e_integrity EXCEPTION;
PRAGMA EXCEPTION_INIT(e_integrity,-2291);
BEGIN
INSERT INTO emp(empno,ename,sal,job,deptno)
VALUES(eno,name,sal,job,dno);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
RAISE_APPLICATION_ERROR(-20000,'僱員號不能重複');
WHEN e_integrity THEN
RAISE_APPLICATION_ERROR(-20001,'部門號不存在');
END;
輸入重複僱員號:
exec add_employee(1111,'CLARK',2000,'MANAGER',10)
begin add_employee(1111,'CLARK',2000,'MANAGER',10); end;
ORA-20000: 僱員號不能重複自定義錯誤號
2. 建立過程帶有OUT參數
CREATE OR REPLACE PROCEDURE query_employee
(eno NUMBER,name OUT VARCHAR2,salary OUT NUMBER)
IS
BEGIN
SELECT ename,sal INTO name,salary FROM emp
WHERE empno=eno;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000,'僱員不存在');
END;
SQL> var name VARCHAR2(10)
SQL> var salary NUMBER
SQL> exec query_employee(7788,:name,:salary)
begin query_employee(7788,:name,:salary); end;
ORA-20000: 僱員不存在
ORA-06512: 在 "SYS.QUERY_EMPLOYEE", line 9
ORA-06512: 在 line 2
var name VARCHAR2(10)
SQL> var salary NUMBER
SQL> exec query_employee(7369,:name,:salary)
PL/SQL procedure successfully completed
name
---------
SMITH
salary
---------
3600
3.帶有IN OUT 參數
CREATE OR REPLACE PROCEDURE compute
(num1 IN OUT NUMBER,num2 IN OUT NUMBER)
IS
v1 NUMBER;
v2 NUMBER;
BEGIN
v1:=num1/num2;
v2:=MOD(num1,num2);
num1:=v1;
num2:=v2;
END;
SQL> var n1:=100 NUMBER
SQL> var n2:30 NUMBER
SQL> exec compute(:n1,:n2)
4.參數傳遞的三種方式
1.位置傳遞(如上)
2.名稱傳遞
CREATE OR REPLACE PROCEDURE add_dept
(dno NUMBER,dname VARCHAR2 DEFAULT NULL,loc VARCHAR2 DEFAULT NULL)
IS
BEGIN
INSERT INTO dept VALUES(dno,dname,loc);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
RAISE_APPLICATION_ERROR(-20000,'部門號不能重複');
END;
exec add_dept(dname=>'SALES',dno=>70);
3.混合傳遞
5.查看過程源代碼
SELECT text FROM user_source WHERE name='ADD_DEPT';
6.刪除過程
DROP PROCEDURE add_dept;
二:開發函數
函數用於返回特定數據,當經常需要使用SQL返回數據時可以定義函數
1. 函數:不帶參數
CREATE OR REPLACE FUNCTION get_user
RETURN varchar2
IS
v_user VARCHAR2(100);
BEGIN
SELECT username INTO v_user FROM user_users;
RETURN v_user;
END;
1.使用變量接受返回值
SQL> var v1 VARCHAR2(100)
SQL> exec :v1:=get_user
PL/SQL procedure successfully completed
v1
---------
SYS
2. SQL語句調用函數
select get_user FROM dual;
2.建立函數:帶有IN參數
CREATE OR REPLACE FUNCTION get_sal(name IN VARCHAR2)
RETURN NUMBER
AS
v_sal emp.sal%TYPE;
BEGIN
SELECT sal INTO v_sal FROM emp
WHERE upper(ename)=upper(name);
RETURN v_sal;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000,'該僱員不存在');
END;
SQL> var sal number
SQL> exec :sal:=get_sal('smith')
3. 建立函數:帶有OUT參數
CREATE OR REPLACE FUNCTION get_into
(name VARCHAR2,title OUT VARCHAR2)
RETURN VARCHAR2
AS
deptname dept.dname%TYPE;
BEGIN
SELECT a.job,b.dname INTO title,deptname
FROM emp a,dept b
WHERE a.deptno=b.deptno
AND upper(a.ename)=upper(name);
RETURN deptname;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000,'該僱員不存在');
END;
var job varchar2(20)
var dname varchar(20)
exec :dname:=get_into('smith',:job)
三:管理子程序
1. 列出當前子程序
col object_name format a20
SELECT object_name,created,status FROM user_objects
WHERE object_type IN ('PROCEDURE','FUNCTION');
習題:
1. 建立過程UPD_SHIPDATE,根據輸入的訂單號和交付日期,更新ORD表特定訂單的交付日期,然後調用該過程。當建立過程UPD_SHIPDATE時,實現
1.如果交付日期小於預定日期,則顯示自定義錯誤
2.如果訂單不存在,。。。。。
CREATE OR REPLACE PROCEDURE upd_shipdate(
2 id NUMBER,shipdate DATE)
3 IS
4 orddate DATE;
5 BEGIN
6 UPDATE ord SET ship_date=shipdate
7 WHERE ord_id=id RETURNING ord_date INTO orddate;
8 IF SQL%NOTFOUND THEN
9 RAISE_APPLICATION_ERROR(-20002,'該訂單不存在');
10 END IF;
11 IF shipdate < orddate THEN
12 ROLLBACK;
13 RAISE_APPLICATION_ERROR(-20001,'交付日期不能小於預定日期');
14 END IF;
END;