Извлечение данных таблицы с помощью курсора в Varray в базе данных Oracle - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть таблица с именем PhoneBook с такими атрибутами: ID, FirstName, LastName.и у него есть 5 записей. Я хочу создать VARRAY и извлечь все firstNames из таблицы телефонной книги в 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 - «Нижний индекс вне предела» * Причина: нижний индекс был больше, чем предел для varray или не был положительным для varray или вложенной таблицы.* Действие: Проверьте логику программы и, если необходимо, увеличьте предел варриа.

Пожалуйста, помогите мне решить эту проблему.спасибо

1 Ответ

0 голосов
/ 04 декабря 2018

Вам нужно увеличить размер массива, создавая пустой элемент, который вы затем можете заполнять, каждый раз, когда хотите добавить элемент:

...
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до назначения, так как массив индексируется с 1, а не с 0. Я также переместил EXIT сразу после FETCH, поэтому вы не пытаетесь обработать последнюю строку из курсора дважды.

Вам на самом деле не нужно 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;
/

Я предполагаю, что этоэто упражнение;в противном случае вы можете использовать массовый сбор в коллекции, и вам не нужен явный курсор:

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

(Вы можете добавить проверку rownum к запросу, чтобы убедиться, что он не пытаетсяполучить больше строк, которые может обработать массив, но для этого может быть более подходящим, если это произойдет, если это когда-либо произойдет.)

...