zoukankan      html  css  js  c++  java
  • 集合

    集合是相同数据类型元素的组合,类似于编程语言中的数组。它包含如下三种类型:关联数组Associative array(索引表 pl/sql table)、嵌套表(Nested Table)、变长数组(VARRAY)

    下面我们来看看官方对于三者的比较

    一、 集合方法

    exists(index) 索引处的元素是否存在
    count 当前集合中的元素总个数
    limit 集合元素索引的最大值,索引表和嵌套表是不限个数的,所以返回null,变长数组返回定义时的最大索引
    first 返回集合第一个元素索引
    last 返回集合最后一个元素索引
    prior 当前元素的前一个元素的索引
    next 当前元素的后一个元素的索引
    extend 扩展集合的容量,增加元素 只是用于嵌套表和varry类型
         x.extend 增加一个null元素
         x.extend(n) 增加n个null元素
         x.extend(n,i) 增加n个元素,元素值与第i个元素相同
    trim 从集合的尾部删除元素 只用于NEST TABLE和VARRY类型
         trim 从集合尾部删除一个元素
         trim(n) 从集合尾部删除n个元素
    delete 按索引删除集合元素
          delete 删除所有
          delete(index) 删除第index个
          delete(a,b) 删除a--b之间的所有元素

    注意:用DELETE删除元素时,PL/SQL会保存所删除元素的占位符。而用TRIM删除时,却不会保存所删除元素的占位符。

    二、关联数组Associative array

    关联数组具有以下特征:

    1> 下标无限制,可以为负数。

    2> 元素个数无限制。

    创建关联数组的语法如下所示:

    TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY index_type;
    table_name TYPE_NAME;

    其中,type_name是用户自定义数据类型的名字,element_type是关联数组中元素类型,index_type是元素下标的数据类型(BINARY_INTEGER,PLS_INTEGER,VARCHAR2);

    例一:

    DECLARE
      CURSOR c_ename IS SELECT * FROM EMP;
    
      TYPE t_ename IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
      ename_tab t_ename; 
    
      v_counter INTEGER :=0;
    BEGIN
      FOR i IN c_ename LOOP
         v_counter := v_counter+1;
         ename_tab(v_counter) := i.ename;
         DBMS_OUTPUT.PUT_LINE(v_counter||': '||ename_tab(v_counter));
      END LOOP;
    END;
    /

    结果输出为:

    1: SMITH
    2: ALLEN
    3: WARD
    4: JONES
    5: MARTIN
    6: BLAKE
    7: CLARK
    8: SCOTT
    9: KING
    10: TURNER
    11: ADAMS
    12: JAMES
    13: FORD
    14: MILLER

    上述范例元素下标的类型为BINARY_INTEGER。

    下面另举一例index_type为string的。

    例二:

    DECLARE
      TYPE t_dept IS TABLE OF NUMBER      -- Associative array type
        INDEX BY VARCHAR2(64);            --  indexed by string
      dept_no  t_dept;                    -- Associative array variable
      i  VARCHAR2(64);                    -- Scalar variable
    BEGIN
      -- Add elements (key-value pairs) to associative array:
      dept_no('Ca')  := 10;
      dept_no('Ba')  := 30;
      dept_no('Bb')  := 20;
    
      -- Print associative array:
      i := dept_no.FIRST;  -- Get first element of array
      WHILE i IS NOT NULL LOOP
        DBMS_Output.PUT_LINE
          ('Dept No. for ' || i || ' is ' || dept_no(i));
        i := dept_no.NEXT(i);  -- Get next element of array
      END LOOP;
    END;
    /

    输出结果为:

    Dept No. for Ba is 30
    Dept No. for Bb is 20
    Dept No. for Ca is 10

    由此可见,输出结果是经过排序的,该排序依据的是元素下标的sort order,而不是元素的creation order。

    三、 嵌套表Nested table

    嵌套表具有以下特征:

    1> 下标从1开始,元素个数没有限制

    2> 使用时必须先初始化,用extend属性可以扩展元素个数

    3> 可以作为表定义数据类型,但是前提是要先create创造嵌套表类型

    4> 和索引表的区别也就是看看有无index by语句,嵌套表的索引固定是int型的

    创建语法:

    TYPE type_name IS TABLE OF element_type;

    例一,修改上述索引表的例一

    DECLARE
      CURSOR c_ename IS SELECT * FROM EMP;
    
      TYPE t_ename IS TABLE OF emp.ename%TYPE;
      ename_tab t_ename := t_ename();     -- 初始化
    
      v_counter INTEGER :=0;
    BEGIN
      FOR i IN c_ename LOOP
         v_counter := v_counter+1;
         ename_tab.EXTEND;                -- 增加集合大小
         ename_tab(v_counter) := i.ename;
         DBMS_OUTPUT.PUT_LINE(v_counter||': '||ename_tab(v_counter));
      END LOOP;
    END;
    /

    如官方对于集合三种类型的比较,当声明索引表时,索引表被自动设置为空,而当声明嵌套表和变长数组时,它们被自动设置为NULL,所以必须对其进行初始化。

    该例中还包含一个集合方法:EXTEND,这个方法允许你增加集合的大小。注意,EXTEND不能和索引表一起使用。

    例二,在表列中使用嵌套表,嵌套表类型的列是单独一个表存储,先创建一个这样的类型才能使用。

    1> 创建嵌套表类型

    SQL> create type nest_tab_type is table of varchar2(30);

    2> 创建表

    SQL> create table test (
             id int,
             vals nest_tab_type  --嵌套表类型
             ) nested table vals store as nest_tab;   --vals字段用嵌套表存储,表名为nest_tab

    3> 插入数据

    SQL> insert into test values(1,nest_tab_type('one','two','three','four')); 

    4> 查询数据

    SQL> select * from test;

    ID VALS
    ---------- ------------------------------------------------------------
    1 NEST_TAB_TYPE('one', 'two', 'three', 'four')

    declare
       v_id int;
       v_tab nest_tab_type;
    begin
       select * into v_id,v_tab from test where id=1;
       dbms_output.put_line(v_id);
       for i in 1..v_tab.count loop
       dbms_output.put_line(v_tab(i));
       end loop;
    end;

    输出结果为:

    1
    one
    two
    three
    four

    PL/SQL procedure successfully completed.

    四、 可变数组Varray

    变长数组具有以下特征:

    1> 下标从1开始,元素个数有最大限制。

    2> 类似于嵌套表,当变长数组被声明时,自动设置为NULL。必须在引用某个元素之前,初始化

    3> 不能对变长数组使用DELETE方法来删除元素。

    4> 可以作为表列类型

    创建语法如下:

    TYPE type_name IS VARRAY(size_limit) OF element_type;

    例一,

    DECLARE
      TYPE varray_type IS VARRAY(10) OF NUMBER;
      varray varray_type := varray_type(10,20,30,40,50,60);
    BEGIN
      DBMS_OUTPUT.PUT_LINE('varray.COUNT = '||varray.COUNT);
      DBMS_OUTPUT.PUT_LINE('varray.LIMIT = '||varray.LIMIT);
    
      DBMS_OUTPUT.PUT_LINE('varray.FIRST = '||varray.FIRST);
      DBMS_OUTPUT.PUT_LINE('varray.LAST = '||varray.LAST);
    
      varray.EXTEND(2,4);
      DBMS_OUTPUT.PUT_LINE('varray.LAST = '||varray.LAST);
      DBMS_OUTPUT.PUT_LINE('varray('||varray.LAST||')='||varray(varray.LAST));
    
      --Tirm last two elements
      varray.TRIM(2);
      DBMS_OUTPUT.PUT_LINE('varray.LAST = '||varray.LAST);
    END;

    输出结果为:

    varray.COUNT = 6
    varray.LIMIT = 10
    varray.FIRST = 1
    varray.LAST = 6
    varray.LAST = 8
    varray(8)=40
    varray.LAST = 6

    PL/SQL procedure successfully completed.

    例二,可变数组作为表列类型

    可变数组是存储在表内部的,不同于嵌套表

    1> 创建可变数组类型

    SQL> create type varr_type is varray(10) of varchar2(30);

    2> 创建表

    create table test_varray(    
        id int,    
        varr varr_type  --varr使用可变数组类型    
        );  
     
    3> 插入数据
    SQL> insert into test_varray values(1,varr_type('a','b','c'));
     
    4> 查询数据
    declare
        v_varr varr_type;
    begin
        select varr into v_varr from test_varray where id=1;
        for i in 1..v_varr.count loop
        dbms_output.put_line(v_varr(i));
        end loop;
    end;

    五、多维集合(Multidimensional Collections)

    从Oracle 9i开始,PL/SQL允许创建元素类型为集合类型的集合,这种集合称为多维集合。

    试举一例:

    DECLARE
      TYPE varray_type1 IS VARRAY(4) OF INTEGER;
      TYPE varray_type2 IS VARRAy(3) OF varray_type1;
      varray1 varray_type1 := varray_type1(2,4,6,8);
      varray2 varray_type2 := varray_type2(varray1);
    BEGIN
      DBMS_OUTPUT.PUT_LINE('Varray of integers');
      FOR i IN 1..4 LOOP
         DBMS_OUTPUT.PUT_LINE('varray('||i||'): '||varray1(i));
      END LOOP;
      
      varray2.EXTEND;
      varray2(2) := varray_type1(1,3,5,7);
      
      DBMS_OUTPUT.PUT_LINE(chr(10)||'Varray of varrays of integers');
      FOR i IN 1..2 LOOP
         FOR j IN 1..4 LOOP
            DBMS_OUTPUT.PUT_LINE
              ('varray2('||i||')('||j||'): '||varray2(i)(j));
         END LOOP;
      END LOOP;
    END;

    输出结果为:

    SQL> /
    Varray of integers
    varray(1): 2
    varray(2): 4
    varray(3): 6
    varray(4): 8

    Varray of varrays of integers
    varray2(1)(1): 2
    varray2(1)(2): 4
    varray2(1)(3): 6
    varray2(1)(4): 8
    varray2(2)(1): 1
    varray2(2)(2): 3
    varray2(2)(3): 5
    varray2(2)(4): 7

    PL/SQL procedure successfully completed.

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

     
  • 相关阅读:
    python中的单向链表实现
    Django中的Form表单验证
    顺序表的原理与python中的list类型
    HttpServletRequest get
    maven压缩js css
    left join inner join 区别
    Spark运行模式:cluster与client
    java 变量 final 小结
    eclipse svn 删除不了项目,合并不了问题
    hadoop HDFS常用文件操作命令 (转)
  • 原文地址:https://www.cnblogs.com/ivictor/p/3926783.html
Copyright © 2011-2022 走看看