Вам нужно увеличить размер массива, создавая пустой элемент, который вы затем можете заполнять, каждый раз, когда хотите добавить элемент:
...
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
к запросу, чтобы убедиться, что он не пытаетсяполучить больше строк, которые может обработать массив, но для этого может быть более подходящим, если это произойдет, если это когда-либо произойдет.)