1.什么是存储过程:预先经过编译并存储在数据库中的一段sql语句的集合。
2.使用存储过程的优点:(1)已经编译过,调用时无需编译,提高工作效率。
(2)存放在数据库中,客户端通过存储过程的名字直接调用,减少网络流量,加快系统执行速度。
(3)减少sql注入,且有权限的其情况下才能调用存储过程,提高安全性。
(4)和编程相分离,业务发生变化,需要修改数据库的地方无需修改代码,直接修改存储过程,较方便。
3.使用存储过程的缺点:占用服务器较多资源,对服务器造成压力。
4.什么时候使用存储过程:业务逻辑复杂的时候。
5.怎么写存储过程:
(1)准备工作,创建表,插入数据,这里我用的是sqlplus
SQL> create table student( 2 id varchar2(11) primary key, 3 name varchar2(32), 4 age integer 5 ); Table created.
SQL> insert into student values('1','小明',10); SQL> insert into student values('2','小红',11); SQL> insert into student values('3','小蓝',12);
(2)-----------------------第一个简单的不带参数的存储过程-----------------------------------------------------
SQL> create or replace procedure studentcount 2 as student_count number(10); 3 begin 4 select count(1) into student_count from student; 5 dbms_output.put_line('总人数:'||student_count); 6 end; 7 /
create or replace :创建或替换,有的时候你不知道你要创建的存储过程存不存在可以用create or replace,不然会报错
procedure:存储过程关键字
as:用于定义变量的一个块,这里定义你要使用的变量
begin:存储过程开始,里面执行你的逻辑
dbms_output.put_line:用在begin..end之间,控制台输出 '||'是oracle用于字符串连接,如果没有打印出来,执行set serveroutput on;再调用存储过程就能打印出来
end:存储过程结束
调用方式(1):
SQL> set serveroutput on; SQL> begin 2 studentcount(); 3 end; 4 / 总人数:3 PL/SQL procedure successfully completed.
调用方式(2):
SQL> exec studentcount(); 总人数:3 PL/SQL procedure successfully completed.
(3)----------------带参数的存储过程------------------------------------------------------------------------------------
create or replace procedure studentinfo( id in varchar2, name varchar2, studentcount out varchar2 ) as begin select count(1) into studentcount from student where id=id and name=name; Dbms_Output.put_line('id为:'||id||'姓名为'||name||'的学生有'||studentcount||'位'); end;
参数说明:参数有3种类型,in,out,in out ,in是作为输入参数,当参数没有指定类型的时候就是in类型,out是输出参数,in out 既可以作为输入参数也可以作为输出参数。这里参数是不需要指明宽度的,in的宽度由外部调用的时候决定,out由存储过程内部决定。in类型的参数可以有默认值,out类型的参数不能有默认值,不然会报错。
调用:
SQL> set serveroutput on; SQL> declare scount varchar2(1); 2 begin 3 studentinfo('1','小明',scount); 4 end; 5 / id为:1姓名为小明的学生有3位 PL/SQL procedure successfully completed.
发现怎么有3位不对,把定义的id,name换个名字就好了,那么这里发现sql中where查询条件不能带上表的一样的字段名。
有的时候你不知道参数是什么类型,或者表里面字段类型会变,可以用%type来表示
create or replace procedure studentinfo2( sid in student.id%type, --表示和student表里id的字段类型 sname student.name%type,--表示和student表里name的字段类型 studentcount out varchar2 ) as begin select count(1) into studentcount from student where id=sid and name=sname; Dbms_Output.put_line('id为:'||sid||'姓名为'||sname||'的学生有'||studentcount||'位'); end;
***********返回一行数据的存储过程用%rowtype
create or replace procedure studentinfo3( sid in student.id%type, sname student.name%type, studentinfos out student%rowtype --匹配student表里的一行数据 ) as begin select * into studentinfos from student where id=sid and name=sname; Dbms_Output.put_line('id为'||studentinfos.id||'姓名为:'||studentinfos.name); end;
***********返回结果集(可以用游标)
create or replace procedure studentinfo4 (s_info out sys_refcursor) as begin open s_info for 'select * from student'; end;
调用:
SQL> declare 2 cur1 SYS_REFCURSOR; 3 i student%rowtype; 4 begin 5 studentinfo4(cur1); 6 loop 7 fetch cur1 into i; 8 exit when cur1%notfound;--检索到没有数据就退出循环 9 dbms_output.put_line('----------------:' || i.id); 10 end loop; 11 close cur1; 12 end; 13 / ----------------:1 ----------------:2 ----------------:3 PL/SQL procedure successfully completed.
查看自己写的存储过程:
select text from user_source where name=upper('你要查询的存储过程名称') and type=upper('procedure');
user_source 是存放oracle源代码的一个字典。
删除存储过程:
SQL> drop procedure studentinfo4;
这是目前本人对于oracle学习的一个总结,希望对你们有帮助,不对的地方请望指出,谢谢!