Nested cursors in oracle - oracle

I got this stored procedure in oracle
create or replace
procedure mayor_sueldo
as
cursor c_depto is select deptno from dept;
c_deptno dept.deptno%type;
c_empno number;
c_ename emp.ename%type;
c_job emp.job%type;
c_sal emp.sal%type;
begin
open c_depto;
fetch c_depto into c_deptno;
while ( c_depto%found )loop
select empno, ename, job, sal into c_empno, c_ename, c_job, c_sal from emp where sal = (select max(sal) from emp where(deptno = c_deptno) );
dbms_output.put_line( c_empno||'-'||c_ename||'-'||c_job||' '||c_sal );
fetch c_depto into c_deptno;
end loop;
close c_depto;
end;
the problem is inside the query inside the while block if the query returns one and only one row there is no problem but what about when the query return more than one row i was thinking that i could use another cursor but idk how.
please help me

maybe this will help: for _row in (select ....) loop dbms_output(_row.a || ..); end loop;

Related

Cursor/bulk collect

I was trying to display hiredate using lead function with cursor however I'm getting this error message - PLS-00435: DML statement without BULK In-BIND cannot be used inside FORALL. Please guide me.
SET SERVEROUTPUT ON
DECLARE
CURSOR C_11 IS SELECT * FROM EMP;
TYPE DD IS TABLE OF EMP%ROWTYPE;
CC DD;
VV EMP.HIREDATE%TYPE;
GG EMP.HIREDATE%TYPE;
BEGIN
OPEN C_11;
LOOP
FETCH C_11 BULK COLLECT INTO CC LIMIT 1000;
FORALL I IN CC.FIRST..CC.LAST
SELECT HIREDATE,LEAD(HIREDATE) OVER(ORDER BY HIREDATE) INTO VV,GG FROM EMP;
DBMS_OUTPUT.PUT_LINE (VV ||' '||GG);
EXIT WHEN C_11%NOTFOUND;
END LOOP;
CLOSE C_11;
END;
PLS-00435: DML statement without BULK In-BIND cannot be used inside
FORALL.
FORALL statement is only used for INSERT / UPDATE or DELETE . It doesnot support SELECT.
Read the FORALL Restrictions:
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/forall_statement.htm
Alternatively you can do it as shown below:
DECLARE
CURSOR c_11 IS
SELECT hiredate,
LEAD(hiredate) OVER( ORDER BY hiredate ) DT
FROM emp;
TYPE dd IS TABLE OF c_11%rowtype;
cc dd;
BEGIN
OPEN c_11;
LOOP
FETCH c_11 BULK COLLECT INTO cc LIMIT 100;
FOR i IN 1..cc.count
LOOP
dbms_output.put_line(cc(i).hiredate || ' -- ' || cc(i).dt);
END LOOP;
EXIT WHEN c_11%notfound;
END LOOP;
CLOSE c_11;
END;

Statement ignored error while inserting data

I am writing procedure to insert data to one table by fetching data from another table. While inserting the data an error occurs (SQL Statement ignored) and (in this place, this column is forbidden). Can you suggest what I am doing wrong
SET SERVEROUTPUT ON;
CREATE OR REPLACE PROCEDURE KOL2
IS
CURSOR CUR IS SELECT empno, ename, SUM(SAL) sal FROM EMP where job =
'MANAGER';
nr_kier NUMBER; nazwisko_kier varchar(20); suma_pensji int;
ostatnia_mod date;
BEGIN
OPEN CUR;
LOOP
FETCH CUR INTO nr_kier, nazwisko_kier, suma_pensji;
EXIT WHEN CUR%NOTFOUND;
INSERT INTO statystyka_kierownikow (nr_kier , naziwsko_kier,
suma_pensji, ostatnia_mod)
VALUES (nr_kier, nazwisko_kier, sal, sysdate);
END LOOP;
CLOSE CUR;
COMMIT;
END;
what you are trying to do is time consuming task. It is not even suitable for SQL. You are trying to fetch every record and make insertion one-by-one.
Check my solution below.
INSERT INTO statystyka_kierownikow
(nr_kier , naziwsko_kier, suma_pensji, ostatnia_mod)
SELECT empno, ename, SUM(SAL) sal
FROM EMP where job = 'MANAGER'
GROUP BY empno, ename;

How can get deptno number from user and print the all employees, belongs deptno 10 in Oracle 11g

How can get deptno number from user and print the all employees, belongs deptno 10 in Oracle 11g
**Answer is
declare
cursor a(T number) is
Select *from EMp where Deptno = T;
Em a%rowtype;
begin
open a(&b);
loop
Fetch a into Em;
exit when a%notfound;
dbms_output.put_line(Em.EName);
end loop;
END;
/**
declare
cursor a(T number) is
Select *from EMp where Deptno = T;
Em a%rowtype;
begin
open a(&b);
loop
Fetch a into Em;
exit when a%notfound;
dbms_output.put_line(Em.EName);
end loop;
END;
/
You can simplify your code by using an implicit cursor ( T must be provided to the code block below, of course):
BEGIN
FOR i IN (
SELECT *
FROM emp
WHERE deptno = T
) LOOP
dbms_output.put_line(i.EName);
END LOOP;
END;

I want to return top 4 highest salaries from each dept along with deptno and dname in a stored procedure

I want to return top 4 highest salaries from each dept along with deptno and dname in a stored procedure.
when deptno is not included there is no error but
When including deptno im getting an error invalid number.
ORA-01722: invalid number
Here is the code
create or replace procedure tpro2(dno in emp.deptno%type,dnum out dept.deptno%type, name out emp.ename%type, sal out emp.sal%type,dname out dept.dname%type, cur out sys_refcursor)
is begin
open cur for select ename , sal, dname, dept.deptno from (select * from emp order by sal desc)emp, dept where emp.deptno=dept.deptno and emp.deptno=dno and rownum<=4;
end tpro2;
/
declare
dnum dept.deptno%type;
name emp.ename%type;
sal emp.sal%type;
dname dept.dname%type;
cur sys_refcursor;
begin
tpro2(&dno,dnum,name,sal,dname,cur);
loop
fetch cur into dnum,name,sal,dname;
exit when cur%notfound;
dbms_output.put_line(dnum||' '||name||' '||sal||' '||dname);
end loop;
close cur;
end;
/
Please help!!!
open cur for select ename, sal, dname, dept.deptno
fetch cur into dnum, name, sal, dname;
Does you see nothing suspicious here? :)
I would use window functions to get the information you need without writing a stored procedure at all:
SELECT ename, sal, dname, deptno
RANK() OVER (PARTITION BY deptno ORDER BY sal DESC) "Rank"
FROM emp e inner join dept d using (deptno)

pl/sql query which takes deptno from emp as input and return ename, sal all the columns from dept table

Can anyone please help me in solving this.
I need to write a pl/sql query which takes deptno from emp as input and returns ename, sal plus all the columns from dept table.(I don't want to declare the columns individually, instead I want to use %rowtype).
I have tried it in several ways. one of them is mentioned below.
Creation--
CREATE OR REPLACE PROCEDURE PROC01(
DNO EMP.DEPTNO%TYPE,
REC OUT DEPT%ROWTYPE,
NAME OUT EMP.ENAME%TYPE,
SAL OUT EMP.SAL%TYPE
, MY_CURSOR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN MY_CURSOR FOR
SELECT D.*, ENAME, SAL
FROM EMP, DEPT D
WHERE EMP.DEPTNO = D.DEPTNO
AND D.DEPTNO = DNO;
END PROC01;
/
--Declare & Execution
DECLARE
REC DEPT%ROWTYPE;
NAME EMP.ENAME%TYPE;
SAL EMP.SAL%TYPE;
MY_CURSOR SYS_REFCURSOR;
BEGIN
PROC01(&DNO,REC, NAME, SAL, MY_CURSOR);
LOOP
FETCH MY_CURSOR INTO REC, NAME, SAL;
EXIT WHEN MY_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(REC.DNAME||' '||NAME||' '||SAL);
END LOOP;
CLOSE MY_CURSOR;
END;
/
ERROR :--
expression 'REC' in the INTO list is of wrong type
Thanks in advance...
The error is because of oracle can't fetch cursor in both rec type and normal type together.
I changed your query and it's working NOW!
Procedure :
CREATE OR REPLACE PROCEDURE PROC01(DNO IN emp.deptno%TYPE,
/*REC OUT DEPT%ROWTYPE,
NAME OUT EMP.ENAME%TYPE,
SAL OUT EMP.SAL%TYPE,*/
MY_CURSOR OUT SYS_REFCURSOR) IS
BEGIN
OPEN MY_CURSOR FOR
SELECT D.*, ENAME, SAL
FROM EMP, DEPT D
WHERE EMP.DEPTNO = D.DEPTNO
AND D.DEPTNO = DNO;
END PROC01;
Test code :
DECLARE
REC DEPT%ROWTYPE;
DEPTNO DEPT.deptno%TYPE;
DNAME DEPT.dname%TYPE;
LOC DEPT.loc%TYPE;
NAME EMP.ENAME%TYPE;
SAL EMP.SAL%TYPE;
MY_CURSOR SYS_REFCURSOR;
BEGIN
PROC01(&DNO, /*REC, NAME, SAL,*/ MY_CURSOR);
LOOP
FETCH MY_CURSOR
INTO /*REC*/ DEPTNO, DNAME, LOC, NAME, SAL;
EXIT WHEN MY_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( /*REC.*/ DNAME || ' ' || NAME || ' ' || SAL);
END LOOP;
CLOSE MY_CURSOR;
END;

Resources