Oracle PL/SQL 嵌套表的使用

PL/SQL当中有一个常用的容器,nested Table,在项目开发中,需要借用容器来实现一些计算操作,PL/SQL并不想其他语言当中有一些数组等比较容易使用的容器,在此整理一下nested tables一些常用的操作。

一、简介

netsted tables 可以看成一个变长数组,可以存放任意数量的元素(只要内存足够大),通过下标来实现对元素的访问,nested tables 有点是可以在SQL中直接使用。

            

                                    nested table 内存存储模型

nested tables 为了提高删除元素的效率,元素删除后并不移动后续的元素,从图中可以看nested tables 的下标是从1开始的,这点跟其它语言的数组或者容器有些区别。

(1) 定义。

   TYPE  tb_table IS TABLE OF VARCHAR2(100) ;    --定义一个嵌套表格类型存储 字符型数据

    tb_instance  tb_table:=tb_table();                    -- 采用上面定义的类型顶一个一个对象。

 (2)添加元素

    tb_instance.extend(1);--在末尾扩充一个元素

    tb_instance(tb_instance.last):=i; --为末尾的元素赋值

 (3) 删除元素

  tb_instance.delete(index);  --删除元素

(4)迭代器

  由于nested tables 元素的删除仅仅是留下一个空槽,元素遍历时我们要跳过这些空槽,nested table有以下的属性来访问存在的元素

   Fist : 第一个存在的元素下标

   Last:  最后一个存在的元素下标   

   exists(index): 判断下标index的元素是否存在

  NEXT(index):  获取 index下标后存在元素的下标,如果index是最后一个元素,则返回NULL

  PRIOR(index):  获取 index下标前面存在元素的下标,如果index是第一个元素,则返回NULL

  以上操作属性方法的存在可以让我们实现对Nested tables 的遍历了

   示例代码如下:

DECLARE
  -- Local variables here
  i INTEGER;

  counter INTEGER;
  TYPE tb_table IS TABLE OF VARCHAR2(100);
  tb_instance tb_table := tb_table(); 
  PROCEDURE log(l VARCHAR2) IS
  BEGIN
    dbms_output.put_line(l);
  END;

  PROCEDURE remove_depulate(p_tb_instance IN OUT tb_table) IS
    i INTEGER;
    j INTEGER;
  BEGIN
    i := p_tb_instance.first;
    WHILE i IS NOT NULL LOOP
      j := p_tb_instance.next(i);
      WHILE j IS NOT NULL LOOP
        IF p_tb_instance(i) = p_tb_instance(j) THEN
          p_tb_instance.delete(i);
          EXIT;
        END IF;
      
        j := p_tb_instance.next(j);
      END LOOP;
    
      i := p_tb_instance.next(i);
    END LOOP;
  END;

BEGIN

  FOR i IN 1 .. 10 LOOP    --每个元素增加两次
    tb_instance.extend(1);
   tb_instance.extend(1); tb_instance(tb_instance.last) :
= i; log('last:' || tb_instance.last); tb_instance(tb_instance.last) := i; END LOOP; remove_depulate(tb_instance); --去掉容器中重复的元素 log('-------------------------------------------------------'); counter := tb_instance.first; --通过属性方法遍历容器当中的元素 WHILE counter IS NOT NULL LOOP dbms_output.put_line('Element #' || counter || ' = ' || tb_instance(counter)); counter := tb_instance.next(counter); END LOOP; END;

上面的代码使用到了容器的增加,删除,遍历操作,修改操作直接通过下标访问修改就OK了。

 

posted on 2015-08-12 13:34  dyc0113  阅读(2033)  评论(0编辑  收藏  举报

导航