创建存储过程
CREATE OR REPLACE PROCEDURE TEST_COUNT AS
v_total number(10);
BEGIN
select count(*) into v_total from testtable;
dbms_output.put_line('总人数:'||v_total);
END TEST_COUNT;
CREATE OR REPLACE 的意思就是如果这个存储过程没有就创建(CREATE ),如果这个存储过程存在,那么就替换(REPLACE)。
v_total number(10)的意思就是声明一个变量v_total,它的类型是number(10).
BEGIN关键字,表示开始跟 END 存储过程的过程名字是固定的格式。
select count(*) into v_total from testtable;的意思是从testtable行数综合和赋值给v_total。
可以换成 select student_name into s_name from testtable,换句话说查询的结果是可以赋值给上面声明的变量,可以查询赋值一个,也可以查询多个赋值给多个变量,当然一般不这么做,因为还可以使用游标。
使用游标的存储过程
CREATE OR REPLACE PROCEDURE TEST_COUNT AS
CURSOR test_cursor is select t.id1,t.name from testtable t;
BEGIN
for test_record in test_cursor
loop
dbms_output.put_line(test_record.id1||test_record.name);//打印test_record和test_record.name
end loop;
END TEST_COUNT;
CURSOR test_cursor is select t.id1,t.name from testtable t;
声明一个游标 test_cursor (格式 Cursor XX is),游标的意思就类似我们编程语言中的集合,在这里他的结果就是把查询testtable中的t.id1和t.name赋值给游标test_cursor,接下来利用 loop循环(类似for函数)依次遍历出来。
带参数的存储过程
CREATE OR REPLACE PROCEDURE TEST_COUNT(p_id1 in varchar2 default'0') AS
v_name varchar2(20);
BEGIN
select t.name into v_name from testtable t where t.id1=p_id1;
dbms_output.put_line('姓名:'||v_name);
END TEST_COUNT;
要给存储过程带参数只需要在过程名后面加括号带参数,类似Java(function(param param1))这样子就可以了,当然参数要声明类型,带进来的参数在后面的存储过程中均可以直接使用。
拼接SQL还有使用动态游标
接下来进阶了,拼接SQL还有使用动态游标,因为之前的游标都是直接赋值的,不像其他一样先声明,后赋值,所以使用动态游标可以解决这个问题。
还是刚刚的带参数的存储过程,如果ID是空的,那我们不是查不到数据,所以我们可以实现先判断id是不是空,如果是空,那么不传参,如果有才传参。
CREATE OR REPLACE PROCEDURE TEST_COUNT(p_id1 in varchar2 default'0') AS
type ref_cursor is ref cursor; //类似C语言里面的typedef(个人见解)
t_result ref_cursor;//所以现在t_result就是一个 动态游标(其实还是游标)
t_sql varchar(100);//声明t_sql来拼接sql,切记sql在oracle是关键字
v_name varchar(50);
BEGIN
t_sql:='select t.name into v_name from testtable t where 1=1';//1-1是为了把where关键字代入。
if p_id1 is not null
t_sql:=t_sql||'where t_id1='||p_id1;
end if //if .... end if 固定格式
open t_result for t_sql //打开动态游标,其实就是把结果集赋值给t_result.
loop
fetch t_result into v_name;
exit when t_result%notfound;//当结果集没有什么影响就跳出循环
dbms_output.put_line(v_name);
end loop;
END TEST_COUNT;
返回结果集是游标
create or replace
package test_package
as
type cursorRef is ref cursor; --定义游标引用类型
procedure test_procedure(p_id number,cursor_ref out cursorRef);
end test_package;
第一步创建程序包,其实一般的存储过程都是先创建程序包的。
然后再来创建存储过程。
create or replace
PACKAGE BODY test_package IS
procedure test_procedure(p_id number,cursor_ref out cursorRef)// 因为是out的,所以这个cursor_ref是输出的也就是返回的游标,out关键字
BEGIN
open cursor_ref for select * from testtable t where t.id1=p_id;
end test_procedure;
end test_package;
select * from testtable t where t.id1 =1;
这样子调用就可以返回游标型的结果集。