Ошибка при записи в массив plsql, как исправить? Расширение также не работает

#sql #plsql

#sql #plsql

Вопрос:

итак, я пытаюсь записать в массив в PL / SQL, и я всегда получаю ошибку нижнего индекса за пределами предела. Я видел похожие сообщения и реализовал все на основе этих ответов, кажется, я не могу найти, что я делаю неправильно. Строка, выдающая ошибку, — «arr_quartosLivres (счетчик) : = q.id ;» Я пытался расширить массив, но он по-прежнему не работает, однако, в любом случае, просмотр выполняется только 21 раз (потому что в таблице quarto всего 21 значение), поэтому его даже не нужно расширять. Любая помощь будет высоко оценена! Спасибо

 SET SERVEROUTPUT ON;

DECLARE
    p_idReserva reserva.id%type := 408;
    v_dataEntradaReserva reserva.data_entrada%type;
    counter integer := 0;

    type arr_aux IS varray(21) of quarto.id%type;
    arr_quartosLivres arr_aux := arr_aux(); 

BEGIN
    SELECT data_entrada INTO v_dataEntradaReserva FROM reserva WHERE id = p_idreserva;

    FOR q IN (SELECT * FROM quarto)
    LOOP
        BEGIN
            IF isQuartoIndisponivel(q.id, v_dataEntradaReserva) 
            THEN    DBMS_OUTPUT.PUT_LINE('nao disponivel' || counter);
                arr_quartosLivres(counter) := q.id;
            ELSE DBMS_OUTPUT.PUT_LINE('disponivel' || counter);
            END IF;
            counter := counter   1;
        END;
    END LOOP;
END;
 

Ответ №1:

Значения индекса для varray начинаются с 1. Ваша логика пытается использовать значение индекса 0. Таким образом, индекс выходит за пределы диапазона. Кстати, расширение не применяется к varray, когда объявленный varray имеет фиксированный размер. У вас есть 3 решения: инициализировать счетчик на 1 вместо 0 или переместить его, увеличив его до его использования в качестве индекса. Поскольку в нынешнем виде вы увеличиваете каждый раз в цикле, даже когда условие IF возвращает false и вы не используете счетчик в качестве индекса, оставляя нулевое значение в массиве.Но вы используете счетчик для 2 разных целей: подсчета обработанных строк и индексирования в массив. Поскольку значение строки может не помещаться в массив, ваш третий вариант — ввести другую переменную для индекса. Далее нет необходимости в BEGIN … Завершающий блок в цикле.

 declare
    p_idreserva reserva.id%type := 408;
    v_dataentradareserva reserva.data_entrada%type;
    counter integer := 0;

    type arr_aux is varray(21) of quarto.id%type;
    arr_quartoslivres arr_aux := arr_aux(); 
    varray_index integer := 1 ; -- index varaibal for varray.
begin
    select data_entrada into v_dataentradareserva from reserva where id = p_idreserva;

    for q in (select * from quarto)
    loop
         if isquartoindisponivel(q.id, v_dataentradareserva) 
         then
             dbms_output.put_line('nao disponivel' || counter || ' at index ' || varray_index); 
             arr_quartoslivres(varray_index) := q.id;
             varray_index :=  varray_index   1;
         else 
            dbms_output.put_line('disponivel' || counter);
         end if;
         counter := counter   1;
    end loop;
end;