<!-- /* 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;