热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

oracle存储过程及REFCURSOR的使用

oracle存储过程及REFCURSOR的使用摘要:主要记录了oracle的storedprocedure相关知识、从定义到使用。从最简单的例子入手、逐渐深入。同时后面结合了refcursor的使用。顺便补充了在ja
oracle 存储过程及REF CURSOR的使用 摘要:主要记录了oracle的stored procedure相关知识、从定义到使用。从最简单的例子入手、逐渐深入。同时后面结合了ref cursor的使用。顺便补充了在java中如何使用。

一:简介

1、存储过程定义:

存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。

存储过程是由流控制的和SQL 语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在ORACLE 中,若干个有联系的过程可以组合在一起构成程序包。

2、优点:

a) 存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。

b) 当对数据库进行复杂操作时(如对多个表进行Update、Insert、Query、Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务管理结合一起使用。

c)存储过程可以重复使用,可减少数据库开发人员的工作量。

d)安全性高,可设定只有某用户才具有对指定存储过程的使用权。

简单说,你在你的机器上写了个存储过程,这个存储过程像那些表里的数据一样被放在遥远的数据库服务器当中,但是它又是可执行的代码,其他能连到数据库服务器的用户,可以调用你写的存储过程
它的作用是隐藏细节,就是说,你写的存储过程代码可能很复杂,但是其他人调用它却很简单,不用具体知道它是如何做的,且一次能完成多个指令

3、分类:

oracle有系统存储过程自定义存储过程2种存储过程。

系统存储过程就是由oracle预先提供的一组完成特定功能的存储过程,安装完oracle就有了。

自定义存储过程就是存在oracle数据库里由一组plsql语句组成的自定义过程(procedure)。它可以供其它oracle自定义存储过程、自定义函数和job调用或者由客户端程序调用。

二:基本使用方法及示例

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
						        
推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 本文介绍了新款奇骏的两个让人上瘾的功能,分别是智能互联系统和BOSE音响。通过对新款奇骏的配置和功能进行评测,探讨了这两个新增功能的使用体验和优势。此外,还介绍了新款奇骏的其他配置和改进,如增加的座椅和驾驶辅助系统,以及内饰的舒适性提升。对于喜欢音响的消费者来说,BOSE音响的升级也是一个亮点。最后,文章提到了BOSE音响的数字还原能力,以及7座版无法配备BOSE音响的原因。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 如何基于ggplot2构建相关系数矩阵热图以及一个友情故事
    本文介绍了如何在rstudio中安装ggplot2,并使用ggplot2构建相关系数矩阵热图。同时,通过一个友情故事,讲述了真爱难觅的故事背后的数据量化和皮尔逊相关系数的概念。故事中的小伙伴们在本科时参加各种考试,其中有些沉迷网络游戏,有些热爱体育,通过他们的故事,展示了不同兴趣和特长对学习和成绩的影响。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
雅婷婉君323
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有