[i]环境:[/i]
[list]
[*]oracle数据库
[*]PL/SQL Developer
[*]测试库使用的是 学习分析函数删除冗余数据那个[tablename:test1]
[/list]
[i]1.创建个最简单的存储过程[/i]
SQL窗口执行:
打开测试窗口测试:
[i]2.增加简单的逻辑,和输出语句[/i]
在测试窗口中进行测试:
[i]3.查询一条记录,并把字段值保存进变量c1,c2[/i]
在测试窗口中进行测试:
[i]4.多记录查询,操作游标[/i]
[u]4.1 FOR循环游标[/u]
[u]4.2 Fetch 游标[/u]
[i]4.3带参数的游标[/i]
[i]5.增删改操作[/i]
[i]注释:[/i]
[u]@1. 存储过程中的IS,AS[/u]
[u]@2. %rowtype[/u]
[u]@3. %notfound[/u]
[list]
[*]oracle数据库
[*]PL/SQL Developer
[*]测试库使用的是 学习分析函数删除冗余数据那个[tablename:test1]
[/list]
[i]1.创建个最简单的存储过程[/i]
SQL窗口执行:
create or replace procedure p_test --创建一个名字为p_test的存储过程
(
p1 in number,--in表示该参数为输入参数,输出参数用out
p2 in number --最后一个参数声明最后无逗号
)
IS --这里用AS也可以,详见底部注释@1
c1 varchar2(25); --声明存储过程逻辑中用到的临时变量
c2 varchar2(25); --注意最后一个也有分号
begin
NULL; --如无内容必须写个NULL;
end p_test; --注意写上存储过程名
打开测试窗口测试:
call p_test(1,1) --测试脚本,后边无分号
[i]2.增加简单的逻辑,和输出语句[/i]
create or replace procedure p_test --创建一个名字为p_test的存储过程
(
p1 in number,--in表示该参数为输入参数,输出参数用out
p2 in number --最后一个参数声明最后无逗号
)
AS
c1 varchar2(25); --声明存储过程逻辑中用到的临时变量
c2 varchar2(25); --注意最后一个也有分号
begin
if p1 = p2 then --如果p1=p2则输出p1=p2
dbms_output.put_line('p1 = p2 !');
end if;
if p1 <> p2 then--如果p1=p2则输出p1!=p2
dbms_output.put_line('p1 != p2 !');
end if;
end p_test; --注意写上存储过程名
在测试窗口中进行测试:
call p_test(1,1) --输入参数相同时,DBMS输出p1=p2!
--call p_test(1,2)--输入参数不同时,DBMS输出p1!=p2!
[i]3.查询一条记录,并把字段值保存进变量c1,c2[/i]
create or replace procedure p_test(p1 in number, p2 in number)
AS
c1 varchar2(25);
c2 varchar2(25);
begin
SELECT code1,code2 into c1,c2 FROM test1 where id = 1;--将code1,code2的值分别保存进变量c1,c2
dbms_output.put_line('code1 = ' || c1);--输出变量c1的值
dbms_output.put_line('code2 = ' || c2);--输出变量c2的值
EXCEPTION --异常处理异常处理
WHEN NO_DATA_FOUND --查无结果的处
THEN dbms_output.put_line('NO DATA FOUND!'); --查无结果输出 NO DATA FOUND!
end p_test;
在测试窗口中进行测试:
call p_test(1,1) --输出结果为 code1 = 1
--code2 = a
[i]4.多记录查询,操作游标[/i]
[u]4.1 FOR循环游标[/u]
create or replace procedure p_test
(
p_in_code1 in varchar2
)
AS
vs_msg varchar2(4000); --记录异常信息
cursor cur_test
is--这里不能用AS,只能用IS,详细描述见注释@1
select * from test1 where code1 = p_in_code1;
begin
for cur in cur_test --游标变量在for循环游标中可以直接使用,不用另外声明
loop
dbms_output.put_line(cur.id ||' '||cur.code1||' '||cur.code2||' '||cur.code3);
end loop;
exception
when others then ---错误处理部分。OTHERS表示除了声明外的任意错误。SQLERRM是系统内置变量保存了当前错误的详细信息。
vs_msg := 'ERROR IN P_TEST('||p_in_code1||'):'||SUBSTR(SQLERRM,1,500);
Dbms_Output.put_line('异常警告!!!');
Dbms_Output.put_line('异常信息:' || vs_msg);
ROLLBACK;--发生异常,回滚事务
--将当前错误,记录到日志中
--insert into XXX(proc_name,error_info,op_date) values('p_test',vs_msg,SYSDATE);
--commit;
--return;
end p_test;
[u]4.2 Fetch 游标[/u]
create or replace procedure p_test
(
p_in_code1 in varchar2
)
AS
vs_msg varchar2(4000); --记录异常信息
cursor cur_test IS
select * from test1 where code1 = p_in_code1;
p_cur_test cur_test%rowtype;--定义一个游标变量,%rowtype说明见 注释@2
begin
open cur_test;
loop
fetch cur_test into p_cur_test;--提取一行数据到游标变量中
exit when cur_test%notfound;--取不到值跳出本次循环 ,%notfound 返回值说明见注释@3
dbms_output.put_line(p_cur_test.id ||' '||p_cur_test.code1||' '||p_cur_test.code2||' '||p_cur_test.code3);
end loop;
close cur_test;
exception
when others then
vs_msg := 'ERROR IN P_TEST('||p_in_code1||'):'||SUBSTR(SQLERRM,1,500);
Dbms_Output.put_line('异常警告!!!');
Dbms_Output.put_line('异常信息:' || vs_msg);
ROLLBACK;--发生异常,回滚事务
--将当前错误,记录到日志中
--insert into XXX(proc_name,error_info,op_date) values('p_test',vs_msg,SYSDATE);
--commit;
--return;
end p_test;
[i]4.3带参数的游标[/i]
create or replace procedure p_test
(
p_in_code1 in varchar2
)
AS
vs_msg varchar2(4000); --记录异常信息
cursor cur_test(p_cur test1.code1%type) --test1为数据库表名,code1是test1的一个字段,p_cur是定义的一个游标参数
IS
select * from test1 where code1 = p_cur;
p_cur_test cur_test%rowtype;--定义一个游标变量,%rowtype说明见 注释@2
begin
open cur_test(p_in_code1);--打开游标
loop
fetch cur_test into p_cur_test;--提取一行数据到游标变量中
exit when cur_test%notfound;--取不到值跳出本次循环 ,%notfound 返回值说明见注释@3
dbms_output.put_line(p_cur_test.id ||' '||p_cur_test.code1||' '||p_cur_test.code2||' '||p_cur_test.code3);
end loop;
close cur_test;--关闭游标
exception
when others then
vs_msg := 'ERROR IN P_TEST('||p_in_code1||'):'||SUBSTR(SQLERRM,1,500);
Dbms_Output.put_line('异常警告!!!');
Dbms_Output.put_line('异常信息:' || vs_msg);
ROLLBACK;--发生异常,回滚事务
--将当前错误,记录到日志中
--insert into XXX(proc_name,error_info,op_date) values('p_test',vs_msg,SYSDATE);
--commit;
--return;
end p_test;
[i]5.增删改操作[/i]
create or replace procedure p_test
(
p_in_id in integer,
p_in_code1 in varchar2,
p_in_code2 in varchar2,
p_in_code3 in number
)
AS
vs_msg varchar2(4000); --记录异常信息
begin
insert into test1(id,code1,code2,code3)values(p_in_id,p_in_code1,p_in_code2,p_in_code3); -- 新增记录 根据输入参数
Dbms_Output.put_line('新增数据' || sql%rowcount||'条。');
update test1 set id = p_in_id + 1,code1=p_in_code1||'zzz',code2=p_in_code2||'zz',code3=p_in_code3+1 where id =p_in_id;--修改记录
Dbms_Output.put_line('更新数据' || sql%rowcount||'条。');
delete from test1 where id = p_in_id + 1;--删除记录 根据ID
Dbms_Output.put_line('删除数据' || sql%rowcount||'条。');
commit;
exception
when others then ---错误处理部分。OTHERS表示除了声明外的任意错误。SQLERRM是系统内置变量保存了当前s错误的详细信息。
vs_msg := 'ERROR IN P_TEST('||p_in_id||'):'||SUBSTR(SQLERRM,1,500);
Dbms_Output.put_line('异常警告!!!');
Dbms_Output.put_line('异常信息:' || vs_msg);
ROLLBACK;--发生异常,回滚事务
--将当前错误,记录到日志中
--insert into XXX(proc_name,error_info,op_date) values('p_test',vs_msg,SYSDATE);
--commit;
--return;
end p_test;
[i]注释:[/i]
[u]@1. 存储过程中的IS,AS[/u]
--在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别,在游标(CURSOR)中只能用IS不能用AS。
[u]@2. %rowtype[/u]
--定义一个游标变量p_cur_test cur_test%ROWTYPE ,变量p_cur_test的类型为游标cur_test中的一行数据类型。
[u]@3. %notfound[/u]
--判读是否提取到值
--取到值cur_test%notfound 是false
--取不到值cur_test%notfound 是true
--或者写为: not cur_test%found
--四个常用属性:%found、%notfound、%isopen和%rowcount。