天天看点

oracle 存储过程基本语法

关键字: oracle 1.基本结构

CREATE OR REPLACE PROCEDURE 存储过程名字

(

    参数1 IN NUMBER,

    参数2 IN NUMBER

) IS

变量1 INTEGER :=0;

变量2 DATE;

BEGIN

END 存储过程名字

2.SELECT INTO STATEMENT

  将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条

  记录,否则抛出异常(如果没有记录抛出NO_DATA_FOUND)

  例子:

  BEGIN

  SELECT col1,col2 into 变量1,变量2 FROM typestruct where xxx;

  EXCEPTION

  WHEN NO_DATA_FOUND THEN

      xxxx;

  END;

  ...

3.IF 判断

  IF V_TEST=1 THEN

    BEGIN

       do something

    END;

  END IF;

4.while 循环

  WHILE V_TEST=1 LOOP

  BEGIN

 XXXX

  END;

  END LOOP;

5.变量赋值

  V_TEST := 123;

6.用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;

7.带参数的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;

8.用pl/sql developer debug

  连接数据库后建立一个Test WINDOW

  在窗口输入调用SP的代码,F9开始debug,CTRL+N单步调试

关于oracle存储过程的若干问题备忘

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

oracle 存储过程基本语法

select  a.appname  from  appinfo a; -- 正确

oracle 存储过程基本语法

select  a.appname  from  appinfo  as  a; -- 错 误

 也许,是怕和oracle中的存储过程中的关键字as冲突的问题吧

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

oracle 存储过程基本语法

   select  af.keynode  into  kn  from  APPFOUNDATION af  where  af.appid = aid  and  af.foundationid = fid; --  有into,正确编译

oracle 存储过程基本语法

   select  af.keynode  from  APPFOUNDATION af  where  af.appid = aid  and  af.foundationid = fid; --  没有into,编译报错,提示:Compilation 

oracle 存储过程基本语法

  Error: PLS - 00428 : an  INTO  clause  is  expected  in  this  SELECT  statement

oracle 存储过程基本语法
oracle 存储过程基本语法

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

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

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

oracle 存储过程基本语法

  select  keynode  into  kn  from  APPFOUNDATION  where  appid = aid  and  foundationid = fid; --  正确运行

oracle 存储过程基本语法

select  af.keynode  into  kn  from  APPFOUNDATION af  where  af.appid = appid   and  af.foundationid = foundationid ; --  运行阶段报错,提示

oracle 存储过程基本语法

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

oracle 存储过程基本语法

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

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

oracle 存储过程基本语法

create   table  A(

oracle 存储过程基本语法

id  varchar2 ( 50 )  primary   key   not   null ,

oracle 存储过程基本语法

vcount  number ( 8 )  not   null ,

oracle 存储过程基本语法

bid  varchar2 ( 50 )  not   null   --  外键 

oracle 存储过程基本语法

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

oracle 存储过程基本语法

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

oracle 存储过程基本语法

if  fcount  is   null  then

oracle 存储过程基本语法

    fcount: = 0 ;

oracle 存储过程基本语法

end  if ; 这样就一切ok了。

6.Hibernate调用oracle存储过程

oracle 存储过程基本语法

         this .pnumberManager.getHibernateTemplate().execute(

oracle 存储过程基本语法
oracle 存储过程基本语法

                 new  HibernateCallback()  ... {

oracle 存储过程基本语法

                     public  Object doInHibernate(Session session)

oracle 存储过程基本语法
oracle 存储过程基本语法

                             throws  HibernateException, SQLException  ... {

oracle 存储过程基本语法

                        CallableStatement cs  =  session

oracle 存储过程基本语法

                                .connection()

oracle 存储过程基本语法

                                .prepareCall( " {call modifyapppnumber_remain(?)} " );

oracle 存储过程基本语法

                        cs.setString( 1 , foundationid);

oracle 存储过程基本语法

                        cs.execute();

oracle 存储过程基本语法

                         return   null ;

oracle 存储过程基本语法

                    }

oracle 存储过程基本语法

                } );

示例代码:

import java.sql.*;

public class DBDeclareTest{

private Connection con = null;// 数据库连接

private java.sql.CallableStatement cs = null;//执行存储过程的接口

private int key;

private String name;

//在构造函数中构造连接

public DBDeclareTest(){

try {

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

con = DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=pubs","sa","");

System.out.println ("con ok");

    }

    catch (Exception ex) {

    ex.printStackTrace();

    }

}

//调用无返回值的存储过程

public void getOK1(){

try {

String sql="{call pro_mypro1(?,?)}";

cs = con.prepareCall(sql);

cs.setInt(1,key);

cs.setString(2,name);

cs.executeUpdate();

System.out.println ("执行成功,可以休息了。。。。");

cs.close();

con.close();

    }

    catch (Exception ex) {

    ex.printStackTrace();

    }

}

//调用有返回值的存储过程

public void getOK2(){

try {

String sql = "{call pro_mypro2(?,?)}";

cs = con.prepareCall(sql);

//设置output外部传参

cs.registerOutParameter(1,java.sql.Types.BIT);

cs.setString(2,name);

cs.execute();

//获得output外部传参的值

int numOut = cs.getInt(1);

if(numOut ==1){

System.out.println ("数据表存在");

}else{

System.out.println ("数据表不存在!!!");

}

cs.close();

con.close();

    }

    catch (Exception ex) {

    ex.printStackTrace();

    }

}

//返回结果集的存储过程

public void getOK3(){

try {

String sql = "{call pro_mypro3(?,?)}";

cs = con.prepareCall(sql);

//设置output外部传参

cs.registerOutParameter(1,java.sql.Types.BIT);

cs.setString(2,name);

boolean flag = cs.execute();

System.out.println (flag);

if(flag){

System.out.println ("OKOKOKO");

ResultSet rs = cs.getResultSet();

ResultSetMetaData rsmd =rs.getMetaData();

     int numberOfColumns = rsmd.getColumnCount();

while(rs.next()){

for(int i=0;i<numberOfColumns;i++)

{

System.out.println (rsmd.getColumnName(i)+"  ");

System.out.println (rs.getObject(i)+"  ");

}

}

}else

{

System.out.println ("表名不存在:"+cs.getBoolean(1));

}

cs.close();

con.close();

    }

    catch (Exception ex) {

    ex.printStackTrace();

    }

}

public void setKey(int k){

this.key = k;

}

public int getKey(){

return this.key;

}

public void setName(String n){

this.name = n;

}

public String getName(){

return this.name;

}

}