Procedure finding senior employees [closed] - sql

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I tried writing a PL/SQL procedure to find if an employee has worked for at least 10 years.
create or REPLACE PROCEDURE IsSenEmp IS
jdate date;
years NUMBER;
BEGIN
SELECT HIRE_DATE into jdate
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
years := "MONTHS_BETWEEN"(SYSDATE, jdate)/12;
if years >= 10 THEN
dbms_output.put_line(first_name||' has worked for more than 10 years.');
ELSE
dbms_output.put_line(first_name||' has NOT worked for 10 years.');
end if;
END;
But I'm getting
Procedure created with compilation error.
in SQL Plus.

You have to declare first_name local variable, something like this:
CREATE OR REPLACE PROCEDURE IsSenEmp IS
-- When declaring local variables let's use table fields' types: %type
jdate EMPLOYEES.HIRE_DATE%TYPE;
years NUMBER;
first_name EMPLOYEES.FIRST_NAME%TYPE; -- <- first_name must be declared
BEGIN
SELECT HIRE_DATE,
FIRST_NAME -- reading FIRST_NAME field ...
INTO jdate,
first_name -- ... into first_name local variable
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
years := "MONTHS_BETWEEN"(SYSDATE, jdate) / 12;
if years >= 10 THEN
dbms_output.put_line(first_name || ' has worked for more than 10 years.');
ELSE
dbms_output.put_line(first_name || ' has NOT worked for 10 years.');
END IF;
END;

I don't have access to HR schema so I created my own sample table. Here you go:
SQL> CREATE TABLE employees
2 (
3 employee_id NUMBER,
4 hire_date DATE,
5 first_name VARCHAR2 (20)
6 );
Table created.
SQL> INSERT INTO employees
2 VALUES (100, DATE '2017-10-25', 'Littlefoot');
1 row created.
SQL> CREATE OR REPLACE PROCEDURE IsSenEmp
2 IS
3 jdate DATE;
4 l_first_name employees.first_name%TYPE;
5 years NUMBER;
6 BEGIN
7 SELECT HIRE_DATE, first_name
8 INTO jdate, l_first_name
9 FROM EMPLOYEES
10 WHERE EMPLOYEE_ID = 100;
11
12 years := MONTHS_BETWEEN (SYSDATE, jdate) / 12;
13
14 IF years >= 10
15 THEN
16 DBMS_OUTPUT.put_line (
17 l_first_name || ' has worked for more than 10 years.');
18 ELSE
19 DBMS_OUTPUT.put_line (l_first_name || ' has NOT worked for 10 years.');
20 END IF;
21 END;
22 /
Procedure created.
SQL> EXEC issenemp;
Littlefoot has NOT worked for 10 years.
PL/SQL procedure successfully completed.
SQL>

you forgot to declare first_name
create or REPLACE PROCEDURE IsSenEmp IS
jdate date;
years NUMBER;
first_name VARCHAR2(100);
BEGIN
SELECT HIRE_DATE into jdate
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
SELECT first_name into first_name
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
years := "MONTHS_BETWEEN"(SYSDATE, jdate)/12;
if years >= 10 THEN
dbms_output.put_line(first_name||' has worked for more than 10 years.');
ELSE
dbms_output.put_line(first_name||' has NOT worked for 10 years.');
end if;
END;

Related

Can we use %rowtype attribute inside the plsql record?

Can we use %rowtype attribute inside the plsql record like the below code..
type xx is RECORD
( v_emp employees%rowtype ,
v_loc departments.LOCATION_ID%type
);
v_data xx;
I can, and I hope you can too.
SQL> set serveroutput on
SQL>
SQL> declare
2 type xx is RECORD
3 ( v_emp emp%rowtype ,
4 v_loc dept.LOC%type );
5 v_data xx;
6 begin
7 v_data.v_emp.ename := 'LF';
8 v_data.v_loc := 'x';
9
10 dbms_output.put_line(v_data.v_emp.ename ||', '|| v_data.v_loc);
11 end;
12 /
LF, x
PL/SQL procedure successfully completed.
SQL>

Join table in PL/SQL

Hi i would like to ask i get an error when i run this code , can i know how to fix it, i want to know the doctor for this patient when i enter the patient id, thank you. below is my code
DECLARE
patientid(3) := &pt_id;
dname doc_name%type;
BEGIN
SELECT doc_name
INTO dname
FROM doctor
JOIN patient
ON doctor.doc_id = patient.doc_id
WHERE pt_id = patientid;
DBMS_OUTPUT.PUT_LINE('He/She is the patient of Dr.' || dname);
END;
What is patient(3) supposed to be? Datatype is missing!
Though, consider something like this:
SQL> set serveroutput on
SQL> declare
2 -- No : patientid(3):=&pt_id;
3 -- Better : patientid varchar2(3) := &pt_id; -- is it VARCHAR2? or NUMBER? Who knows ...
4 -- Even better:
5 l_pt_id patient.pt_id%type := &par_pt_id;
6 l_dname doctor.doc_name%type;
7 begin
8 select d.doc_name
9 into l_dname
10 from doctor d join patient p on d.doc_id = p.doc_id
11 where p.pt_id = l_pt_id;
12
13 dbms_output.put_line ('He/She is the patient of Dr. '|| l_dname);
14 end;
15 /
Enter value for par_pt_id: 100
He/She is the patient of Dr. Luffy
PL/SQL procedure successfully completed.
SQL>

pl-sql errror on select HR schema

i want to do something like that.. but in a function.. select * from employees where employee_id = &employee_id in HR schema of oracle
Q: Create Function “SEARCH_EMPLOYEE” that receives an Employee ID and returns all its attributes through an output parameter with a data structure that represents all its information
R:
Create or replace FUNCTION get_complete_employee (&in_employee_id IN NUMBER)
AS person_details;
BEGIN
SELECT * --'Name-'||first_name||' '|| last_name
into person_details
FROM employees;
Dbms_output.put_line(person_details);
-- END get_complete_employee;
end;
i have a error of sintax i guess..
i don't know what is wrong
If you are learning how to create the function which returns entire row of the table then following is the basic example of doing the same:
Table data:
SQL> select * from EMP;
EMP_ID EMP_NAME E
---------- -------------------- -
10 John N
20 May Y
SQL>
Function:
SQL> CREATE OR REPLACE FUNCTION GET_COMPLETE_EMPLOYEE (
2 IN_EMPLOYEE_ID IN NUMBER
3 ) RETURN EMP%ROWTYPE AS
4 MY_ROWTYPE EMP%ROWTYPE;
5 BEGIN
6 SELECT
7 * --'Name-'||first_name||' '|| last_name
8 INTO MY_ROWTYPE
9 FROM
10 EMP
11 WHERE
12 EMP_ID = IN_EMPLOYEE_ID;
13
14 RETURN MY_ROWTYPE;
15 END;
16 /
Function created.
SQL>
Calling the function and result:
SQL> SET SERVEROUT ON
SQL>
SQL> DECLARE
2 EMPTYPE EMP%ROWTYPE;
3 BEGIN
4 EMPTYPE := GET_COMPLETE_EMPLOYEE(10);
5 DBMS_OUTPUT.PUT_LINE(EMPTYPE.EMP_NAME);
6 END;
7 /
John
You must have to handle multiple exception scenarios in real-world coding.
Cheers!!

Converting column data into row in pl/sql

Hi When i went for an interview they asked me this question.
Create table course(Name CHAR(10));
insert into course values ('Java');
insert into course values ('Oracle');
insert into course values ('Python');
insert into course values ('C');
insert into course values ('C++');
o/p:
Java Oracle python c c++
Thanks in advance,
Sandhya.
I presume that NAME column's datatype should have been VARCHAR2, not CHAR.
Anyway, another option (similar to Tejash's LISTAGG) which uses XMLAGG and is safer if the result is larger than 4000 characters.
SQL> SELECT RTRIM (
2 XMLAGG (XMLELEMENT (e, name || ' ') ORDER BY null).EXTRACT (
3 '//text()'),
4 ',')
5 result
6 FROM course;
RESULT
------------------------------------------------------------
Java Oracle Python C C++
SQL>
Or, as you tagged the question with PL/SQL tag, then an anonymous PL/SQL block might look like this:
SQL> set serveroutput on
SQL>
SQL> declare
2 l_result varchar2(100);
3 begin
4 for cur_r in (select name from course) loop
5 l_result := l_result ||' '|| cur_r.name;
6 end loop;
7
8 dbms_output.put_line(trim(l_result));
9 end;
10 /
Java Oracle Python C C++
PL/SQL procedure successfully completed.
SQL>
Or - similarly - a function:
SQL> create or replace function f_course
2 return varchar2
3 is
4 l_result varchar2(100);
5 begin
6 for cur_r in (select name from course) loop
7 l_result := l_result ||' '|| cur_r.name;
8 end loop;
9
10 return trim(l_result);
11 end;
12 /
Function created.
SQL> select f_course from dual;
F_COURSE
--------------------------------------------------------------
Java Oracle Python C C++
SQL>
Or, a procedure with an OUT parameter:
SQL> create or replace procedure p_course (par_result out varchar2)
2 is
3 l_result varchar2(100);
4 begin
5 for cur_r in (select name from course) loop
6 l_result := l_result ||' '|| cur_r.name;
7 end loop;
8
9 par_result := trim(l_result);
10 end;
11 /
Procedure created.
SQL> declare
2 l_out varchar2(100);
3 begin
4 p_course(l_out);
5 dbms_output.put_line(l_out);
6 end;
7 /
Java Oracle Python C C++
PL/SQL procedure successfully completed.
SQL>
As you can see, quite a few options; use the one that most suits your needs.
You can use an aggregate function - LISTAGG as following:
SQL> SELECT
2 LISTAGG(TRIM(NAME), ' ') WITHIN GROUP(
3 ORDER BY
4 NULL
5 ) AS RESULT
6 FROM
7 COURSE;
RESULT
--------------------------------------------------------------------------------
C C++ Java Oracle Python
SQL>
Cheers!!

Display result from loop tables (oracle, pl/sql)

I'm try to loop some tables and run select as below:
set serveroutput on
declare
type tables_names is table of varchar2(30);
type selectTable is table of varchar2(30);
tName tables_names;
sTableName selectTable;
begin;
tName := tables_names('PERIOD','SETTING','RAP','LOG');
sTableName := selectTable('m_table1','m_table2','m_table3','m_table4','m_table5');
for i in 1..tName.count loop
for j in 1..sTableName.count loop
select col10, count(*) from user.sTableName(j)
where table_name = tName(i) group by col10;
end loop;
end loop;
end;
I got error:PL/SQL: ORA-00933.
Can you please tell me how can I correctly run PL/SQL procedure to have displayed result from my select?
UPDATE: looking result
Normally, to get this I need to run below select's:
select column_name,
count(*) as countColumn
from user.m_table1 where table_name = 'PERIOD' group by column_name;
select column_name,
count(*) as countColumn
from user.m_table2 where table_name = 'PERIOD' group by column_name;
Oracle complains (ORA-00933) that command isn't properly ended. That's probably because of a semi-colon behind the BEGIN; also, you lack the INTO clause.
I'm not sure what PERIOD, SETTING, ... are opposed to m_table1, m_table2, ... Which ones of those are table names? What are those other values, then?
Anyway: here's an example which shows how to do something like that - counting rows from tables. Try to adjust it to your situation, or - possibly - add some more info so that we'd know what you are doing.
SQL> set serveroutput on
SQL> declare
2 tname sys.odcivarchar2list := sys.odcivarchar2list();
3 l_cnt number;
4 l_str varchar2(200);
5 begin
6 tname := sys.odcivarchar2list('EMP', 'DEPT');
7
8 for i in 1 .. tname.count loop
9 l_str := 'select count(*) from ' || tname(i);
10 execute immediate l_str into l_cnt;
11 dbms_output.put_line(tname(i) ||': '|| l_cnt);
12 end loop;
13 end;
14 /
EMP: 14
DEPT: 4
PL/SQL procedure successfully completed.
SQL>
[EDIT: added GROUP BY option]
Here you go; as EMP and DEPT share the DEPTNO column, I chose it for a GROUP BY column.
SQL> declare
2 tname sys.odcivarchar2list := sys.odcivarchar2list();
3 type t_job is record (deptno varchar2(20), cnt number);
4 type t_tjob is table of t_job;
5 l_tjob t_tjob := t_tjob();
6 l_str varchar2(200);
7 begin
8 tname := sys.odcivarchar2list('EMP', 'DEPT');
9
10 for i in 1 .. tname.count loop
11 l_str := 'select deptno, count(*) from ' || tname(i) ||' group by deptno';
12 execute immediate l_str bulk collect into l_tjob;
13
14 for j in l_tjob.first .. l_tjob.last loop
15 dbms_output.put_Line('Table ' || tname(i) || ': Deptno ' || l_tjob(j).deptno||
16 ': number of rows = '|| l_tjob(j).cnt);
17 end loop;
18
19 end loop;
20 end;
21 /
Table EMP: Deptno 30: number of rows = 6
Table EMP: Deptno 20: number of rows = 5
Table EMP: Deptno 10: number of rows = 3
Table DEPT: Deptno 10: number of rows = 1
Table DEPT: Deptno 20: number of rows = 1
Table DEPT: Deptno 30: number of rows = 1
Table DEPT: Deptno 40: number of rows = 1
PL/SQL procedure successfully completed.
SQL>
You are probably looking for something like this. Note that you can't run a simple select statement inside a PL/SQL without INTO clause. use a refcursor and DBMS_SQL.RETURN_RESULT
DECLARE
TYPE tables_names IS TABLE OF VARCHAR2 (30);
TYPE selectTable IS TABLE OF VARCHAR2 (30);
tName tables_names;
sTableName selectTable;
rc SYS_REFCURSOR;
BEGIN
tName :=
tables_names ('PERIOD',
'SETTING',
'RAP',
'LOG');
sTableName :=
selectTable ('m_table1',
'm_table2',
'm_table3',
'm_table4',
'm_table5');
FOR i IN 1 .. tName.COUNT
LOOP
FOR j IN 1 .. sTableName.COUNT
LOOP
OPEN rc FOR
'select col10, count(*) from '||USER||'.'
|| sTableName (j)
|| ' where table_name = '''
|| tName (i)
|| ''' group by col10';
DBMS_SQL.RETURN_RESULT (rc);
END LOOP;
END LOOP;
END;
/