一、存储过程介绍和案例1
1 ---修改表字段 2 alter table emp modify deptno not null; 3 4 --注意:存储过程不会报出具体哪行报错,所以要仔细仔细再仔细 5 --1.创建存储过程,完成添加员工的信息。包括编号、名称、薪水、工种和部门编号。 6 --or replace表示如果有已经存在的存储过程则要覆盖 7 create or replace procedure add_emp( 8 v_eno number, --参数,雇员编号 9 v_ename varchar2, --参数,雇员姓名 10 v_job varchar2 default 'clerk', --参数,工作 11 v_mgr number, --参数,领导编号 12 v_hiredate date, --参数,雇佣日期 13 v_sal number, --参数,基本工资 14 v_comm number, --参数,奖金 15 v_dno number --参数,部门编号 16 ) 17 is 18 emp_null_error exception; --定义异常变量 19 20 --非预定义异常,前提是:deptno列非空,插入控制会报错 21 22 pragma exception_init(emp_null_error, -1400); --定义异常变量 23 24 --非预定义异常,前提是:deptno列非空,插入控制会报错 25 emp_no_deptno exception; 26 pragma exception_init(emp_no_deptno, -2291); 27 begin 28 insert into emp values(v_eno,v_ename,v_job,v_mgr,v_hiredate,v_sal,v_comm,v_dno); 29 exception 30 when dup_val_on_index then 31 raise_application_error(-20000,'该雇员已经存在'); 32 when emp_null_error then 33 raise_application_error(-20001,'部门编号不能为空'); 34 when emp_no_deptno then 35 raise_application_error(-20002,'不存在该部门编号'); 36 end; 37 / 38 39 --2.用命令调用存储过程 40 --(1)按照位置传递参数,参数位置固定 41 --正确调用 42 exec add_emp(1113,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,10); 43 44 --①写不存在的部门编号 45 SQL> exec add_emp(1114,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,33); 46 47 --输出内容 48 BEGIN add_emp(1114,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,33); END; 49 50 * 51 第 1 行出现错误: 52 ORA-20002: 不存在该部门编号 53 ORA-06512: 在 "SCOTT.ADD_EMP", line 29 54 ORA-06512: 在 line 1 55 56 --②写一个已存在的员工 57 exec add_emp(1113,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,10); 58 59 --输出内容 60 BEGIN add_emp(1113,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,10); END; 61 62 * 63 第 1 行出现错误: 64 ORA-20000: 该雇员已经存在 65 ORA-06512: 在 "SCOTT.ADD_EMP", line 25 66 ORA-06512: 在 line 1 67 68 69 70 --(2)按照名称传递参数,参数位置不固定 71 exec add_emp(v_dno=>20,v_eno=>1113,v_ename=>'holly',v_job=>'mary',v_mgr=>7799,v_hiredate=>to_date('2015-5-6','yyyy-mm-dd'),v_sal=>2300, v_comm=>300 ); 72 73 --(3)混合方式传递参数,参数位置不固定 74 exec add_emp(1114,v_ename=>'holly',v_job=>'mary',v_mgr=>7799,v_hiredate=>to_date('2015-5-6','yyyy-mm-dd'),v_sal=>2300,v_comm=>300, v_dno=>20); 75 76 77 78 --(4).在plsql块中调用 79 --(4).1在pl/sql块中按位置调用存储雇员的存错过程 80 set serverout on 81 declare 82 83 emp_20001 exception; 84 pragma exception_init(emp_20001,-20001); 85 86 emp_20000 exception; 87 pragma exception_init(emp_20000,-20000); 88 89 emp_20002 exception; 90 pragma exception_init(emp_20002,-20002); 91 92 begin 93 --异常,部门不存在 94 add_emp(2111,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,66); 95 96 --正确,按位置传递参数 97 add_emp(2111,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,10); 98 99 --异常,雇员编号重复 100 add_emp(2111,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,10); 101 102 --异常,部门为空 103 add_emp(2111,'zzy','mary',7799,to_date('2015-5-6','yyyy-mm-dd'),2300,300,null); 104 105 exception 106 107 when emp_20000 then 108 dbms_output.put_line('emp_20000的雇员编号不能重复'); 109 110 when emp_20001 then 111 dbms_output.put_line('emp_20001的部门编号不能空'); 112 113 when emp_20002 then 114 dbms_output.put_line('emp_20002不存在该部门编号'); 115 116 when others then 117 dbms_output.put_line('出现了其他异常错误'); 118 end; 119 / 120 raise emp_20001; 121 122 --(4).2在pl/sql块中按名字调用存储雇员的存错过程 123 set serverout on 124 declare 125 emp_20000 exception; 126 pragma exception_init(emp_20000,-20000); 127 emp_20001 exception; 128 pragma exception_init(emp_20001,-20001); 129 emp_20002 exception; 130 pragma exception_init(emp_20002,-20002); 131 132 begin 133 --正确,按位置传递参数 134 add_emp(v_dno>=10,v_eno>=2111,v_ename>='zzy',v_job>='mary',v_mgr>=7799,v_hiredate>=to_date('2015-5-6','yyyy-mm-dd'),v_sal>=2300,v_comm>=300); 135 136 --异常,雇员编号重复 137 add_emp(v_dno>=10,v_eno>=2111,v_ename>='zzy',v_job>='mary',v_mgr>=7799,v_hiredate>=to_date('2015-5-6','yyyy-mm-dd'),v_sal>=2300,v_comm>=300); 138 139 --异常,部门为空 140 add_emp(v_dno>=null,v_eno>=2111,v_ename>='zzy',v_job>='mary',v_mgr>=7799,v_hiredate>=to_date('2015-5-6','yyyy-mm-dd'),v_sal>=2300,v_comm>=300); 141 142 --异常,部门不存在 143 add_emp(v_dno>=66,v_eno>=2111,v_ename>='zzy',v_job>='mary',v_mgr>=7799,v_hiredate>=to_date('2015-5-6','yyyy-mm-dd'),v_sal>=2300,v_comm>=300); 144 exception 145 when emp_20000 then 146 dbms_output.put_line('emp_20000的雇员编号不能重复'); 147 when emp_20001 then 148 dbms_output.put_line('emp_20001的部门编号不能空'); 149 when emp_20002 then 150 dbms_output.put_line('emp_20002不存在该部门编号'); 151 when others then 152 dbms_output.put_line('出现了其他异常错误'); 153 end; 154 / 155 156 --3.存储过程的参数模式in,out 157 --创建存储过程 158 create or replace procedure QueryEmp 159 (v_empno in emp.empno%type, 160 v_ename out emp.ename%type, 161 v_sal out emp.sal%type) 162 as 163 begin 164 select ename,sal into v_ename,v_sal 165 from emp 166 where empno=v_empno; 167 dbms_output.put_line('温馨提示:编码为'||v_empno||'的员工已经查到!'); 168 exception 169 when no_data_found then 170 dbms_output.put_line('温馨提示:雇员不存在!'); 171 when others then 172 dbms_output.put_line('出现了其他异常错误'); 173 end QueryEmp; 174 / 175 176 --调用存储过程 177 declare 178 v1 emp.ename%type; 179 v2 emp.sal%type; 180 begin 181 QueryEmp(7788,v1,v2); 182 dbms_output.put_line('姓名:'||v1); 183 dbms_output.put_line('工资:'||v2); 184 185 QueryEmp(7900,v1,v2); 186 dbms_output.put_line('姓名:'||v1); 187 dbms_output.put_line('工资:'||v2); 188 189 QueryEmp(1111,v1,v2); 190 dbms_output.put_line('姓名:'||v1); 191 dbms_output.put_line('工资:'||v2); 192 end; 193 / 194 195 --输出结果 196 温馨提示:编码为7788的员工已经查到! 197 姓名:SCOTT 198 工资:3000 199 温馨提示:编码为7900的员工已经查到! 200 姓名:JAMES 201 工资:950 202 温馨提示:雇员不存在! 203 姓名: 204 工资: 205 PL/SQL 过程已成功完成。 206 207 --4.创建带in out 参数过程 208 --创建存储过程 209 create or replace procedure swap(p1 in out number,p2 in out number) 210 is 211 v_temp number; 212 begin 213 v_tem:=p1; 214 p1:=p2; 215 p2:=v_temp; 216 end; 217 / 218 219 --调用存储过程 220 set serverout on 221 declare 222 num1 number:=100; 223 num2 number:=200; 224 begin 225 swap(num1,num2); 226 dbms_output.put_line('num1='||num1); 227 dbms_output.put_line('num2='||num2); 228 end; 229 /