zoukankan      html  css  js  c++  java
  • ORACLE HANDBOOK系列之五:PL/SQL中的集合类型(Collections in PL/SQL)

    1)集合的分类

     

    Oracle支持3种类型的集合

    关联数组Associative array,即Index-by table

    嵌套表Nested table

    变长数组VARRAY

    它们的区别之一是, Nested tableVARRY既可以被用于PL/SQL,也可以被直接用于数据库中,但是Associative array不行,也就是说,Associative array是不能通过CREATE TYPE语句进行单独创建,只能在PL/SQL(或Package中进行定义并使用(即适用范围PL/SQL Block级别),而Nested tableVARRAY则可以使用CREATE TYPE进行创建(即适用范围是Schema级别)它们还可以直接作为数据库表中列的类型

    BTW,为了避免误解,以下显式提到索引的地方,并非指的是数据库表的索引,而是特指访问集合元素时使用的下标,即Collection_Name(index)中的index

     

    2)集合类型的声明与初始化

    2.1)Associative array

    首先看一下Associative array的声明及初始化,示例中的第一部分显示,Associative array不能使用CREATE TYPE来创建。第二部分使用一个匿名PL/SQL块来演示Associative array使用,可以看到用法还是相对简单的。

    Associative array的索引可以是稀疏的(即可以不连续)。

    SQL> CREATE OR REPLACE TYPE ib_planguage IS TABLE OF VARCHAR2(10INDEX BY PLS_INTEGER;
     
    2 /
    Warning: Type created 
    with compilation errors.
    SQL
    > SHOW ERROR;
    Errors 
    for TYPE IB_PLANGUAGE:
    LINE
    /COL ERROR
    -------- -----------------------------------------------------------------
    0/0      PL/SQL: Compilation unit analysis terminated
    1/22     PLS-00355use of pl/sql table not allowed in this context
     
    DECLARE
     TYPE ib_planguage 
    IS TABLE OF VARCHAR2(10INDEX BY PLS_INTEGER;
     lang ib_planguage;
     idx PLS_INTEGER;
    BEGIN
     lang(
    1):='java';
     lang(
    9):='c#';
     lang(
    3):='c++';
     idx:
    =lang.FIRST;
     
    WHILE(idx IS NOT NULL) LOOP
        DBMS_OUTPUT.PUT_LINE(lang(idx));
        idx:
    =lang.NEXT(idx);
     
    END LOOP;
    END;
    SQL
    > /
    java
    c
    ++
    c#

     

    2.2)Nested table

    接着来看Nested table的声明及初始化,Nested table既可以通过CREATE TYPE声明成全局类型,也可以在PL/SQL块中声明块级别的类型。

    Associative array不同,Nested table变量需要显式初始化,其语法类似于C#,只是不用new关键字。额外地,Nested table初始化之后还需要调用EXTEND过程,扩展此集合的容量

    示例的第二部分提供了一种相对简单的初始化方法,即可以在构造器中直接传入集合成员。这种简便的初始化方法不适用于Associative array

    SQL> CREATE OR REPLACE TYPE nt_planguage IS TABLE OF VARCHAR2(10);
     
    2 /
    Type created.
     
    DECLARE
     lang nt_planguage;
    BEGIN
     lang:
    =nt_planguage();
     lang.EXTEND(
    3);
     lang(
    1):='java';
     lang(
    2):='c#';
     lang(
    3):='c++';
     
    FOR i IN 1..lang.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE(lang(i));
     
    END LOOP;
    END;
    SQL
    > /
    java
    c#
    c
    ++

    或者可以简单地写成:

    DECLARE
     lang nt_planguage;
    BEGIN
     lang:
    =nt_planguage('java','c#','c++');
     
    FOR i IN 1..lang.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE(lang(i));
     
    END LOOP;
    END;

     

    2.3)VARRAY

    最后我们来看VARRAY的声明及初始化,它与Nested table比较类似,但仍然存在一些区别,包括(1)VARRAY可以在声明时限制集合的长度,EXTEND的长度不能大于集合声明时的长度(下例中长度是8),但是在给集合成员赋值时,以EXTEND为准,例如下例中可以使用的只有3个集合成员。;(2)其索引总是连续的,而Nested table的索引在初始化赋值时是连续的,不过随着集合元素被删除,可能变得不连续。

    SQL> CREATE OR REPLACE TYPE va_planguage IS VARRAY(8OF VARCHAR2(10);
     
    2 /
    Type created.
     
    DECLARE
     lang va_planguage;
    BEGIN
     lang:
    =va_planguage();
     lang.EXTEND(
    3);
     lang(
    1):='java';
     lang(
    2):='c#';
     lang(
    3):='c++';
     
    FOR i IN 1..lang.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE(lang(i));
     
    END LOOP;

    END; 

    同样,也可以简单地写成:

    DECLARE
     lang va_planguage;
    BEGIN
     lang:
    =va_planguage('java','c#','c++');
     
    FOR i IN 1..lang.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE(lang(i));
     
    END LOOP;
    END;

     

    3)如何选择适用的集合类型

    通常来说对集合类型的第一选择应该是Associative array,因为它不需要初始化或者EXTEND操作,并且是迄今为止最高效的集合类型。唯一不足的一点是它只能用于PL/SQL而不能直接用于数据库。

    如果你需要允许使用负数索引,应该选择Associative array

    如果你需要使用10g11g中的那些集合操作,应该选择Nested table

    如果你需要限制集合元素的个数,应该选择VARRAY

     

    4)其它

    一个非常令人费解的地方是,位于PL/SQL语句块中的TYPE声明,必须使用关键字IS,而不能使用AS,但是在使用CREATE TYPE声明全局类型时,这两个是通用的。

    本来,说到这里就应该介绍完了,但是,Oracle引入了OO,导致我还要稍微说一下Object的声明及初始化,因为在某些情况下,你还会遇到集合成员是对象类型的情况。

    SQL> CREATE OR REPLACE TYPE o_planguage IS OBJECT(lang VARCHAR2(10),lang_desc VARCHAR2(100));
     
    2 /
    Type created.
     
    DECLARE
     lang o_planguage;
    BEGIN
     lang:
    =o_planguage('java','java is an OO programming language...');
     DBMS_OUTPUT.PUT_LINE(lang.lang_desc);

    END; 

    注意,Object不能在PL/SQL语句块中声明。

    注意2,我们不能使用如下代码进行初始化:

    lang:=o_planguage();

    lang.lang:=’java’;

    lang.lang_desc:=’java is an OO programming language…’

    这样的语法会导致出现{PLS-00306: 调用 'lang' 时参数个数或类型错误},即Object类型没有默认的无参构造器。介绍完这个,那么即使集合的成员是Object时,也可以如法炮制去声明、初始化了。

     

  • 相关阅读:
    Eclipse的Debug教程
    Java面向对象--关键字(package、import、this)
    Java面向对象--JavaBean类&UML类图
    Java面向对象--构造器(构造方法)
    Java面向对象--属性和方法
    python | 基础知识与基本概念
    post登录 jsessionid 以及cookie 传递
    JMeter学习-017-java.net.SocketException: Permission denied: connect 解决方案
    python自建模块显示说明与详情
    在linux下pycharm无法输入中文
  • 原文地址:https://www.cnblogs.com/morvenhuang/p/2008158.html
Copyright © 2011-2022 走看看