Skip to content
Advertisement

Error while writing to array plsql how to fix? Extend doesn’t work also

so I am trying to write to an array in PL/SQL, and I always get the subscript outside of limit error. I’ve seen similar posts and implemented everything based on those answers, I can’t seem to find what I’m doing wrong. The line giving the error is “arr_quartosLivres(counter) := q.id;” I’ve tried to extend the array and it still doesn’t work, however, either way, the look only runs 21 times (because there are only 21 values in the table quarto) so it shouldn’t even need to be extended. Any help would be highly appreciated! Thank you

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;

Advertisement

Answer

The index values for varray begin with 1. Your logic is trying to use index value 0. Thus index out of range. BTW extend does not apply to varray, when declared a varray has a fixed size. You have 3 solutions: initialize counter to 1 instead of 0, or move incrementing it prior to its use as an index. Since as it stands you increment every time through the loop, even when the IF condition returns false and you do not use the counter as an index, leaving a NULL value in the array.But you use counter for 2 different purposes: Counting rows processed and index into the array. Since the row value may not be put into the array then your 3rd option is to introduce another variable for the index. Further there is no need for the BEGIN … End block in the loop.

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; 

 
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement