`
clq9761
  • 浏览: 587966 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

Oracle存储过程

 
阅读更多

一、 存储过程

1、定义
所谓存储过程(Stored Procedure),就是一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过
编译后存储在数据库系统中。在使用时候,用户通过指定已经定义的存储过程名字并给出相应的存储过程参数
来调用并执行它,从而完成一个或一系列的数据库操作。


2、存储过程的创建
Oracle存储过程包含三部分:过程声明,执行过程部分,存储过程异常。
(1)无参存储过程语法

create or replace procedure NoParPro
 as  //声明
 ;
 begin // 执行
 ;
 exception//存储过程异常
 ;
 end;

 

(2)带参存储过程实例

  create or replace procedure queryempname(sfindno emp.empno%type) 
  as
     sName emp.ename%type;
     sjob emp.job%type;
  begin
         ....
  exception
         ....
  end;

 

(3)带参数存储过程含赋值方式

 create or replace procedure runbyparmeters  
     (isal in emp.sal%type, 
      sname out varchar,
      sjob in out varchar)
  as 
  	icount number;
  begin
       select count(*) into icount from emp where sal>isal and job=sjob;
       if icount=1 then
         ....
       else
        ....
      end if;
 exception
      when too_many_rows then
      DBMS_OUTPUT.PUT_LINE('返回值多于1行');
      when others then
      DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS过程中出错!');
 end;

 

其中参数IN表示输入参数,是参数的默认模式。
OUT表示返回值参数,类型可以使用任意Oracle中的合法类型。
OUT模式定义的参数只能在过程体内部赋值,表示该参数可以将某个值传递回调用他的过程
IN OUT表示该参数可以向该过程中传递值,也可以将某个值传出去。

 

(4)存储过程中游标定义使用

as //定义(游标一个可以遍历的结果集) 
CURSOR cur_1 IS 
  SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,
  		 SUM(usd_amt)/10000 usd_amt_sn 
  FROM BGD_AREA_CM_M_BASE_T 
  WHERE ym >= vs_ym_sn_beg 
       AND ym <= vs_ym_sn_end 
  GROUP BY area_code,CMCODE; 
    
begin //执行(常用For语句遍历游标)		
FOR rec IN cur_1 LOOP 
  UPDATE xxxxxxxxxxx_T 
   SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn 
   WHERE area_code = rec.area_code 
   AND CMCODE = rec.CMCODE 
   AND ym = is_ym; 
END LOOP;

 

3、在Oracle中对存储过程的调用 

(1)过程调用方式一

declare
      realsal emp.sal%type;
      realname varchar(40);
      realjob varchar(40);
begin   //过程调用开始
	  realsal:=1100;
	  realname:='';
	  realjob:='CLERK';
	  runbyparmeters(realsal,realname,realjob);--必须按顺序
	  DBMS_OUTPUT.PUT_LINE(REALNAME||'   '||REALJOB);
END;  //过程调用结束

 

(2)过程调用方式二

declare
     realsal emp.sal%type;
     realname varchar(40);
     realjob varchar(40);
begin    //过程调用开始
     realsal:=1100;
     realname:='';
     realjob:='CLERK';
     --指定值对应变量顺序可变
     runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob);         
    DBMS_OUTPUT.PUT_LINE(REALNAME||'   '||REALJOB);
END;  //过程调用结束	

 

(3)过程调用方式三(SQL命令行方式下)

1、SQL>exec  proc_emp('参数1','参数2');//无返回值过程调用
2、SQL>var vsal number
     SQL> exec proc_emp ('参数1',:vsal);// 有返回值过程调用
      或者:call proc_emp ('参数1',:vsal);// 有返回值过程调用

 

4、JAVA调用Oracle存储过程

 

(1)不带输出参数情况,过程名称为pro1,参数个数1个,数据类型为整形数据

import  java.sql. * ; 
 public   class  ProcedureNoArgs{    
	 public   static   void  main(String args[])  throws  Exception{ 
		 //加载Oracle驱动  
		 DriverManager.registerDriver( new  oracle.jdbc.driver.OracleDriver()); 
		 //获得Oracle数据库连接  
		 Connection conn = DriverManager.getConnection
   		  ("jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd " );
   	     //创建存储过程的对象  
   		 CallableStatement c = conn.divpareCall( " {call pro1(?)} " );      
         //给Oracle存储过程的参数设置值 ,将第一个参数的值设置成188  
          c.setInt( 1 , 188 );      
         // 执行Oracle存储过程  
          c.execute(); 
          conn.close(); 
     }  
}

 

(2)带输出参数的情况,过程名称为pro2,参数个数2个,数据类型为整形数据,返回值为整形类型。

import java.sql.*; 
public class ProcedureWithArgs {   
	public static void main(String args[]) throws Exception{	 
	   //加载Oracle驱动 
	   DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); 
	   //获得Oracle数据库连接 
	   Connection conn = DriverManager.getConnection
	   ("jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd "); 
	   //创建Oracle存储过程的对象,调用存储过程 
	   CallableStatement c=conn.divpareCall("{call pro2(?,?)}");  
	   //给Oracle存储过程的参数设置值 ,将第一个参数的值设置成188 
	   c.setInt(1,188); 
	   //注册存储过程的第二个参数 
	   c.registerOutParameter(2,java.sql.Types.INTEGER);    
	   c.execute(); //执行Oracle存储过程 
	   //得到存储过程的输出参数值并打印出来
	   System.out.println (c.getInt(2)); 
	   conn.close(); 
	} 
}  

 

二、 函数


1、基本语法规则

 

 create or replace function (Name in type, Name in type, ...) 
 	return number 
   is
 	Result number;
  begin  
  	return (Result);
  end ;

 

2、具体事例(查询出empno=7935的sal值)

 create or replace function ret_emp_sal(v_ename varchar2)
	return number
  is
	v_sal number(7,2);
  begin
	select nvl(sal,0) into v_sal from emp where lower(ename)=lower(v_ename);
	return v_sal;
  end;

 

3、函数调用:

SQL> var vsla number
SQL> call ret_emp_sal('7935') into :vsal;

 

4、与存储过程的区别

(1)返回值的区别,函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有
(2)调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用.
(3)使用场景的区别,函数一般情况下是用来计算并返回一个计算结果
 而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等)

 

三、包
    包用于组合逻辑相关的过程和函数,它由包规范和包体两个部分组成。包规范用于定义公用的常量、变量、过程
和函数,创建包规范可以使用CREATE PACKAGE命令,创建包体可以使用CREATE PACKAGE BODY.


1、创建包规范

 create package emp_pkg is
 	procedure emp_update_ename(v_empno varchar2,v_ename varchar2);
 	function emp_get_sal(v_empno varchar2) return number;
 end;

 

2、创建包体

 create or replace package body emp_pkg
 is
 	// 存储过程
	procedure emp_update_ename
	(
		v_empno varchar2,
		v_ename varchar2
	)
	is
		vename varchar2(32);
	begin 
		update emp set ename=v_ename where empno=v_empno;
		commit;
		select ename into vename from emp where empno=v_empno;   
		dbms_output.put_line('雇员名称:'||vename);    
	end;
    // 函数
    function emp_get_sal
    (
    		v_empno varchar2
    )
    return number is
    	vsal number(7,2);
    begin
    	select sal into vsal from emp where empno=v_empno;
    return vsal;
    end;
end;

 

3、包调用
   在没有创建包规范就创建包体,会失败,要使用包,必须先创建包规范,然后在创建包体。
当要调用包的过程和函数时,在过程和函数的名称前加上包名作为前缀(包名.子程序名称),
而如果要访问其他方案的包时需要在包的名称前加上方案的名称(方案名称.包名.子程序名称)。


(1)调用包函数

SQL> var vsla number
SQL> call emp_pkg.emp_get_sal('7935') into :vsal;

 

(2)调用包存储过程

SQL> exec emp_pkg.emp_update_ename('7935','helong');

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics