简体   繁体   English

在Oracle数据库中使用游标将表数据获取到Varray

[英]Fetching Table Data with Cursor to a Varray in oracle database

I have a table called PhoneBook with this attributes: ID, FirstName, LastName. 我有一个名为PhoneBook的表,该表具有以下属性:ID,FirstName,LastName。 and it has 5 records I Want to create an VARRAY and fetch all firstNames in the PhoneBook Table into the VARRAY using Cursor. 它有5条记录,我希望创建一个VARRAY并使用Cursor将PhoneBook表中的所有firstName提取到VARRAY中。 Here is my code: 这是我的代码:

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;/

When I Compile this code it gave me an error: 当我编译此代码时,它给了我一个错误:

ORA-06532: Subscript outside of limit ORA-06512: at line 14 06532. 00000 - "Subscript outside of limit" *Cause: A subscript was greater than the limit of a varray or non-positive for a varray or nested table. ORA-06532:下标超出限制ORA-06512:在第14 06532行。00000-“下标超出限制” *原因:下标大于varray的限制,或者对于varray或嵌套表为非正数。 *Action: Check the program logic and increase the varray limit if necessary. *措施:检查程序逻辑,并在必要时增加varray的限制。

Please help me to solve this problem. 请帮我解决这个问题。 thank you 谢谢

You need to increase the size of the array, creating an empty element you can then populate, each time you want to add a member: 您需要增加数组的大小,每次要添加成员时,创建一个可以填充的空元素:

...
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;

Notice that I've moved the i := i+1 to before the assignment, as the array is indexed from 1 rather than 0. I've also moved the EXIT to immediately after the FETCH , so you don't try to process the last row from the cursor twice. 请注意,由于数组是从1而不是0索引的,所以我已将i := i+1移到了赋值之前。我还将EXIT移到了FETCH ,所以您不要尝试处理光标的最后一行两次。

You don't actually need i in this example, you can use the array's current COUNT to identify the newly-added entry: 在此示例中,您实际上并不需要i ,可以使用数组的当前COUNT来标识新添加的条目:

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;
/

I assume this is an exercise; 我认为这是一种练习; otherwise you could use a bulk collect into the collection, and don't need an explicit cursor: 否则,您可以在集合中使用批量收集,并且不需要显式游标:

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

(You could add a rownum check to the query to make sure it doesn't try to get more rows that the array can handle, but it might be more appropriate for that to error if it ever happens.) (您可以在查询中添加一个rownum检查,以确保它不会尝试获取该数组可以处理的更多行,但是如果发生这种情况,则更适合于出错。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM