Итерация над столбцом в PL/SQL

У меня есть таблица Emp с EmpID, Empname, Salary, и я пытаюсь сделать расчет для каждого сотрудника. Но у меня возникают проблемы с попыткой выполнить итерацию по каждой emp для вычисления. Я не могу использовать явные курсоры.

Итак, сейчас я просто пытаюсь создать список empIDs:

Declare
    aRows Number;
    eid emp_ID%TYPE;
Begin
    Select Count(*)
    Into aRows 
    from emp;

    Select emp_ID
    Into eid 
    From emp;

    FOR days IN 1..Tot_Rows
    Loop
        Dbms_Output.Put_Line(eid);
        eid := eid + 1;
    End Loop;
END; 

Но я получаю ошибку: PLS-00320: объявление типа этого выражения является неполным или искаженным

Ответ 1

Самый простой способ перебора строк в таблице в PL/SQL - это сделать что-то вроде

BEGIN
  FOR employees IN (SELECT emp_id FROM emp)
  LOOP
    dbms_output.put_line( employees.emp_id );
  END LOOP;
END;

В качестве альтернативы вы можете получить все значения EID в коллекции PL/SQL и выполнить итерацию по коллекции, как в этом примере

DECLARE
  TYPE emp_id_tbl IS TABLE OF emp.emp_id%type;
  l_emp_ids emp_id_tbl ;
BEGIN
  SELECT emp_id
    BULK COLLECT INTO l_emp_ids 
    FROM emp;

  FOR i IN l_emp_ids .FIRST .. l_empnos.LAST
  LOOP
    dbms_output.put_line( l_emp_ids (i) );
  END LOOP;
END;

Если ваш запрос может возвращать тысячи строк, однако, выборка всех данных в коллекции может использовать больше памяти PGA, чем вам хотелось бы, и вам может понадобиться извлечь строки в куски, используя предложение LIMIT. Но это, похоже, будет опережать нас в этот момент.

Ответ 2

Джастин Кейв объяснил, как это сделать, но специально посмотреть на полученную вами ошибку, из-за этого:

eid emp_ID%TYPE;

При использовании %TYPE вам нужно указать имя таблицы, а также имя столбца:

eid emp.emp_ID%TYPE;

Если вы выбрали все столбцы в строке, вы также можете посмотреть %ROWTYPE.

В вашем подходе также были сделаны два предположения: первоначальный выбор в eid нашел самый низкий идентификатор, который отнюдь не гарантирован; и что все последующие идентификационные значения являются последовательными. И вы объявляете и заселяете aRows, но ссылаетесь на Tot_Rows.