0

我有一个名为 PhoneBook 的表,它具有以下属性:ID、FirstName、LastName。它有 5 条记录我想创建一个 VARRAY 并使用光标将电话簿表中的所有名字提取到 VARRAY 中。这是我的代码:

DECLARE
    v_FirstName PHONEBOOK.FIRSTNAME%TYPE;
    TYPE arrayNames IS VARRAY(10) OF VARCHAR2(20);
    v1 arrayNames;
    i INT := 0;
    CURSOR c_phonebook IS SELECT FIRSTNAME FROM PHONEBOOK;
       BEGIN
           v1 := arrayNames(); 
           OPEN c_phonebook;
           LOOP
                FETCH c_phonebook INTO v_firstname;
                v1(i) := v_firstname;
                i := i+1;
                EXIT WHEN c_phonebook%NOTFOUND;
           END LOOP;

          CLOSE c_phonebook;

       END;/

当我编译这段代码时,它给了我一个错误:

ORA-06532:下标超出限制 ORA-06512:在第 14 行 06532。00000 -“下标超出限制” *原因:下标大于可变数组的限制或可变数组或嵌套表的非正数。*操作:检查程序逻辑并在必要时增加可变数组限制。

请帮我解决这个问题。谢谢你

4

1 回答 1

1

您需要增加数组的大小,创建一个空元素,然后可以填充,每次要添加成员时:

...
BEGIN
    v1 := arrayNames();
    OPEN c_phonebook;
    LOOP
        FETCH c_phonebook INTO v_firstname;
        EXIT WHEN c_phonebook%NOTFOUND;
        i := i+1;
        v1.EXTEND();
        v1(i) := v_firstname;
    END LOOP;
    CLOSE c_phonebook;
END;

请注意,我已经i := i+1在赋值之前移动了 to,因为数组是从 1 而不是 0 索引的。我还在EXIT之后立即移动了 to FETCH,因此您不要尝试两次处理游标的最后一行。

i在这个例子中你实际上不需要,你可以使用数组的 currentCOUNT来识别新添加的条目:

DECLARE
    v_FirstName PHONEBOOK.FIRSTNAME%TYPE;
    TYPE arrayNames IS VARRAY(10) OF VARCHAR2(20);
    v1 arrayNames;
    CURSOR c_phonebook IS SELECT FIRSTNAME FROM PHONEBOOK;
BEGIN
    v1 := arrayNames(); 
    OPEN c_phonebook;
    LOOP
        FETCH c_phonebook INTO v_firstname;
        EXIT WHEN c_phonebook%NOTFOUND;
        v1.EXTEND();
        v1(v1.COUNT) := v_firstname;
    END LOOP;
    CLOSE c_phonebook;
END;
/

我认为这是一个练习;否则您可以在集合中使用批量收集,并且不需要显式游标:

DECLARE
    TYPE arrayNames IS VARRAY(10) OF VARCHAR2(20);
    v1 arrayNames;
BEGIN
    SELECT FIRSTNAME
    BULK COLLECT INTO v1
    FROM PHONEBOOK;
END;
/

(您可以在查询中添加一个rownum检查,以确保它不会尝试获取数组可以处理的更多行,但如果发生错误,它可能更适合出错。)

于 2018-12-04T17:25:17.057 回答