热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle之存储过程

PLSQL块:PLSQL块都用于解决特定问题,PLSQL块可以有参数,也可以相互调用。PLSQL块可以作为模式对象在Oracle数据库中保存,根据用途可以

PL/SQL块:

     PL/SQL块都用于解决特定问题,PL/SQL块可以有参数,也可以相互调用

     PL/SQL块可以作为模式对象在Oracle数据库中保存,根据用途可以分为两类:

         1、存储过程:用于特定目的,执行一系列操作的PL/SQL块

         2、自定义函数:通过计算返回调用者一个值的PL/SQL块


存储过程:


    存储过程是由流控制和SQL语句组成的,经编译和优化后存储在数据库服务器中,使用时只需调用即可。

    

    存储过程类似于高级程序设计语言中模块的概念,它将一些内部联系的命令组成一个个存储过程,通过参数在存储过程之间传递数据是模块化设计思想的主要内容。


    SQL语句执行的时候要先编译,然后执行。存储过程就是编译好了的一些SQL语句。可以直接执行,所以执行效率较高。


存储过程的优点: 

     1、存储过程大大增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

     2、可保证数据的安全性和完整性:

                  a:通过存储过程可以使没有使用权限的用户间接地存取数据,从而保证数据的完全。

                   b : 通过存储过程可以使相关的动作在一起发生,从而维护数据库的完整性。

     3、在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案,这种已经编译好的存储过程极大地改善SQL语句的性能。

     4、使用存储过程可以降低网络的通信量。

     5、使体现应用需要的运算程序放入数据库服务器中,以便集中控制。


存储过程定义:

 存储过程的创建:

    1、创建存储过程的语法结构,完整的存储过程结构如下:

            create [or replace]  procedure  存储过程名称

             as             声明语句     

             begin       执行语句段;

                            exception

                            异常处理语句段

             end;

    2、存储过程示例:

        create  or  replace  procedure  scott.tempprocedure   as

            tempdate  scott.emp.hiredate%type;

        begin   select  hiredate  into tempdate

                       from  scott.emp

                       where   scott.emp.SAL =  1500;

                       dbms_output.put_line('存储过程生成的变量值:'||tempdate);

        end;

 

存储过程的修改:

     存储过程的修改有两个方法:

        方法一:如果以前已经写了存储过程的全部或部分,现在需要修改或者继续完成,可以用SLQPlus  Worksheet打开以前保存的文件,方法是在SLQPlus  Worksheet的菜单栏选择“文件”-->“ 打开”命令,将创建存储过程的SQL文件调出进行修改,修改完毕后保存并重新执行创建存储过程即可。

         方法二:1、在企业管理器里选中要修改的存储过程,用鼠标右键点击,在出现的快捷菜单里选择“查看/编辑详细资料”菜单项;2、在弹出“编辑过程”窗口中的文本域中修改存储过程之后点击窗口中的“应用”按钮即可完成对存储过程的修改。


存储过程的执行:

    创建存储过程的最终目的是为了执行,所以创建存储过程后,需要调用它,才会让它执行。要执行创建的存储过程,必须通过主程序来调用存储过程,如果我们要调用前面写好的存储过程,可以在SQLPlus Worksheet中执行下列PL/SQL程序:

    


带参数的存储过程:

    创建带参数的存储过程的语法如下:

        create  [or replace]  procedure   过程名

            参数1  [in|out|in out]  数据类型

             [,参数2  [in|out|in out]  数据类型] ...

               {is|as}  pl/sql  语句

    1、参数类型

          在PL/SQL存储过程中,可以有3种类型的参数,其功能简要概述如下:

            in参数:读入参数,主程序向存储过程传递参数。

            out参数:读出参数,存储过程向主程序传递参数值。    

            in  out参数:双向参数,存储过程与主程序双向交流数据。

        定义带参数的存储过程:

                create  or  replace  procedure  scott.tempprocedure1(

                            tempdeptno   in   scott.dept.deptno%type,

                            tempdname    out   scott.dept.dname%type,

                            temploc           in out   scott.dept.loc%type)

                as        loc1  scott.dept.loc%type;

                            dname1  scott.dept.dname%type;

                begin   select  loc  into loc1 

                             from  scott.dept

                             where deptno=tempdeptno;

                            select dname into  dname1

                             from  scott.dept

                             where   deptno = tempdeptno;

                             temploc:='地址:'||loc1;

                             tempdname:='姓名'||dname1;

                   end;

该存储过程的功能是:从数据表scott.dept中寻找deptno字段等于一个变量(即调用参数,这里我们命名为tempdeptno的dname和loc字段,并将这两个字段的值赋给新的变量


带参数的存储过程的调用:

       在主程序中的实际参数和过程中的形式参数的传递有很多中方法,这里推荐采取——对应的办法,按对应的位置传递参数。要求实际参数和形式参数在数据类型和位置排列上做到完全一致。

         set  serveroutput  on

         declare  myno  scott.dept.deptno%type;

                       mydname  scott.dept.dname%type;

                       myloc   scott.dept.loc%type;

           begin   myno:=10;

                       mydname:='';

                       myloc:='';

                       scott.tempprocedure1(myno,myname,myloc);

                         dbms_output.put_line(myno);

                         dbms_output.put_line(myname);

                         dbms_output.put_line(myloc);

        end;



自定义函数:

         创建自定义函数语法如下:

             create  or  replace  function  函数名(参数名    参数类型,......)

                  return  返回值类型

              is

                  begin

                    ......

                  end   函数名;

例:

         create  or replace  function 

                get_sal(empname  in  varchar2)  return

                number  is

                    Result   number;

                    begin

                    select sal  into  Result  from  emp where

                  ename  = empname;

                    return(Result);

                   end  get_sal;

        执行:SQL>var sal  number

                  SQL>exec:sal:=get_sal('scott');


使用包:

        包可以看做是过程和函数的集合,对过程和函数进行更好的封装。

       包的作用:包可以将任何出现在块声明的语句(过程,函数,游标,类型,变量)放于包中,相当于一个容器。将声明语句放入包中的好处是:用户可以从其他PL/SQL块中对其进行引用,因此包为PL/SQL提供了全程变量。

        包的包括包头和包体两部分,需要分别定义。

    定义包头:

        create  or  replace  package   包名

                    is      

                        过程名/函数名;        --申明了该包中的过程及函数

        end  包名;

    定义包体:

          create  or  replace  package  body  包名

                        is

                            过程/函数定义实现;

                end   包名;

    例:

            创建包头:

                create  or  replace package  fitpackage

                        is

                            procedure  myproc1(num in number);

                            procedure  myproc2;

                            function  myfunc(stuno  varchar2)  return  number;

                      end     fitpackage;

            创建包体:包名以及包内的函数,过程名以及参数列表都要和包头定义中的内容一致

                create  or   replace  package  body   fitpackage

                    is

                        procedure  myproc1(num in number)

                            as 

                            ......

                            end    myproc1;

                        procedure  myproc2

                            as

                            ......

                            end  myproc2;

                        function  myfunc(stuno  varchar2)

                            return   number

                            as

                             ......

                            end   myfunc;

                        end fitpackage;


JAVA程序调用存储过程:

    JDBC通过CallableStatement接口提供对此类功能的支持。可以通过Connection对象的prepareCall()方法来,该方法的参数是一个String,是一种SQL转义语法:

    例如:

    

过程的参数:

    in参数的占位符为?,使用CallableStatement接口的setXXX()方法来为参数设置值。

   out参数的占位符为?,使用的时候必须先使用CallableStatement接口的registerOutParameter()方法注册此参数,最后通过getXXX()方法来取值。

    对于存储过程的返回值,除索引号为1外,其他与out参数用法一样。

    

带有输出参数:

    创建存储过程:

    create or replace procedure P_myPro_ConnOracle(empId in int,empName out String)

      as 

        begin

            select e.ename

            into empName

            from emp  e

            where  e.empno = empId;

            dbms_output.put_line('empId='||empId);

            dbms_output.put_line('empName='||empName);

        end;

    JDBC操作:

        //获得CallableStatement对象

            CallableStatement ctmt = conn.prepareCall("{call proc_forvalue(?,?)}");

       //设置输入参数

        ctmt.setString(1,type);

       //注册输出参数及数据类型

        ctmt.registerOutParameter(2,java.sql.Types.INTEGER);

       //调用存储过程,并查询输出参数的值

        ctmt.execute();

        result = ctmt.getInt(2);


使用游标返回结果集:

    创建存储过程:

        create or replace  package my_package

        as

        type my_cursor is ref cursor;

        end my_package;


        create or replace procedure my_test(test_result

                out  my_pakcage.my_cursor)

        as

        begin

        open  test_result  for

        select * from  dept;

        end;


使用游标返回结果集:

    JDBC操作:

           //获得CallableStatement对象

            CallableStatement proc= conn.prepareCall("{call my_test(?)}");

       //设置输入参数

        proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);

       //调用存储过程,并获得第一个产生的结果集

        proc.execute();

        rs = (ResultSet)proc.getObject(1);//1指的是参数1

                while(rs.next()){

                System.out.println(rs.getString(1)+","+rs.getString(2));

        }



推荐阅读
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • 本文详细介绍了Oracle 11g中的创建表空间的方法,以及如何设置客户端和服务端的基本配置,包括用户管理、环境变量配置等。 ... [详细]
  • Docker安全策略与管理
    本文探讨了Docker的安全挑战、核心安全特性及其管理策略,旨在帮助读者深入理解Docker安全机制,并提供实用的安全管理建议。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 本文作为《WM平台上使用Sybase Anywhere 11》系列的第二篇,将继续探讨在Windows Mobile (WM) 系统中如何高效地操作Sybase Anywhere 11数据库。继上一篇关于安装与基本测试的文章之后,本篇将深入讲解数据库的具体操作方法。 ... [详细]
  • 从CodeIgniter中提取图像处理组件
    本指南旨在帮助开发者在未使用CodeIgniter框架的情况下,如何独立使用其强大的图像处理功能,包括图像尺寸调整、创建缩略图、裁剪、旋转及添加水印等。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 调试利器SSH隧道
    在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问。但我们一般都会在本地开发,因为这能快速的看到 ... [详细]
  • 解决PHP项目在服务器无法抓取远程网页内容的问题
    本文探讨了在使用PHP进行后端开发时,遇到的一个常见问题:即在本地环境中能够正常通过CURL获取远程网页内容,但在服务器上却无法实现。我们将分析可能的原因并提供解决方案。 ... [详细]
  • 如何从BAM文件绘制ATAC-seq插入片段长度分布图?
    在ATAC-seq数据处理中,插入片段长度的分布图是一个重要的质量控制指标,它能反映出核小体的周期性排列。本文将详细介绍如何从BAM文件中提取并绘制这些数据。 ... [详细]
  • 本文将从基础概念入手,详细探讨SpringMVC框架中DispatcherServlet如何通过HandlerMapping进行请求分发,以及其背后的源码实现细节。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
author-avatar
mobiledu2502909493
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有