declare no1 number:=19; no2 number:=19; begin if no1 > no2 then dbms_output.put_line(no1); elsif no1 < no2 then dbms_output.put_line(no2); else raise_application_error(-20000,'请输入两个不同的数值'); end if; end;
create or replace procedure pro_wenzi(no1 in number, no2 in number) is begin if no1 > no2 then dbms_output.put_line(no1); elsif no1 < no2 then dbms_output.put_line(no2); else raise_application_error(-20000,'请输入两个不同的数值'); end if; end;
call pro_wenzi(19,19);
begin pro_wenzi(18,19); end;
例:写一个存储过程,输入员工编号,打印员工姓名
1 2 3 4 5 6 7 8 9
create or replace procedure pro_xingming(no1 number) is v_emp emp%rowtype; begin select * into v_emp from emp where empno = no1; dbms_output.put_line(v_emp.ename); end;
declare v_emp emp%rowtype; xm varchar2(20); begin select * into v_emp from emp where empno = 7788; xm := v_emp.ename;---------要传出的参数得有赋值的步骤 dbms_output.put_line(xm); end;
create or replace procedure pro_xingming2(xm out varchar2) is v_emp emp%rowtype; begin select * into v_emp from emp where empno = 7788; xm := v_emp.ename;---------要传出的参数得有赋值的步骤 end;
declare v_xingming varchar2(100);--声明一个数据类型用于接收传出的参数 begin pro_xingming2(v_xingming);---调用中写一个数据类型接收传出的参数,名称可以跟出参 参数 一致,也可以不同 dbms_output.put_line(v_xingming); end;
declare no1 number :=7788; xz number; v_emp emp%rowtype; begin select*into v_emp from emp where empno=no1; xz:= v_emp.sal; dbms_output.put_line(xz); end;
createor replace procedure pro_xingmingxinzi(xmxz inout number) is v_emp emp%rowtype; begin select*into v_emp from emp where empno=xmxz; xmxz:= v_emp.sal; end;
declare xz number :=7788; begin dbms_output.put_line(xz); pro_xingmingxinzi(xz); dbms_output.put_line(xz); end;
declare shuzi2 number :=&数字;--1 begin pro(shuzi2);--2--4 dbms_output.put_line(shuzi2);--5 end;
5.多个参数in,out先传入再传出
例:写一个存储过程,传入一个员工编号,传出一个员工姓名
1 2 3 4 5 6 7 8 9 10 11 12
create or replace procedure pro_emp(xm out varchar2,no1 in number) is begin select ename into xm from emp where empno = no1; end;
declare xm varchar2(100); begin pro_emp(xm,7788); dbms_output.put_line(xm); end;
思考题:在存储过程中 入参与出参 的执行顺序与它俩谁在前面有关系吗?
在存储过程中,先执行入参,后执行出参,==跟位置没关系==。
二、在存储过程中使用游标
无参数传递
1 2 3 4 5 6 7 8 9 10 11
createor replace procedure pro_cur is cursor cursor_emp isselect*from emp; begin for v_emp in cursor_emp loop dbms_output.put_line(v_emp.ename ||' '|| v_emp.sal); end loop; end;
begin pro_cur(); end;
传入一个参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
create or replace procedure pro_cur(bm in int) is cursor cursor_emp is select * from emp where deptno = bm; begin for v_emp in cursor_emp loop dbms_output.put_line(v_emp.ename || ' ' || v_emp.sal); end loop; end;
begin pro_cur(20); end;
sys_refcursor --系统游标,这是一个数据类型
例:传入一个游标,打印出员工的姓名与薪资—传入一组数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
create or replace procedure pro_cur(cur in sys_refcursor) is--接收游标并打印 v_emp emp%rowtype; begin loop fetch cur into v_emp; exit when cur%notfound; dbms_output.put_line('员工姓名为:'||v_emp.ename||',员工薪资为:'||v_emp.sal); end loop; end;
declare--声明游标并赋值 cur_a sys_refcursor;--声明游标 begin open cur_a for select * from emp;--打开游标 pro_cur(cur_a);--调用存储过程--传递参数 close cur_a;--关闭游标 end;
例:传出一个游标,打印出员工的姓名与薪资—传出一组数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
create or replace procedure pro_cur(cur out sys_refcursor) is--打开游标并赋值 begin open cur for select * from emp;--打开游标 end;
declare--接收游标并打印 cur_a sys_refcursor;--声明游标 v_emp emp%rowtype; begin pro_cur(cur_a);--调用存储过程--打开游标 loop fetch cur_a into v_emp;--传递参数 exit when cur_a%notfound; dbms_output.put_line('员工姓名为:'||v_emp.ename||',员工薪资为:'||v_emp.sal); end loop; close cur_a;--关闭游标 end;
注意点:
1.存储过程可以在当前用户下–> all object –> procedures 文件夹中右键查看 2.存储过程写错了没有报错弹窗,但是存储过程名左上角有红色❌ 3.错误的存储过程调用时会报错 4.数据类型后面不要跟东西 5.想要打印传入的参数,打印中要写==参数名==
拓展题:
1、有表student(s_no, s_name, s_age, s_grade),其中s_no-学号,也是主键,是从1开始向上排的(例如:第一个学生学号是1,第二个是2,一次类推);s_name-学生姓名;s_age-学生年龄;s_grade-年级;这张表的数据量有几千万甚至上亿。一个学年结束了,我要让这些学生全部升一年级,即,让s_grade字段加1。这条sql,写出来如下: update student set s_grade=s_grade+1 但是我们直接运行这条sql,会因数据量太大会把数据库undo表空间撑爆,从而发生异常。那我们来写个存储过程,进行批量更新,我们每10万条提交一次。
1
2、现有学生表(学号 sid,姓名sname,所在系名xi_name) 选课表(课程号cid,学号 sid,老师tid,可容纳总人数all_student,已选人数checked,剩余可选人数 space_num) ① 编写一个程序,输入学号,返回学生姓名、所在系名,所选课程 ② 编写一个程序:向学生表插入一条数据,返回该学生可以选学的课程id ③ 创建选课表历史记录表(check_history),并创建一个触发器,当对选课表进行删、改时,将原数据添加到选课历史记录表中