Oracle 存储过程 使用示例 .
2013-09-27 09:15
429 查看
此文转自大虾DAVE 地址:/article/1449151.html 可以说我第一次数据库安装成功也是从他博客里学习的,在此表示下感谢
在这里说一条使用存储过程很重要的理由:存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
Oracle
存储过程定义和优点与函数区别
http://blog.csdn.net/tianlesoftware/archive/2010/01/27/5261364.aspx
Oracle
查看表存储过程触发器函数等对象定义语句的方法
http://blog.csdn.net/tianlesoftware/archive/2010/06/19/5679293.aspx
1. 存储过程格式
/* Formatted on 2011/1/17 13:20:44 (QP5 v5.115.810.9015) */
CREATEORREPLACEprocedure proc_trade(
v_tradeid
innumber,
--交易id
v_third_ip
invarchar2,
--第三方ip
v_third_time
indate,
--第三方完成时间
v_thire_state
innumber,
--第三方状态
o_result
outnumber,
--返回值
o_detail
outvarchar2
--详细描述
)
as
-- 定义变量
v_error
varchar2(500);
begin
--对变量赋值
o_result:=0;
o_detail:='验证失败';
--业务逻辑处理
if v_tradeid
>100then
insertinto table_name(...)values(...);
commit;
elsif v_tradeid
<100and v_tradeid>50then
insertinto table_name(...)values(...);
commit;
else
gotolog;
endif;
--跳转标志符,名称自己指定
<<log>>
o_result:=1;
--捕获异常
exception
whenno_data_found
then
result
:=2;
whendup_val_on_index
then
result
:=3;
whenothers
then
result
:=-1;
end proc_trade;
在上面这个存储过程中使用了输入参数,并返回输出参数,这里的参数类型是我们自己指定的。 这种写法可行,但是最好使用%type 来获取参数的类型(table_name.column_name%TYPE)。 这样就不会出现参数类型的错误。
如:
CREATEORREPLACEPROCEDURE
spdispsms(
aempid
IN otherinfo.empid%TYPE,
amsg
IN otherinfo.msg%TYPE,
abillno
IN otherinfo.billno%TYPE,
ainfotype
IN otherinfo.infotype%TYPE,
aopid
IN otherinfo.OPERATOR%TYPE,
ainfoid
OUT otherinfo.infoid%TYPE,
RESULT
OUT INTEGER
)
2. 存储过程中的循环
存储过程写的是业务逻辑,循环是常用的处理方法之一。
2.1 for ... in ... loop
循环
2.1.1:循环遍历游标
示例1:
CREATEORREPLACEPROCEDURE proc_test
AS
CURSOR c1
IS
SELECT
* FROMdat_trade;
BEGIN
FOR x
IN c1
LOOP
DBMS_OUTPUT.put_line
(x.id);
ENDLOOP;
END proc_test;
示例2:
CREATEORREPLACEPROCEDURE proc_test
AS
BEGIN
FOR x
IN(SELECT
power_id FROMsys_power)
LOOP
DBMS_OUTPUT.put_line
(x.power_id);
ENDLOOP;
END proc_test;
2.1. 2:根据数值进行循环
示例1:
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
BEGIN
for x
in1..100loop
dbms_output.put_line(x);
endloop;
END proc_test;
示例2:在过程里指定输入参数v_num.
在调用过程时指定循环次数。
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
BEGIN
FOR x
IN1.. v_num
LOOP
DBMS_OUTPUT.put_line
(x);
ENDLOOP;
END proc_test;
2.2 loop 循环
LOOP
DELETEFROMorders
WHERE senddate
<TO_CHAR(ADD_MONTHS(SYSDATE,-3),
'yyyy-mm-dd')
ANDROWNUM< 1000;
EXITWHENSQL%ROWCOUNT<
1;
COMMIT;
ENDLOOP;
这里的SQL%ROWCOUNT
是隐士游标。除了这个,还有其他几个:%found,%notfound, %isopen。
2.3 while 循环
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
i NUMBER:=1;
BEGIN
WHILE i
< v_num
LOOP
BEGIN
i
:= i +1;
DBMS_OUTPUT.put_line
(i);
END;
ENDLOOP;
END proc_test;
3. 存储过程中的判断
判断也是存储过程中最常用的方法之一。
3.1 if ... elsif ... else ...
判断
CREATEORREPLACEPROCEDUREproc_test(v_num
INNUMBER)
AS
BEGIN
IF v_num
<10
THEN
DBMS_OUTPUT.put_line
(v_num);
ELSIF v_num
>10AND v_num
<50
THEN
DBMS_OUTPUT.put_line
(v_num -10);
ELSE
DBMS_OUTPUT.put_line
(v_num -50);
ENDIF;
END proc_test;
3.2 case ... when ... end case
判断
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
BEGIN
case v_num
when1then
DBMS_OUTPUT.put_line
(v_num);
when2then
DBMS_OUTPUT.put_line
(v_num);
when3then
DBMS_OUTPUT.put_line
(v_num);
elsenull;
endcase;
END proc_test;
4. 游标
存储过程中使用游标也是很常见的。 这里的游标分两种:
4.1 Cursor型游标(不能用于参数传递)
这种方法具体参考 2.1.1:循环遍历游标中的示例。
4.2 SYS_REFCURSOR型游标
该游标是Oracle以预先定义的游标,可作出参数进行传递。
注意一点:SYS_REFCURSOR只能通过OPEN方法来打开和赋值
4.2.1 我们可以使用这种类似的游标来返回一个结果集:
CREATE OR REPLACE procedure proc_test(
checknum in number, --每次返回的数据量
ref_cursor out sys_refcursor --返回的结果集,游标
)
as
begin
open ref_cursor for select * from (select * from dat_trade where state=41 order by id) where rownum<checknum;
end proc_test;
/
SYS_REFCURSOR中可使用三个状态属性:
(1).
%NOTFOUND(未找到记录信息)
(2).
%FOUND(找到记录信息)
(3).
%ROWCOUNT(然后当前游标所指向的行位置)
CREATEORREPLACEPROCEDURE proc_test
(
checknum IN
NUMBER,--每次返回的数据量
ref_cursor OUT sys_refcursor
--返回的结果集,游标
)
AS
t_tmp table_name%ROWTYPE;
BEGIN
OPEN ref_cursor
FOR
SELECT
*
FROM
( SELECT
*
FROM
table_name
WHERE
state =41
ORDERBY
id)
WHERE
ROWNUM< checknum;
--循环游标
LOOP
FETCH ref_cursor
INTO t_tmp;
EXITWHEN ref_cursor%NOTFOUND;
-- DBMS_OUTPUT.put_line
(t_tmp.id);
UPDATE
table_name
SET
state =53
WHERE
id= t_tmp.id;
COMMIT;
ENDLOOP;
CLOSE ref_cursor;
END proc_test;
五. 存储过程的调试
如果使用PL/SQL Developer 或者TOAD 工具的话,调试还是很方便的。 如果是在Sqlplus里,我们可以使用:
SQL>show errors
来查看错误。不过在开发中估计也很少有人直接使用sqlplus来写存储过程。 效率低,调试又麻烦。 还是使用工具方便点。我一直使用的是Toad的。
如果想在某处退出存储过程,直接使用Return;就可以了。 与存储过程编写相关的数组和游标, 这两块说起来还是有很多东西。 在上面的示例中, 也简单的举了几个有关游标与存储过程编写的例子。
总之,写代码都是都是费脑子的事,相比之下还是做管理DBA舒服点,虽然压力大很多,至少不用这么费心思去整理业务逻辑。
在这里说一条使用存储过程很重要的理由:存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
Oracle
存储过程定义和优点与函数区别
http://blog.csdn.net/tianlesoftware/archive/2010/01/27/5261364.aspx
Oracle
查看表存储过程触发器函数等对象定义语句的方法
http://blog.csdn.net/tianlesoftware/archive/2010/06/19/5679293.aspx
1. 存储过程格式
/* Formatted on 2011/1/17 13:20:44 (QP5 v5.115.810.9015) */
CREATEORREPLACEprocedure proc_trade(
v_tradeid
innumber,
--交易id
v_third_ip
invarchar2,
--第三方ip
v_third_time
indate,
--第三方完成时间
v_thire_state
innumber,
--第三方状态
o_result
outnumber,
--返回值
o_detail
outvarchar2
--详细描述
)
as
-- 定义变量
v_error
varchar2(500);
begin
--对变量赋值
o_result:=0;
o_detail:='验证失败';
--业务逻辑处理
if v_tradeid
>100then
insertinto table_name(...)values(...);
commit;
elsif v_tradeid
<100and v_tradeid>50then
insertinto table_name(...)values(...);
commit;
else
gotolog;
endif;
--跳转标志符,名称自己指定
<<log>>
o_result:=1;
--捕获异常
exception
whenno_data_found
then
result
:=2;
whendup_val_on_index
then
result
:=3;
whenothers
then
result
:=-1;
end proc_trade;
在上面这个存储过程中使用了输入参数,并返回输出参数,这里的参数类型是我们自己指定的。 这种写法可行,但是最好使用%type 来获取参数的类型(table_name.column_name%TYPE)。 这样就不会出现参数类型的错误。
如:
CREATEORREPLACEPROCEDURE
spdispsms(
aempid
IN otherinfo.empid%TYPE,
amsg
IN otherinfo.msg%TYPE,
abillno
IN otherinfo.billno%TYPE,
ainfotype
IN otherinfo.infotype%TYPE,
aopid
IN otherinfo.OPERATOR%TYPE,
ainfoid
OUT otherinfo.infoid%TYPE,
RESULT
OUT INTEGER
)
2. 存储过程中的循环
存储过程写的是业务逻辑,循环是常用的处理方法之一。
2.1 for ... in ... loop
循环
2.1.1:循环遍历游标
示例1:
CREATEORREPLACEPROCEDURE proc_test
AS
CURSOR c1
IS
SELECT
* FROMdat_trade;
BEGIN
FOR x
IN c1
LOOP
DBMS_OUTPUT.put_line
(x.id);
ENDLOOP;
END proc_test;
示例2:
CREATEORREPLACEPROCEDURE proc_test
AS
BEGIN
FOR x
IN(SELECT
power_id FROMsys_power)
LOOP
DBMS_OUTPUT.put_line
(x.power_id);
ENDLOOP;
END proc_test;
2.1. 2:根据数值进行循环
示例1:
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
BEGIN
for x
in1..100loop
dbms_output.put_line(x);
endloop;
END proc_test;
示例2:在过程里指定输入参数v_num.
在调用过程时指定循环次数。
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
BEGIN
FOR x
IN1.. v_num
LOOP
DBMS_OUTPUT.put_line
(x);
ENDLOOP;
END proc_test;
2.2 loop 循环
LOOP
DELETEFROMorders
WHERE senddate
<TO_CHAR(ADD_MONTHS(SYSDATE,-3),
'yyyy-mm-dd')
ANDROWNUM< 1000;
EXITWHENSQL%ROWCOUNT<
1;
COMMIT;
ENDLOOP;
这里的SQL%ROWCOUNT
是隐士游标。除了这个,还有其他几个:%found,%notfound, %isopen。
2.3 while 循环
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
i NUMBER:=1;
BEGIN
WHILE i
< v_num
LOOP
BEGIN
i
:= i +1;
DBMS_OUTPUT.put_line
(i);
END;
ENDLOOP;
END proc_test;
3. 存储过程中的判断
判断也是存储过程中最常用的方法之一。
3.1 if ... elsif ... else ...
判断
CREATEORREPLACEPROCEDUREproc_test(v_num
INNUMBER)
AS
BEGIN
IF v_num
<10
THEN
DBMS_OUTPUT.put_line
(v_num);
ELSIF v_num
>10AND v_num
<50
THEN
DBMS_OUTPUT.put_line
(v_num -10);
ELSE
DBMS_OUTPUT.put_line
(v_num -50);
ENDIF;
END proc_test;
3.2 case ... when ... end case
判断
CREATEORREPLACEPROCEDURE proc_test
(v_num INNUMBER)
AS
BEGIN
case v_num
when1then
DBMS_OUTPUT.put_line
(v_num);
when2then
DBMS_OUTPUT.put_line
(v_num);
when3then
DBMS_OUTPUT.put_line
(v_num);
elsenull;
endcase;
END proc_test;
4. 游标
存储过程中使用游标也是很常见的。 这里的游标分两种:
4.1 Cursor型游标(不能用于参数传递)
这种方法具体参考 2.1.1:循环遍历游标中的示例。
4.2 SYS_REFCURSOR型游标
该游标是Oracle以预先定义的游标,可作出参数进行传递。
注意一点:SYS_REFCURSOR只能通过OPEN方法来打开和赋值
4.2.1 我们可以使用这种类似的游标来返回一个结果集:
CREATE OR REPLACE procedure proc_test(
checknum in number, --每次返回的数据量
ref_cursor out sys_refcursor --返回的结果集,游标
)
as
begin
open ref_cursor for select * from (select * from dat_trade where state=41 order by id) where rownum<checknum;
end proc_test;
/
SYS_REFCURSOR中可使用三个状态属性:
(1).
%NOTFOUND(未找到记录信息)
(2).
%FOUND(找到记录信息)
(3).
%ROWCOUNT(然后当前游标所指向的行位置)
CREATEORREPLACEPROCEDURE proc_test
(
checknum IN
NUMBER,--每次返回的数据量
ref_cursor OUT sys_refcursor
--返回的结果集,游标
)
AS
t_tmp table_name%ROWTYPE;
BEGIN
OPEN ref_cursor
FOR
SELECT
*
FROM
( SELECT
*
FROM
table_name
WHERE
state =41
ORDERBY
id)
WHERE
ROWNUM< checknum;
--循环游标
LOOP
FETCH ref_cursor
INTO t_tmp;
EXITWHEN ref_cursor%NOTFOUND;
-- DBMS_OUTPUT.put_line
(t_tmp.id);
UPDATE
table_name
SET
state =53
WHERE
id= t_tmp.id;
COMMIT;
ENDLOOP;
CLOSE ref_cursor;
END proc_test;
五. 存储过程的调试
如果使用PL/SQL Developer 或者TOAD 工具的话,调试还是很方便的。 如果是在Sqlplus里,我们可以使用:
SQL>show errors
来查看错误。不过在开发中估计也很少有人直接使用sqlplus来写存储过程。 效率低,调试又麻烦。 还是使用工具方便点。我一直使用的是Toad的。
如果想在某处退出存储过程,直接使用Return;就可以了。 与存储过程编写相关的数组和游标, 这两块说起来还是有很多东西。 在上面的示例中, 也简单的举了几个有关游标与存储过程编写的例子。
总之,写代码都是都是费脑子的事,相比之下还是做管理DBA舒服点,虽然压力大很多,至少不用这么费心思去整理业务逻辑。
相关文章推荐
- Oracle 存储过程 使用示例
- oracle job + 存储过程 的使用示例
- Oracle 存储过程 使用示例
- 数据库操作_连接SQL Server数据库示例;连接ACCESS数据库;连接到 Oracle 数据库示例;SqlCommand 执行SQL命令示例;SqlDataReader 读取数据示例;使用DataAdapter填充数据到DataSet;使用DataTable存储数据库表;将数据库数据填充到 XML 文件;10 使用带输入参数的存储过程;11 使用带输入、输出参数的存储过程示;12 获得数据库中表的数目和名称;13 保存图片到SQL Server数据库示例;14 获得插入记录标识号;Exce
- Oracle 存储过程 使用示例
- Oracle 存储过程 使用示例
- oracle使用sql语句增加字段示例(sql删除字段语句)_oracle
- oracle使用存储过程实现日志记录.sql
- hibernate里使用jdbc方式调用oracle带游标返回参数的简单分页存储过程
- Oracle expdp/impdp 使用示例
- MySQL,Oracle,DB2使用存储过程插入大数据
- 在 Oracle 产品中使用 .NET 存储过程
- MySQL FEDERATED引擎使用示例, 类似Oracle DBLINK.
- oracle作业调用存储过程(第一次使用,弱~~)
- Oracle中定义package以及存储过程的使用
- 从概念到示例—Oracle中操作存储过程
- 使用 ADO.NET 访问 Oracle 9i 存储过程
- ORACLE 定时运行存储过程经常使用时间间隔
- Oracle 使用RMAN COPY 移动 Datafile 位置 示例