DB开发之oracle存储过程
1. 存储过程格式
/* Formatted on 2011/1/17 13:20:44 (QP5 v5.115.810.9015) */
CREATE OR REPLACE procedure proc_trade(
v_tradeid in number, --交易id
v_third_ip in varchar2, --第三方ip
v_third_time in date , --第三方完成时间
v_thire_state in number , --第三方状态
o_result out number, --返回值
o_detail out varchar2 --详细描述
)
as
-- 定义变量
v_error varchar2(500);
begin
--对变量赋值
o_result:=0;
o_detail:='验证失败';
--业务逻辑处理
if v_tradeid >100 then
insert into table_name(...) values(...);
commit;
elsif v_tradeid < 100 and v_tradeid>50 then
insert into table_name(...) values(...);
commit;
else
goto log;
end if;
--跳转标志符,名称自己指定
<<log>>
o_result:=1;
--捕获异常
exception
when no_data_found
then
result := 2;
when dup_val_on_index
then
result := 3;
when others
then
result := -1;
end proc_trade;
在上面这个存储过程中使用了输入参数,并返回输出参数,这里的参数类型是我们自己指定的。 这种写法可行,但是最好使用%type 来获取参数的类型(table_name.column_name%TYPE)。 这样就不会出现参数类型的错误。
如:
CREATE OR REPLACE PROCEDURE 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:
CREATE OR REPLACE PROCEDURE proc_test
AS
CURSOR c1
IS
SELECT * FROM dat_trade;
BEGIN
FOR x IN c1
LOOP
DBMS_OUTPUT.put_line (x.id);
END LOOP;
END proc_test;
示例2:
CREATE OR REPLACE PROCEDURE proc_test
AS
BEGIN
FOR x IN (SELECT power_id FROM sys_power)
LOOP
DBMS_OUTPUT.put_line (x.power_id);
END LOOP;
END proc_test;
2.1. 2:根据数值进行循环
示例1:
CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)
AS
BEGIN
for x in 1..100 loop
dbms_output.put_line(x);
end loop;
END proc_test;
示例2:在过程里指定输入参数v_num. 在调用过程时指定循环次数。
CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)
AS
BEGIN
FOR x IN 1 .. v_num
LOOP
DBMS_OUTPUT.put_line (x);
END LOOP;
END proc_test;
2.2 loop 循环
LOOP
DELETE FROM orders
WHERE senddate < TO_CHAR (ADD_MONTHS (SYSDATE, -3),
'yyyy-mm-dd')
AND ROWNUM < 1000;
EXIT WHEN SQL%ROWCOUNT < 1;
COMMIT;
END LOOP;
这里的SQL%ROWCOUNT 是隐士游标。 除了这个,还有其他几个:%found,%notfound, %isopen。
2.3 while 循环
CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)
AS
i NUMBER := 1;
BEGIN
WHILE i < v_num
LOOP
BEGIN
i := i + 1;
DBMS_OUTPUT.put_line (i);
END;
END LOOP;
END proc_test;
3. 存储过程中的判断
判断也是存储过程中最常用的方法之一。
3.1 if ... elsif ... else ... 判断
CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)
AS
BEGIN
IF v_num < 10
THEN
DBMS_OUTPUT.put_line (v_num);
ELSIF v_num > 10 AND v_num < 50
THEN
DBMS_OUTPUT.put_line (v_num - 10);
ELSE
DBMS_OUTPUT.put_line (v_num - 50);
END IF;
END proc_test;
3.2 case ... when ... end case 判断
CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)
AS
BEGIN
case v_num
when 1 then
DBMS_OUTPUT.put_line (v_num);
when 2 then
DBMS_OUTPUT.put_line (v_num);
when 3 then
DBMS_OUTPUT.put_line (v_num);
else null;
end case;
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(然后当前游标所指向的行位置)
CREATE OR REPLACE PROCEDURE 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
ORDER BY id)
WHERE ROWNUM < checknum;
--循环游标
LOOP
FETCH ref_cursor INTO t_tmp;
EXIT WHEN ref_cursor%NOTFOUND;
-- DBMS_OUTPUT.put_line (t_tmp.id);
UPDATE table_name
SET state = 53
WHERE id = t_tmp.id;
COMMIT;
END LOOP;
CLOSE ref_cursor;
END proc_test;
五. 存储过程的调试
如果使用PL/SQL Developer 或者TOAD 工具的话,调试还是很方便的。 如果是在Sqlplus里,我们可以使用:
SQL>show errors
来查看错误。不过在开发中估计也很少有人直接使用sqlplus来写存储过程。 效率低,调试又麻烦。 还是使用工具方便点。我一直使用的是Toad的。
如果想在某处退出存储过程,直接使用Return;就可以了。 与存储过程编写相关的数组和游标, 这两块说起来还是有很多东西。 在上面的示例中, 也简单的举了几个有关游标与存储过程编写的例子。
总之,写代码都是都是费脑子的事,相比之下还是做管理DBA舒服点,虽然压力大很多,至少不用这么费心思去整理业务逻辑。
DB开发之oracle存储过程的更多相关文章
- DB开发之oracle
常用命令: select table_name from user_tables; //当前用户的表 select table_name from all_tables; //所有用户的表 sel ...
- 实用开发之-oracle表回滚到一个指定时间的操作语句
在开发或客户使用过程中,难免会出现误操作或脏数据,那么怎么迅速处理这个问题呢? 1.备份还原就用了,太麻烦. 就是使用ORACLE的备份功能,然后在还原,还原的时候新建一个库,然后使用dblink进行 ...
- DB开发之mysql
1. MySQL 4.x版本及以上版本提供了全文检索支持,但是表的存储引擎类型必须为MyISAM,以下是建表SQL,注意其中显式设置了存储引擎类型 CREATE TABLE articles ( id ...
- DB开发之postgresql
1.环境变量配置: PGLIB=/usr/local/pgsql/lib PGDATA=$HOME/data PATH=$PATH:/usr/local/pgsql/bin MANPATH=$MANP ...
- Android安全开发之ZIP文件目录遍历
1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在“../”的字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接s ...
- C# 获取 oracle 存储过程的 返回值1
/// <summary> /// 返回对应表的模拟自增字段值 /// </summary> /// <param name="tablename"& ...
- Android安全开发之WebView中的地雷
Android安全开发之WebView中的地雷 0X01 About WebView 在Android开发中,经常会使用WebView来实现WEB页面的展示,在Activiry中启动自己的浏览器,或者 ...
- Oracle 存储过程学习
转自:http://blog.chinaunix.net/uid-20495387-id-174394.html http://www.cnblogs.com/rootq/articles/11000 ...
- ArcGIS Engine开发之旅04---ARCGIS接口详细说明
原文:ArcGIS Engine开发之旅04---ARCGIS接口详细说明 ArcGIS接口详细说明... 1 1. IField接口(esriGeoDatabase)... 2 2. ...
随机推荐
- 【Redis】 make编译是提示 make cc Command not found
在linux系统上对redis源码进行编译时提示提示“make cc Command not found,make: *** [adlist.o] Error 127”. 这是由于系统没有安装gcc环 ...
- php array key 的存储规则
刚刚写程序遇到php数组取值的问题,发现字符串和数字取出来的是一样的. key 可以是 integer 或者string.value 可以是任意类型. 此外 key 会有如下的强制转换: 包含有合法整 ...
- Excel 2010 如何在Excel的单元格中加入下拉选项
http://jingyan.baidu.com/article/03b2f78c4ba8a05ea237ae95.html 第一步:打开excel文档,选中需加入下拉选项的单元格. 第二步:点击 ...
- 《FPGA那些事儿》原创教程总结
经过我们黑金工程师多年的不断努力,黑金原创教程已经达到了14部,包括: 第一部:[黑金原创教程]NIOSII那些事儿 http://www.heijin.org/forum.php?mod=viewt ...
- linux显示文件列表命令ls,使用ls --help列出所有命令参数
ls命令的相关参数 在提示符下输入ls --help ,屏幕会显示该命令的使用格式及参数信息: 先介绍一下ls命令的主要参数: -a 列出目录下的所有文件,包括以 . 开头的隐含文件. -A 显示除 ...
- 【Android】TextView动态设置android:drawableLeft|Right|Top|Bottom,SetColor
Android中有时需动态设置控件四周的drawble图片,这个时候就需要调用 setCompoundDrawables(left, top, right, bottom),四个参数类型都是drawa ...
- 微信小程序 --- 页面跳转
第一种:wx.navigateTo({}); 跳转: 注意:这种跳转回触发当前页面的 onHide 方法,将当前页面隐藏,然后显示跳转页面.所以可以返回,返回的时候触发 onShow方法进行显示: ( ...
- 沈阳网络赛D-Made In Heaven【k短路】【模板】
One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with her. However, Pucci ...
- 一个不需要Log4Net的写日志的简单方法
有些项目写日志时会选择大名鼎鼎的Log4Net.而在我们使用它时,总会出现一些诸如版本不匹配而造成的写日志失败的情况,还要改web.config,还要改AssemblyInfo.而且,它的失败,并不是 ...
- Oracle安装部署之 6节点11g cluster环境搭建
**********************集群规划*************************************** --配置主机,共需要8台主机,其中6台做grid集群,1台作为存储服 ...