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;
/
This code does not work:
ERROR at line 2: ORA-06550: line 2, column 17: PLS-00103: Encountered the symbol "SELECT" when expecting one of the following: ( ; is return The symbol "is" was substituted for "SELECT" to continue.
You have missed a IS
on cursor declaration and there is a typo in line7 EMPREC.EMONO
.
Try like this,
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;
/
I would like to suggest that ranking things using the rownum pseudocolumn in a subquery is at best a flawed approach, rarely delivering on the actual goal. For instance, do you want the employees with the top three salaries? Or do you always want up to three records? How does this equation cope with employees with identical salaries? Et cetera.
It is a better approach to use the analytic functions, define your explicit rankings in those functions and return the results that actually answer the question.
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.