Oracle 11g:当将新类型声明为表时,我必须添加"INDEX BY PLS_INTEGER"吗?



添加INDEX BY PLS_INTEGER和不在新表类型声明的末尾有什么区别?看这个例子:

DECLARE
    GC_BULK_LIMIT CONSTANT INTEGER := 500;
    CURSOR CUR_CLIENTS IS SELECT C.ID, C.NAME FROM CLIENTS C;
    TYPE RT_CLIENTS IS TABLE OF CUR_CLIENTS%ROWTYPE;
    -- TYPE RT_CLIENTS IS TABLE OF CUR_CLIENTS%ROWTYPE INDEX BY PLS_INTEGER;
    LT_CLIENTS RT_CLIENTS;
BEGIN
    OPEN CUR_CLIENTS;
    LOOP
        FETCH CUR_CLIENTS BULK COLLECT INTO LT_CLIENTS LIMIT GC_BULK_LIMIT;
        EXIT WHEN LT_CLIENTS.COUNT = 0;
        FOR I IN 1..LT_CLIENTS.COUNT LOOP
            -- ... SOME LOGIC
        END LOOP;
    END LOOP;
    CLOSE CUR_CLIENTS;
END;

回应"必须添加"。简短的回答是否定的。

的区别在于

TYPE RT_CLIENTS IS TABLE OF CUR_CLIENTS%ROWTYPE;

是一个嵌套表。这意味着对于这种类型的给定变量,我们知道下标是顺序的。即下标从1开始,一直到数组长度。

因此,下面的循环是访问嵌套表数组的正确方法:
FOR I IN 1..LT_CLIENTS.COUNT LOOP

然而,这被称为关联数组:

TYPE RT_CLIENTS IS TABLE OF CUR_CLIENTS%ROWTYPE INDEX BY PLS_INTEGER;

(如果需要,也可以通过varchar2进行索引)。不同之处在于,在这种情况下,下标不必是顺序的,这取决于如何填充数组。在您的代码中,它们可能是这样的(因为批量收集会这样做),但情况并非总是如此。

访问和循环通过index by数组的安全方法是:

  v_subscript := t_arr.first;
  while v_subscript is not null loop
    dbms_output.put_line(v_subscript || ': ' || t_arr(v_subscript));
    v_subscript := t_arr.next(v_subscript); 
  end loop;

,其中v_subscript是与index by部分相同数据类型的变量。

也可以使用嵌套表,您可以使用:

快速填充数组:
declare
  type myarr is table of number;
  t_arr         myarr;
    v_subscript   number;
begin
  t_arr := myarr(1, 12, 44);

而index by array则需要三行来填充

  t_arr(1):= 1;
  t_arr(2):= 12;
  t_arr(3):= 44;

对于您的特殊情况,没有index by是完全可以的。

进一步阅读:http://docs.oracle.com/cd/E18283_01/appdev.112/e17126/composites.htm

最新更新