oracle 存储过程的基本语法

1.oracle存储过程结构 
CREATE OR REPLACE PROCEDURE oracle存储过程名字
(
    参数1 IN NUMBER,
    参数2 IN NUMBER
) IS
变量1 INTEGER :=0;
变量2 DATE;
BEGIN
END oracle存储过程名字
 
2.无返回值的oracle存储过程
create or replace procedure xs_proc_no is
begin
  insert into xuesheng values (3, 'wangwu', 90, 90);
  commit;
end xs_proc_no;
 
3.有单个数据值返回的oracle存储过程
create or replace procedure xs_proc(temp_name in varchar2,
                                    temp_num  out number) is
  num_1 number;
  num_2 number;
begin
  select yu_wen, shu_xue
    into num_1, num_2
    from xuesheng
   where xing_ming = temp_name;
  --dbms_output.put_line(num_1 + num_2);
  temp_num := num_1 + num_2;
end;
其中,以上两种与sql server基本类似,而对于返回数据集时,上述方法则不能满足我们的要求。在Oracle中,一般使用ref cursor来返回数据集。示例代码如下:
 
4.有返回值的oracle存储过程(列表返回)
首先,建立我们自己的包。并定义包中的一个自定义ref cursor
create or replace package mypackage as
  type my_cursor is ref cursor;
end mypackage;
在定义了ref cursor后,可以书写我们的程序代码
create or replace procedure xs_proc_list(shuxue   in number,
                                         p_cursor out mypackage.my_cursor) is
begin
  open p_cursor for
    select * from xuesheng where shu_xue > shuxue;
end xs_proc_list;
 
5.SELECT INTO STATEMENT
  将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条
  记录,否则抛出异常(若没有记录则抛出NO_DATA_FOUND)
  例子: 
  BEGIN
  SELECT name,age into 变量1,变量2 FROM user where xxx;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
      xxxx;
  END;
  ...
 
6.IF 判断
  IF V_TEST=1 THEN
    BEGIN 
       do something
    END;
  END IF;
 
7.WHILE 循环
  WHILE V_TEST=1 LOOP
  BEGIN
 XXXX
  END;
  END LOOP;
 
8.变量赋值
  V_TEST := 123;
 
9.用FOR IN 使用cursor
  ...
  IS
  CURSOR cur IS SELECT * FROM xxx;
  BEGIN
 FOR cur_result in cur LOOP
  BEGIN
   V_SUM :=cur_result.列名1+cur_result.列名2
  END;
 END LOOP;
  END;
 
10.带参数的CURSOR
  CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE TYPEID=C_ID;
  OPEN C_USER(变量值);
  LOOP
 FETCH C_USER INTO V_NAME;
 EXIT FETCH C_USER%NOTFOUND;
    do something
  END LOOP;
  CLOSE C_USER;
 
11.用pl/sql developer debug
  连接数据库后建立一个Test WINDOW
  在窗口输入调用SP的代码,F9开始debug,CTRL+N单步调试

二,oracle存储过程的若干问题备忘

1.在oracle中,数据表别名不能加as,如:

select a.appname from appinfo a;-- 正确
select a.appname from appinfo as a;-- 错误
 也许,是怕和oracle中的存储过程中的关键字as冲突的问题吧

2.在存储过程中,select某一字段时,后面必须紧跟into,如果select整个记录,利用游标的话就另当别论了。

  select af.keynode into kn from APPFOUNDATION af where af.appid=aid and af.foundationid=fid;-- 有into,正确编译
  select af.keynode from APPFOUNDATION af where af.appid=aid and af.foundationid=fid;-- 没有into,编译报错,提示:Compilation 
  Error: PLS-00428: an INTO clause is expected in this SELECT  statement

3.在利用select...into...语法时,必须先确保数据库中有该条记录,否则会报出"no data found"异常。

   可以在该语法之前,先利用select count(*) from 查看数据库中是否存在该记录,如果存在,再利用select...into...

4.在存储过程中,别名不能和字段名称相同,否则虽然编译可以通过,但在运行阶段会报错

 select keynode into kn from APPFOUNDATION where appid=aid and foundationid=fid;-- 正确运行
select af.keynode into kn from APPFOUNDATION af where af.appid=appid and af.foundationid=foundationid;-- 运行阶段报错,提示
ORA-01422:exact fetch returns more than requested number of rows

5.在存储过程中,关于出现null的问题

假设有一个表A,定义如下:
create table  A(
id 
varchar2(50primary key not null
,
vcount 
number(8not null
,
bid 
varchar2(50not null -- 外键 

);
如果在存储过程中,使用如下语句:
select sum(vcount) into fcount from A where bid='xxxxxx';
如果A表中不存在bid="xxxxxx"的记录,则fcount=null(即使fcount定义时设置了默认值,如:fcount number(8):=0依然无效,fcount还是会变成null),这样以后使用fcount时就可能有问题,所以在这里最好先判断一下:
if fcount is null  then
    fcount:
=0
;
end 
if;
这样就一切ok了。

6.Hibernate调用oracle存储过程

        this .pnumberManager.getHibernateTemplate().execute(
                
new HibernateCallback() ...
{
                    
public
 Object doInHibernate(Session session)
                            
throws HibernateException, SQLException ...
{
                        CallableStatement cs 
=
 session
                                .connection()
                                .prepareCall(
"{call modifyapppnumber_remain(?)}"
);
                        cs.setString(
1
, foundationid);
                        cs.execute();
                        
return null
;
                    }

                }
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值