您的位置:首页 > 数据库 > Oracle

存储过程

2014-02-26 13:31 239 查看
一,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.name from user a;-- 正确

select a.name from user as a;-- 错误

应该是防止和oracle存储过程中的关键字as有冲突,才会这样规定吧!

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

select u.name into kn from user u where u.userid=uid and u.fatherid=fid;-- 有into,正确编译

select u.name from user u where u.userid=uid and u.fatherid=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.oracle在存储过程中,别名不能和字段名称相同,否则虽然编译可以通过,但在运行阶段会报错

select name into kn from user where userid=aid and fatherid=fid;-- 正确运行

select u.name into kn from user u where u.userid=userid and u.fatherid=fatherid;-- 运行时报错,提示

ORA-01422:exact fetch returns more than requested number of rows

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

假设有一个表A,定义如下:

create table user(

id varchar2(50) primary key not null,

age number(5) not null,

fid varchar2(50) not null -- 外键

);

如果在oracle存储过程中,使用如下语句:

select sum(age) into fage from user where fid='xxxxxx';

如果user表中不存在fid="xxxxxx"的记录,则fage=null(即使fage定义时设置了默认值,如:fage number(5):=0依然无效,fage还是会变成null),这样以后使用fage时就可能有问题,所以在这里最好先判断一下:

if fage is null then

fage:=0;

end if;

这样就一切ok了。

6.java调用oracle存储过程。其中,关键是使用CallableStatement这个对象,代码如下:

String oracleDriverName = "oracle.jdbc.driver.OracleDriver";

// 以下使用的Test就是Oracle里的表空间

String oracleUrlToConnect = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";

Connection myConnection = null;

try {

Class.forName(oracleDriverName);

} catch (ClassNotFoundException ex) {

ex.printStackTrace();

}

try {

myConnection = DriverManager.getConnection(oracleUrlToConnect,

"xxxx", "xxxx");//此处为数据库用户名与密码

} catch (Exception ex) {

ex.printStackTrace();

}

try {

CallableStatement proc=null;

proc=myConnection.prepareCall("{call xs_proc(?,?)}");

proc.setString(1, "lisi");

proc.registerOutParameter(2, Types.NUMERIC);

proc.execute();

String teststring=proc.getString(2);

System.out.println(teststring);

} catch (Exception ex) {

ex.printStackTrace();

}

对于列表返回值的oracle存储过程,在上述代码中做简单修改。如下

CallableStatement proc=null;

proc=myConnection.prepareCall("{call getdcsj(?,?,?,?,?)}");

proc.setString(1, strDate);
proc.setString(2, jzbh);

proc.registerOutParameter(3, Types.NUMERIC);

proc.registerOutParameter(4, OracleTypes.CURSOR);

proc.registerOutParameter(5, OracleTypes.CURSOR);

proc.execute();

ResultSet rs=null;

int total_number=proc.getInt(3);

rs=(ResultSet)proc.getObject(4);

上述oracle存储过程修改完毕

7.Hibernate调用oracle存储过程

this.userManager.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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oracle commit procedure