oracle 存储过程及REF CURSOR的使用

基本使用方法及示例

1、基本结构:

    CREATE OR REPLACE PROCEDURE 存储过程名字
    (参数1 IN NUMBER,参数2 IN NUMBER)
    AS
    变量1 INTEGER :=0;
    变量2 DATE;
    BEGIN
    END 存储过程名字  

2、无参形式的procedure:

    --无参procedure
    create or replace procedure pro_no_param
    is
    begin
      dbms_output.put_line(‘the procedure without params‘);
    end pro_no_param;  

    --调用
    --one: 无参的procedure名字后面必须要();
    call pro_no_param();  

    --two:procedure名称后面可以没有();
    begin
      pro_no_param();
    end;  

3、参数类型为IN的procedure:

--有参procedure  只有IN类型
create or replace procedure pro_in_param(
       v_1 in number,
       v_2 in varchar2,
       v_3 in date
)
is
begin
  dbms_output.put_line(‘v1: ‘ || v_1 || ‘ v2: ‘ || v_2 || ‘ v2: ‘|| (to_char(v_3, ‘yyyy-mm-dd‘)));
end pro_in_param;  

begin
  pro_in_param(1, ‘chy‘, sysdate);
end;

4、参数类型为OUT的procedure:

    --有参procedure  只有OUT类型
    create or replace procedure pro_out_param(
           v1 out number,
           v2 out char
    )
    is
    begin
      v1 := 2;
      v2 := ‘andyChen‘;
    end pro_out_param;  

    --记得声明用于存放procedure的out值的变量
    --语句结束了一定记得结尾的 —— ;
    declare
      v_1 number;
      v_2 varchar2(200);
    begin
      pro_out_param(v_1, v_2);
      dbms_output.put_line(‘v1: ‘ || v_1 || ‘ v2: ‘ || v_2);
    end;  

5、参数类型同时为IN和OUT的procedure:

--同时为INOUT参数的procedure
--用同一变量接收传入的值然后将这个变量当作输出的值赋给执行时声明的变量
create or replace procedure pro_in_out_param(
       in_out_param in out varchar2
)
is
begin
      in_out_param := ‘in_out_param and ‘ || in_out_param;
end pro_in_out_param;   

declare
   in_out_param varchar2(222) := ‘detail param‘;
begin
   pro_in_out_param(in_out_param);
   dbms_output.put_line(in_out_param);
end; 

三:实例

    CREATE TABLE user_info
    (
     id   VARCHAR2(4) not null primary key,
     name VARCHAR2(15),
     pwd  VARCHAR2(15),
     address VARCHAR2(30)
    );  

    --创建一个添加用户的stored_procedure;
    create or replace procedure pro_addUser(
           n_id user_info.id%type,
           n_name user_info.name%type,
           n_pwd     user_info.pwd%TYPE,
           n_address user_info.address%TYPE
    )
    as
    begin
      --插入数据
      insert into user_info(id,name,pwd,address)
      values(n_id, n_name, n_pwd, n_address);
    end pro_addUser;  

    --调用、有变量需要声明的时候才有declare、没有就直接begin
    begin
        pro_addUser(‘1‘, ‘chy‘, ‘admin‘, ‘nanjin‘);
        if SQL%found then
          dbms_output.put_line(‘add successed‘);
        end if;
    end;  

    --根据id查询用户名和密码
    create or replace procedure pro_getUserInfo(
           n_id       user_info.id%type,
           n_name out user_info.name%type,
           n_pwd  out user_info.pwd%type
    )
    as
    begin
      select user_info.name, user_info.pwd into n_name, n_pwd
      from user_info
      where user_info.id=n_id;
    end pro_getUserInfo;  

    --调用
    declare
        v_id    user_info.id%type := ‘1‘;
        v_name  user_info.name%type;
        v_pwd   user_info.pwd%type;
    begin
        pro_getUserInfo(v_id, v_name, v_pwd);
        dbms_output.put_line(‘name: ‘ || v_name || ‘ pwd: ‘ || v_pwd);
    end;  

    -- 打印九九乘法表
    create or replace procedure pro_multiplication_table
    is
           i  integer;
           j  integer;
    begin
           for i in 1..9 loop
             for j in 1..9 loop
               if i>=j then
                 DBMS_output.put(To_Char(j)||‘*‘||to_char(i)||‘=‘||to_char(i*j)||‘   ‘);
               end if;
             end loop;
             DBMS_output.put_line(‘‘);
           end loop;
    end  pro_multiplication_table;        

    --调用
    call pro_multiplication_table();  

    --使用自定义游标、根据工作and薪水查询员工姓名
    create or replace procedure pro_getName(
           n_sal        emp.sal%type,
           n_ename  out emp.ename%type,
           n_job in out emp.job%type
    )
    is
           n_count number;
           cursor cur is select ename from emp where emp.sal > n_sal and emp.job=n_job;
           n_row  cur%rowtype;
    begin
           select count(*) into n_count from emp where emp.sal > n_sal and emp.job=n_job;
           if n_count > 1 then
             for n_row in cur loop
               DBMS_output.put_line(‘职工姓名为:‘||n_row.ename||‘    工作为:‘||n_job);
             end loop;
           else
               DBMS_output.put_line(‘未查到符合条件的记录!‘);
           end if;
    end  pro_getName;        

    -- 调用
    declare
       v_sal   emp.sal%type := 2000;
       v_job   emp.job%type :=‘MANAGER‘;
       v_ename emp.ename%type;
    begin
       pro_getName(v_sal, v_ename, v_job);
    end;     

    --ref cursor的使用
    --创建存放弱引用和强引用的cursor的包
    create or replace package refcursor_pkg
    as
    type weak_ref_cursor is ref cursor;
    type strong_ref_cursor is ref cursor return emp%rowtype;
    end refcursor_pkg;  

    --将弱引用的cursor作为结果返回
    create or replace procedure test(
           p_deptno in number,
           p_cursor out refcursor_pkg.weak_ref_cursor
    )
    is begin
           open p_cursor for select * from emp where deptno=p_deptno;
    end test;  

    /**或者不用包直接使用下面这种定义
    create or replace procedure test_1(
           p_deptno IN number,
           p_cursor OUT SYS_REFCURSOR
    )
    is
    begin
      open p_cursor FOR select *from emp where  deptno = p_deptno;
    end test_1;
    */  

    declare
        v_deptno number := 20;
        v_cursor refcursor_pkg.weak_ref_cursor;
        r_emp emp%rowtype;
    begin
        test(v_deptno, v_cursor);
        loop
          fetch v_cursor into r_emp;
          exit when v_cursor%notfound;
          dbms_output.put_line(‘empno: ‘ || r_emp.empno || ‘ ename: ‘ || r_emp.ename || ‘ job: ‘ || r_emp.job);
        end loop;
        close v_cursor;
    end;
    /**  

    //java中使用ref cursor  

    public void method() throws SQLException{
      Connection conn = getConnection();
      CallableStatement cstmt = null;
      ResultSet rs = null;
      int deptno = 10;
      Object temp;
      try{
          cstmt = conn.prepareCall("begin  test(?,?); end;");
          cstmt.setInt(1, deptno);
          cstmt.registerOutParameter(2, OracleTypes.CURSOR);
          cstmt.execute();
          rs = (ResultSet) cstmt.getObject(2);
          ResultSetMetaData rsm = rs.getMetaData();
          int columnCount = rsm.getColumnCount();
          while (rs.next()){
             for (int j=0;j< columnCount;j++){
                temp = rs.getObject(j+1);
             }
          }
      } finally {
          if (!rs==null){
            rs.close();
          }
          if (!stmt==null){
            stmt.close();
          }
          if (!conn==null){
            conn.close();
          }
      }
    }
    */    

原文地址:https://www.cnblogs.com/xwb583312435/p/9054844.html

时间: 2024-08-29 14:26:12

oracle 存储过程及REF CURSOR的使用的相关文章

oracle 游标变量ref cursor详解

oracle 游标变量ref cursor详解 分类: PL/SQL开发 2013-12-04 15:15 685人阅读 评论(0) 收藏 举报 oracleref cursor 一 介绍      像游标cursor一样,游标变量ref cursor指向指定查询结果集当前行.游标变量显得更加灵活因为其声明并不绑定指定查询. 其主要运用于PLSQL函数或存储过程以及其他编程语言java等程序之间作为参数传递.     不像游标的一点,游标变量没有参数.     游标变量具有以下属性:     (

java读取ORACLE 存储过程 返回游标(cursor) 格式 读取到List中

/**  * 执行存储过程(目前只支持返回一个游标) never null  *   * @param sql  *            执行的语句  * @param index  *            当前游标的下标  * @param obj  *            参数(用来替换sql语句中的?)  * @param rop  *            注册oracle的输出参数(注意,这里假如下标为1的是输入参数,为2的输出参数  *            则游标要以输出参数

Oracle ref cursor和sys_refcursor

1. 自定义 ref cursor 和 sys_refcursor; 2. sys_refcursor 做为参数传递结果集; 3. ref cursor 做为参数传递结果集;   1. 自定义 ref cursor 和 sys_refcursor: declare type df_ref is ref cursor; --定义 ref cursor rf df_ref; --声明 rf 是df_ref ename varchar2(30); begin open rf for 'select e

面试概率极大的Oracle存储过程

1.什么是存储过程.存储过程是数据库服务器端的一段程序,它有两种类型.一种类似于SELECT查询,用于检索数据,检索到的数据能够以数据集的形式返回给客户.另一种类似于INSERT或DELETE查询,它不返回数据,只是执行一个动作.有的服务器允许同一个存储过程既可以返回数据又可以执行动作.2.什么时候需要用存储过程 如果服务器定义了存储过程,应当根据需要决定是否要用存储过程.存储过程通常是一些经常要执行的任务,这些任务往往是针对大量的记录而进行的.在服务器上执行存储过程,可以改善应用程序的性能.这

用java调用oracle存储过程总结(转)

//1.call+包名+存储过程名(传入.传出值用?) String str="{call SMSBUSINESS.deleteZhZMember(?,?,?)}"; //2.建立连接 Connection conn=null; conn=DriverManager.getConnection(); //3.使用java.sql.*类 CallableStatement cs=conn.prepareCall(str); //4.传入in值 cs.setInt(1,id); cs.se

C#调用 Oracle 存储过程样例代码

-- 建表CREATE TABLE sale_report (     sale_date DATE NOT NULL ,     sale_item VARCHAR(2) NOT NULL ,      sale_money DECIMAL(10,2) NOT NULL,      PRIMARY KEY(sale_date, sale_item)); -- 測试数据DECLAREv_begin_day DATE;v_end_day DATE;BEGIN v_begin_day := TO_D

Oracle ——存储过程——分页

输入:表名.每页显示的记录数.当前页输出:总记录数.总页数.结果集--首先,创建一个包,定义游标类型CREATE OR REPLACE PACKAGE fenye_package ISTYPE fenye_cursor IS REF CURSOR;END fenye_package; --输入:表名.每页显示的记录数.当前页--输出:总记录数.总页数.结果集CREATE OR REPLACE PROCEDURE sp_fenye(tableName   IN VARCHAR2,--表名称 max

PLSQL中显示Cursor、隐示Cursor、动态Ref Cursor差别

一.显式cursor 显式是相对与隐式cursor而言的,就是有一个明白的声明的cursor.显式游标的声明类似例如以下(具体的语法參加plsql ref doc ): cursor cursor_name (parameter list) is select ... 游标从declare.open.fetch.close是一个完整的生命旅程. 当然了一个这种游标是能够被多次open进行使用的,显式cursor是静态cursor,她的作用域是全局的,但也必须明确,静态cursor也仅仅有pl/s

C#中使用Oracle存储过程返回结果集

问题: 在MSSQLServer中定义的存储过程可以直接返回一个数据集,如: create procedure sp_getAllEmployees as SELECT * FROM [NORTHWND].[dbo].[Employees] 在Oracle数据库中这样定义是错误的,怎么解决? 办法: Oracle中可以使用游标(Cursor)对数据集进行操作,但在存储过程输出参数中直接使用Cursor错误,此时的Cursor应该是一个定义游标的关键字并非类型,所以先要定义一个包,在包中声明全局的