2013-11-27 1 views
0
DECLARE 
    CURSOR EMPCUR 
     SELECT EMPNO,ENAME,SAL,ROWNUM 
     FROM (SELECT * 
       FROM EMP 
       ORDER BY SAL DESC) 
     WHERE ROWNUM<=3 
     ORDER BY ROWNUM; 
BEGIN 
    FOR EMPREC IN EMPCUR 
    LOOP 
    DBMS_OUTPUT.PUT_LINE('RANK '||EMPREC.ROWNUM); 
    DBMS_OUTPUT.PUT_LINE(EMPREC.EMONO||' - '||EMPREC.ENAME||' - '||EMPREC.SAL); 
    END LOOP; 
END; 
/

Этот код не работает:подзапрос для получения лучших 3 ROWNUM не работает в PL/SQL

Ошибка в строке 2: ORA-06550: строка 2, столбец 17: PLS-00103: Встречающиеся символ «SELECT», когда ожидает одно из следующих действий: (; это вернуть символ «является» был заменен на «SELECT», чтобы продолжить

+1

У вас есть ключевое слово 'IS', пропущенное в декларации курсора« EMPCUR ». Более того, в этой конкретной ситуации нет необходимости использовать 'ORDER BY ROWNUM'. –

ответ

0

Вы пропустили IS об объявлении курсора и есть. опечатка в строке7 EMPREC.EMONO.

Попробуйте, как это,

DECLARE 
    CURSOR EMPCUR IS SELECT EMPNO,ENAME,SAL,ROWNUM FROM (SELECT * FROM EMP ORDER BY SAL DESC) WHERE ROWNUM<=3 ORDER BY ROWNUM; 
BEGIN 
    FOR EMPREC IN EMPCUR 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('RANK '||EMPREC.ROWNUM); 
     DBMS_OUTPUT.PUT_LINE(EMPREC.EMPNO||' - '||EMPREC.ENAME||' - '||EMPREC.SAL); 
    END LOOP; 
END; 
/
0

Я хотел бы предложить, что рейтинговые вещи, используя RowNum псевдостолбец в подзапроса в лучшем случае некорректный подход, редко доставки по фактической цели. Например, хотите ли вы, чтобы работники получали три зарплаты? Или вы всегда хотите до трех записей? Как это уравнение справляется с сотрудниками с одинаковой зарплатой? И т. Д.

Это лучший подход к использованию аналитических функций, определение ваших явных ранжировок в этих функциях и возврат результатов, которые фактически отвечают на вопрос.

begin 
    for rec in (select sq.* 
        from (select e.employee_id 
           , e.first_name ||' '|| e.last_name as full_name 
           , e.salary 
           , rank() over (order by e.salary desc) as salary_rank 
          from hr.employees e) sq 
        where sq.salary_rank <= 3 
        order by sq.salary desc) 
    loop 
     dbms_output.put_line('RANK ' || rec.salary_rank); 
     dbms_output.put_line(rec.employee_id || ' - ' || rec.full_name || ' - ' || rec.salary); 
    end loop; 
end;