zoukankan      html  css  js  c++  java
  • oracle 学习笔记(四)

      在oracle中有一个很重要的东东---包,package。(本文中的代码都是在SCOTT中emp表中实现的)

      引用他人的定义--包是一种数据库对象,将逻辑上相关的PL/SQL类型、对象和子程序组合成一个更大的单位。包有两个部分:包说明(specification)和包体(body)。说明部分是为应用程序的接口,它申明类型、常量、例外、游标和可用的子程序。体定义游标和子程序,实现说明。应用程序仅对包说明中的申明是可见的和可存取。如果ORACLE具有Procedure选件,包可以编译、存贮在ORACLE数据库中,其内容可为许多应用共享。当用户第一次调用一包装的子程序时,整个包装入到内存,所以在以后对包中子程序调用时,不再需要I/O操作,故包可提高效率和改进性能。

      我个人的理解是--我们可以在包中写存储过程、函数,这是我们最常用的。那么包中到底可以有什么东西了,如下图,这是在oracle数据库中截取的,应该更有说服力。     

                                         

    在oracle中有一个包 dbms_output,我们就可以调用在这个包中的函数 put_line。

    包分为包说明和包体,下面就分别创建一个包说明和包体,

    create or replace package sp_package is   --注意,这里包的名字是 sp_package,后面要用关键字 is
    procedure update_sal(name emp.ename%type,newsal emp.sal%type); --定义了一个存储过程
    function income(name emp.ename%type) return number; --定义了一个函数,返回值数据类型是整形的
    end;

    包体

    create or replace package body sp_package is


    procedure update_sal(name emp.ename%type,newsal emp.sal%type) is --具体实现包说明中的存储过程
    begin
    update emp set sal=newsal where ename=name;
    end;

    function income(name emp.ename%type) --具体说明包说明中的函数
    return number is salary number;
    begin
    select sal*12 into salary from emp where ename=name;
    return salary;
    end;


    end;
     call sp_package.update_sal('MILLER',1500); --调用这个包中的存储过程,当然如果要访问其他方案的包,还要在包的前面加上方案名。

      如果有异常,则自己处理吧。

     在以上的sql语句,我们返回的都是一个值,没有返回多个值,如果返回的是多个值呢,我们应该用什么容器去承载它,oracle有一个概念,叫做复合变量,用于存放多个值的变量,包括pl/sql 记录,pl/sql 表,嵌套表,varray;

      PL/SQL 记录:下面的sql语句就定义了一个record(记录) emp_record_type,他可以承载姓名,工资,工作类型,是一个记录喔!定义一个记录的格式是

    declare type 记录名 is record(...);这和C语言中的结构定义比较相像。

    declare
    type emp_record_type is record( --这里你需要注意书写的格式是什么
    name emp.ename%type,
    salary emp.sal%type,
    title emp.job%type);
    emp_record emp_record_type; --定义了一个emp_record_type类型的变量 emp_record
    begin
    select ename,sal,job into emp_record from emp where empno=7782;
    dbms_output.put_line(emp_record.name);
    end;

      PL/SQL记录表相当于数组,高级语言里的数组的下表不能为负数,但此时的数组的下标可以是负数,只是没有值罢了。定义记录表的格式是

    declare type 记录表名 is table of 承载内容 index by binary_integer;

    declare
    type sp_table_type is table of emp.ename%type index by binary_integer;
    sp_table sp_table_type;
    begin
    select ename into sp_table(0) from emp where empno=7788;
    dbms_output.put_line(sp_table(0));
    end;

    参照变量是指用于存放数值指针的变量,通过使用参照变量,可以使得应用程序共享相同对象,从而降低使用空间,在编写的时候,可以使用游标变量(ref  cursor)和对象类型变量(ref  obj_type) 两种参照变量类型。使用游标 当定义游标时不需要指定相应的select语句,但是当使用游标时需指定select语句,这样就和select语句结合了。

    declare
    2 --定义游标类型
    3 type sp_emp_cursor is ref cursor;

    4 --定义游标变量
    5 test_cursor sp_emp_cursor;

    6 --定义变量
    7 v_ename emp.ename%type;

    8 v_sal emp.sal%type;
    9 begin
    10 --执行
    11 open test_cursor for select ename,sal from emp where deptno=&no; ---格式 open 游标变量名 for sql语句

    12 loop ---循环读取游标中的值 注意loop的用法 loop....end loop。
    13 fetch test_cursor into v_ename,v_sal; --读取内容,放在变量里面,注意这里存放的顺序,v_ename to ename,v_sal to sal
    14 exit when test_cursor%notfound; --如果没有数据,退出循环
    15 dbms_output.put_line(v_ename||v_sal);
    16 end loop;
    17 --close test_cursor; --这里关闭游标和打开游标时不同的,在Java里面调用,我测试的是如果有这句,则不能读取数据,你可以试试
    18 end;

      

  • 相关阅读:
    MFC的序列化的一点研究.
    一次LoadRunner的CPC考试经历
    LAMP架构上(一)
    文件和目录管理
    如何在Linux上清理内存缓存、缓冲与交换空间
    Linux Shell基础(下)
    防火墙(上)
    LAMP架构(三)
    LNMP(二)
    LNMP(一)
  • 原文地址:https://www.cnblogs.com/xianrongbin/p/2376036.html
Copyright © 2011-2022 走看看