Using more than one table in a procedure in oracle - oracle

I am new to PL/SQL. Can someone help me to solve the following scenario.
How to get the employee details like emp_id,full_name,department_id,total_salary
if we give Postal code as input parameter to the procedure. I know how to write a procedure to employee details from one table but here we have to use three tables.
Can any one help.
I am also providing the code I have used
Create or Replace Procedure P1(postal_cd varchar2)
as
v_empid number;
v_name varchar2(20);
v_dept_Id number(10);
v_dept_nm varchar2(10);
v_hiredate date;
v_sal number;
begin
select e.emp_id
, e.full_name||' '||e.last_name
, e.department_id
, d.department_name
, e.hiredata
, sum(e.sal) salary
into v_empid
, v_name
, v_dept_id
, v_dept_nm
, v_hiredate
, v_sal
from employees e
inner join departments d
on e.department_id = d.department_id
inner join locations l
on d.location_id = l.location.id
where l.postal_code = postal_cd
;
end;
Kindly let me know if the above query gives me the required result. Thanks in advance.

Since you want to display employee details belonging to a particular postal code the following code should help.
CREATE OR REPLACE PROCEDURE p1(postal_cd VARCHAR2)
AS
v_empid NUMBER;
v_name VARCHAR2(20);
v_dept_Id NUMBER(10);
v_dept_nm VARCHAR2(10);
v_hiredate DATE;
v_sal NUMBER;
CURSOR cur_employee
IS
SELECT e.emp_id,
e.full_name||' '||e.last_name AS emp_full_name,
e.department_id,
d.department_name,
e.hiredata,
e.sal
INTO v_empid,
v_name,
v_dept_id,
v_dept_nm,
v_hiredate,
v_sal
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id
INNER JOIN locations l ON d.location_id = l.location_id
WHERE l.postal_code = postal_cd;
BEGIN
FOR c_employee IN cur_employee
LOOP
DBMS_OUTPUT.PUT_LINE(c_employee.emp_full_name || ' ' ||c_employee.department_id||' '||c_employee.department_name||' '||c_employee.hiredata ||' ' || c_employee.sal);
END LOOP;
END;

Related

I have data with formulas and User expecting calculation of data dynamically

I attached my sample data and in summary expected calculation dynamically.
For example: Table 1, Table 2 is the source data and Lookup table (Business_rule) had calculation rule under calculation_rule. so using Table 1, Table 2 data user expected apply calculation_rule and want to get result as per in Output table. Source table are in Oracle Database.
I tried with all algorithms like xmltable etc. but not working.
Here table 1 = employees; table 2 = departments; output is dbms_output.
DECLARE
v_sql VARCHAR2(1000);
lc_cur SYS_REFCURSOR;
ln_employee_id VARCHAR2(10);
ln_department_id NUMBER;
ln_calc_amt NUMBER;
BEGIN
FOR rec IN (SELECT e.department_id, br.metric_code
FROM employees e INNER JOIN business_rule br on e.department_id = br.department_id
)
LOOP
SELECT 'SELECT e.employee_id, d.department_id,'||calculation_rule||'
from employees e inner join departments d on e.department_id = d.department_id
where e.department_id = '||rec.department_id
INTO v_sql
FROM business_rule WHERE department_id = rec.department_id;
OPEN lc_cur FOR v_sql;
LOOP
FETCH lc_cur INTO ln_employee_id, ln_department_id, ln_calc_amt;
EXIT WHEN lc_cur%NOTFOUND;
dbms_output.put_line(ln_employee_id||' - '||ln_department_id||' - '||rec.metric_code||' - '||ln_calc_amt);
END LOOP;
CLOSE lc_cur;
END LOOP;
END;

HOW TO CALL THIS PROCEDURE?

Here I'm Creating procedure to inner join two tables.
create or replace PROCEDURE TBL_EMPLOYEE_PROJECT(
EMP_ID IN TBL_EMPLOYEE.EMPLOYEE_ID%TYPE,
CUR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN CUR FOR
SELECT E.EMPLOYEE_ID EMPLOYEE_ID,
E.FIRST_NAME FIRST_NAME,
E.LAST_NAME LAST_NAME,
E.MIDDLE_NAME MIDDLE_NAME,
E.SALARY SALARY,
E.DATE_OF_BIRTH DATE_OF_BIRTH,
E.DEPARTMENT_ID DEPARTMENT_ID,
E.INSERTED_BY INSERTED_BY,
E.INSERTED_DT INSERTED_DT,
E.UPDATE_BY UPDATE_BY,
E.UPDATED_DT UPDATED_DT,
E.DELETED_BY DELETED_BY,
E.DELETED_DT DELETED_DT,
E.MANAGER_ID MANAGER_ID,
D.DEPARTMENT_ID DEPARTMENT_ID_0,
D.DEPARTMENT_NAME DEPARTMENT_NAME,
D.DEPARTMENT_LOCATION DEPARTMENT_LOCATION
FROM TBL_EMPLOYEE E
INNER JOIN DEPARTMENT D
ON ( E.DEPARTMENT_ID = D.DEPARTMENT_ID )
WHERE E.EMPLOYEE_ID = EMP_ID;
END;
But Don't Know How To Call This Stored Procedure.
Please Tell How To Call This Procedure
Declare
returned_refcursor SYS_REFCURSOR := Null;
Begin
BL_EMPLOYEE_PROJECT(some_emp_id, returned_refcursor);
-- variable returned_refcursor now has a pointer to the CUR from procedure
End;
Here is a simple example
create or replace PROCEDURE AA(
EMP_ID IN VARCHAR2,
CUR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN CUR FOR
Select * From
(
SELECT '12' "ID", 'Name for 12' "NAME" FROM DUAL UNION ALL
SELECT '13' "ID", 'Name for 13' "NAME" FROM DUAL
)
WHERE ID = EMP_ID;
END;
-- Use it
Declare
returned_refcursor SYS_REFCURSOR := Null;
myId VarChar2(10);
myName VarChar2(20);
Begin
AA('12', returned_refcursor);
-- variable returned_refcursor now has a pointer to the CUR from procedure
Fetch returned_refcursor InTo myID, myName;
DBMS_OUTPUT.PUT_LINE(myId);
DBMS_OUTPUT.PUT_LINE(myName);
End
-- Result
-- anonymous block completed
-- 12
-- Name for 12

how to get the output of stored procedure with in and output parameters pl/sql

i have created the stored procedure ...in which getting employee_name ,salary and his manager_name .. procedure is created successfully but when i am executing giving an error of invalid parameter.. how do i execute this procedure ...
create or replace procedure employee_manager (
dept_id in number,
fname out varchar2,
v_sal out number,
fname1 out varchar2
)
is
begin
select a.first_name manager_name,
b.first_name employee_name,
b.salary
into fname,
fname1,
v_sal
from employees a join employees b on a.employee_id = b.manager_id
where a.department_id = dept_id;
end employee_manager ;
If would have helped if you showed us what exactly happened when you called the procedure, or - at least - posted ORA-xxxxx error code. With the info we have so far, we can only guess.
My guess is that you wrongly called it. As it accepts one IN parameter and three OUT ones, you'll have to declare three variables; something like this:
declare
l_fname employees.first_name%type;
l_sal employees.salary%type;
l_fname1 employees.first_name%type;
begin
employee_manager(dept_id => 10,
fname => l_fname,
v_sal => l_sal,
fname1 => l_fname1);
dbms_output.put_line('Values returned are: ' || l_fname ||', '|| l_sal ||', '|| l_fname1);
end;
/

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;

can plsql function return object

i have encountered a problem while writing the following code:
create or replace function getashish(dept varchar2) return emp3 as
emp5 emp3;
str varchar2(300);
begin
str := 'select e.last_name,l.city,e.salary from employees e join departments d
on e.department_id = d.department_id join locations l on d.location_id=l.location_id where
d.department_name = :dept';
execute immediate str bulk collect into emp5 using dept;
end;
emp 3 is table of an object as defined below:
create or replace type emp1 as object (lname varchar2(10),city varchar2(10),sal number(10));
create or replace type emp3 as table of emp1;
i am getting the following error while executing the function: SQL Error:
ORA-00932: inconsistent datatypes: expected - got -
thank you for your anticipated help and support.
try declaring emp5 as a datatype of emp1.
emp5 emp1 := emp1();
Please try the below, (added emp1() to your select query inside function and returned emp5)
CREATE OR REPLACE FUNCTION getashish(
dept VARCHAR2)
RETURN emp3
AS
emp5 emp3 := emp3();
str VARCHAR2(300);
BEGIN
str := 'select emp1(e.last_name,l.city,e.salary) from employees e join departments d
on e.department_id = d.department_id join locations l on d.location_id=l.location_id where
d.department_name = :dept';
EXECUTE immediate str bulk collect INTO emp5 USING dept;
RETURN emp5;
END;
/
and the caller block
SELECT * FROM TABLE( CAST(getashish('IT') AS emp3))
UNION
SELECT * FROM TABLE( CAST(getashish('FINANCE') AS emp3));
the function returns a Table, and hence cant be used in SELECT clause, since it is supposed to return one row only, if have to be used in SELECT. Hope you got the concept!
EDIT: Whatever I did!
create table employees
(last_name varchar2(10),salary number,department_id varchar2(10));
create table locations
(location_id varchar2(10),city varchar2(10));
drop table employees;
create table departments
(department_id varchar2(10),location_id varchar2(10),department_name varchar2(10));
insert into employees values ('ASHISH',6000000,'D1');
insert into employees values ('MAHESH',5000000,'D2');
insert into departments values('D1','L1','IT');
insert into departments values('D2','L2','FINANCE');
insert into locations values('L1','Gurgoan');
insert into locations values('L2','Chennai');
commit;
create or replace type emp1 as object (lname varchar2(10),city varchar2(10),sal number(10));
/
create or replace type emp3 as table of emp1;
/
CREATE OR REPLACE FUNCTION getashish(
dept VARCHAR2)
RETURN emp3
AS
emp5 emp3 := emp3();
str VARCHAR2(300);
BEGIN
str := 'select emp1(e.last_name,l.city,e.salary) from employees e join departments d
on e.department_id = d.department_id join locations l on d.location_id=l.location_id where
d.department_name = :dept';
EXECUTE immediate str bulk collect INTO emp5 USING dept;
RETURN emp5;
END;
/
SELECT * FROM TABLE( CAST(getashish('IT') AS emp3))
UNION
SELECT * FROM TABLE( CAST(getashish('FINANCE') AS emp3));
SQL> SELECT * FROM TABLE( CAST(getashish('IT') AS emp3))
2 UNION
3 SELECT * FROM TABLE( CAST(getashish('FINANCE') AS emp3));
LNAME CITY SAL
---------- ---------- ----------
ASHISH Gurgoan 6000000
MAHESH Chennai 5000000

Resources