Records not showing results - sql

CREATE TABLE manager (
mgrid INT PRIMARY KEY,
fname VARCHAR2(50),
city VARCHAR2(50)
);
The above is the manager table.
& Below is the code I wrote to get records.
DECLARE
TYPE mgr_info IS RECORD (
mgrid manager.mgrid%TYPE,
fname manager.fname%TYPE,
city manager.city%TYPE
);
mgr mgr_info;
id manager.mgrid%TYPE;
name manager.fname%TYPE;
mcity manager.city%TYPE;
BEGIN
SELECT
mgrid,
fname,
city
INTO mgr
FROM
manager
WHERE
city = 'Mumbai';
id := mgr.mgrid;
name := mgr.fname;
mcity := mgr.city;
dbms_output.put_line('Manager ID = '
|| id
|| ' || Manager Name = '
|| name
|| ' || City = '
|| mcity);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No Matching Record Found');
WHEN too_many_rows THEN
dbms_output.put_line('More than one matching Record Found');
END;
/
The issue is I am not able to get proper input even though I have a row that is a manager who lives in Mumbai City.
What is I am not doing that I am not able to get proper output.
Below are the inputs for the table:
insert into manager values(101,'mohan','jaipur');
insert into manager values(102,'sohan','surat');
insert into manager values(103,'rohan', 'delhi');
insert into manager values(104,'jagmohan','mumbai');

The table has Mumbai, the select uses mumbai. The case is different. #Littlefoot was right to ask for the INSERT statements, we couldn't have helped without them.
If you want the SELECT to work, you need to fold both table and query to the same case:
WHERE lower(city) = lower('Mumbai')

Related

PL/SQL procedure that should output the following

Just cant get the output correct, maybe a loop problem ?
Have tried a few things but
Just cant get the output correct
should look like
Department 1 SALES managed by Alvin
Total number of employees: 5
00110 Alvin
00103 Ami
00109 Michael
00101 Peter
00107 Wendy
Department 2 ACCOUNTING managed by Alice
Total number of employees: 2
00120 Alice
00125 Angela
Department 3 GAMES managed by Bob
Total number of employees: 2
00150 Bob
00105 Robert
CREATE TABLE Department (
D# NUMBER(5) NOT NULL, /* Department number */
DName VARCHAR2(30) NOT NULL, /* Department name */
Manager# CHAR(5) NOT NULL, /* Department manager number */
MSDate DATE, /* Manager start date */
CONSTRAINT Department_PK PRIMARY KEY(D#),
CONSTRAINT Department_CK UNIQUE(DName)
);
CREATE TABLE Employee (
E# CHAR(5) NOT NULL, /* Employee number */
Name VARCHAR2(30) NOT NULL, /* Employee name */
DOB Date, /* Date of birth */
Address VARCHAR2(50), /* Home address */
Sex CHAR, /* M-Male, F-Female */
Salary NUMBER(7,2), /* Salary */
Super# CHAR(5), /* Supervisor number */
D# NUMBER(5), /* Department number */
CONSTRAINT Employee_PK PRIMARY KEY(E#),
CONSTRAINT Employee_FK1 FOREIGN KEY (Super#) REFERENCES Employee(E#),
CONSTRAINT Employee_FK2 FOREIGN KEY (D#) REFERENCES Department (D#)
);
ARE THE TABLES
THE CODE I HAVE BEEN TRYING IS
CREATE OR REPLACE PROCEDURE
INSERT_MANAGER IS
MANAGER_NAME VARCHAR(40);
DEPT_# NUMBER(5);
DEPT_NAME VARCHAR(40);
EMP_# NUMBER(5);
EMP_NAME VARCHAR(40);
EMP_TOTAL NUMBER(6);
CURSOR MANAGER IS
SELECT Name, Department.D#,DName
INTO MANAGER_NAME, DEPT_#, DEPT_NAME
FROM Employee
JOIN Department
ON
Department.D# = Employee.D#
WHERE E# = Manager#
ORDER BY DEPT_# ASC;
CURSOR EMPLOYEE IS
SELECT COUNT(NAME),NAME,E#
INTO EMP_TOTAL,EMP_NAME,EMP_#
FROM Employee
JOIN Department ON
Department.D# = Employee.D#
WHERE E# = Manager#
GROUP BY NAME,E#;
BEGIN
OPEN MANAGER;
OPEN EMPLOYEE;
LOOP
FETCH MANAGER INTO MANAGER_NAME, DEPT_#, DEPT_NAME;
FETCH EMPLOYEE INTO EMP_TOTAL,EMP_NAME,EMP_#;
EXIT WHEN MANAGER%notfound;
DBMS_OUTPUT.PUT_LINE('Department ' || DEPT_# || ' ' || DEPT_NAME || ' Managed By: ' || MANAGER_NAME );
DBMS_OUTPUT.PUT_LINE('Total Number Of Emploees ' || EMP_TOTAL);
DBMS_OUTPUT.PUT_LINE(EMP_# || ' ' || EMP_NAME);
END LOOP;
CLOSE MANAGER;
END;
/
My current output lhas the correct manager
but the incorrect TOTAL NUMBER OF EMPLOYEES
and is only showing 1 of the Employees under that manager
Department 1 SALES Managed By: Alvin
Total Number Of Emploees 1
150 Bob
Department 2 ACCOUNTING Managed By: Alice
Total Number Of Emploees 1
338 Helmus
Department 3 GAMES Managed By: Bob
Total Number Of Emploees 1
110 Alvin
THANKS IN ADVANCE FOR ANY HELP.
LUKE
The following produces your desired output while for the most part maintaining your logic flow (except for a 2nd loop for the Employee cursor). But I have made a couple syntactical changes.
First, names are important. Attempt to name objects according to the function being preformed. For example the MANAGER cursor really gets nothing about the manager (except for name). What is gets is information about the department; also
renamed the employee cursor (just because 2 objects with the same name - cursor and table). Structurally, I moved getting the employee count to the department cursor (manager) as it pertains to the department not the employee. As far as naming goes the procedure name itself is misleading as the procedure has nothing to do with inserting managers (but I let it); unless of course it's just part of a larger process.
Definition consistence is also important, and there are problems with that here. For example: Look at table column employee.name vs. the variable manager_name. And what's with employee.e# vs. emp_#? A method to stay consistent is to anchor procedure variables to the table columns they represent.
So instead of "manager_name varchar(40)" use "manager_name employee.name%type"
BTW: Varchar is frowned upon use varchar2.
But I left these with your original definitions. (Just for fun I played around this the data values a little - just values not structure.) The result then:
create or replace procedure insert_manager is
-- department cursor variables
manager_name varchar(40);
dept_# number(5);
dept_name varchar(40);
emp_total number(6);
-- employee cursor variables
emp_# number(5);
emp_name varchar(40);
-- cursors definitions
cursor department_cur is
select name, d#, dname, demps
from ( select e.name
, d.d#
, d.dname
, count(e.e#) over (partition by d.d#) demps
, e.e#
, d.manager# m#
from employee e
join department d on d.d# = e.d#
)
where e# = m#
order by d# asc;
cursor employee_cur(ed# integer) is
select e.name, e.e#
from employee e
where e.d# = ed#;
begin
dbms_output.put_line( 'Chipmunks Gaming, LLC: Department Employee List as of ' || to_char(sysdate, 'dd-Mon-yyyy'));
open department_cur;
loop
fetch department_cur into manager_name, dept_#, dept_name, emp_total;
exit when department_cur%notfound;
dbms_output.put_line('Department ' || dept_# || ' ' || dept_name || ' Managed By: ' || manager_name);
dbms_output.put_line('Total Number Of Employees ' || emp_total);
open employee_cur (dept_#);
loop
fetch employee_cur into emp_name, emp_#;
exit when employee_cur%notfound;
dbms_output.put_line(emp_# || ' ' || emp_name);
end loop;
close employee_cur;
end loop;
close department_cur;
end insert_manager;
-- Generate test data
insert into Department (D#, DName, Manager#)
select 1, 'SALES', '00150' from dual union all
select 2, 'ACCOUNTING','00120' from dual union all
select 3, 'GAMES', '00110' from dual ;
insert into employee(E#, Name ,D# )
select '00150', 'Simon' ,1 from dual union all
select '00103', 'Ami' ,1 from dual union all
select '00109', 'Michael' ,1 from dual union all
select '00101', 'Peter' ,1 from dual union all
select '00107', 'Wendy' ,1 from dual union all
select '00120', 'Theodore' ,2 from dual union all
select '00125', 'Angela' ,2 from dual union all
select '00110', 'Alvin' ,3 from dual union all
select '00105', 'Robert' ,3 from dual ;
---------------------------------------------------------------------------------
-- run it
begin
insert_manager;
end;
The next big step would be using Implicit cursors (cursor for loops) instead of Explicit cursors. That would take of Opening, Looping through, and Closing the cursors. I'll leave that for you.
Good Luck. Hope this helps.

How to add a column to a table and have it displayed as the first column

I have table EMP with 2 columns ENM and EADD. Now I need to add a column EMPID but I want it to be displayed as the first column in the table, like EMPID, ENM, EADD.
Demo:
create table emp
( enm varchar2(20)
, eadd varchar2(100) );
alter table emp add empid number not null;
Describing emp gives:
Name Null? Type
------------------------------- -------- ----------------------------
ENM VARCHAR2(20)
EADD VARCHAR2(100)
EMPID NOT NULL NUMBER
Make all the columns except empid invisible and visible again:
begin
for r in (
select column_name
from user_tab_columns c
where c.table_name = 'EMP'
and c.column_name <> 'EMPID'
)
loop
execute immediate 'alter table emp modify '||r.column_name||' invisible';
execute immediate 'alter table emp modify '||r.column_name||' visible';
end loop;
end;
/
and now you have this:
Name Null? Type
------------------------------- -------- ----------------------------
EMPID NOT NULL NUMBER
ENM VARCHAR2(20)
EADD VARCHAR2(100)
As William Robertson suggests, using invisible and visible can be used to reorder columns. However if your table has a lot of fields this method can be obnoxious, especially if you are reordering multiple times during development.
There is always the tried and true method of dropping the table and recreating with the desired order.

ORACLE PL/SQL Function is created successfully but the execution body is not working

These are the list of tables I have created and inserted values for the created tables:
CREATE TABLE DEPARTMENT
(DEPARTMENT_ID NUMBER PRIMARY KEY,
DEPARTMENT_NAME VARCHAR(30) NOT NULL
);
CREATE TABLE JOBS
(JOB_ID NUMBER PRIMARY KEY,
JOB_TITLE VARCHAR(35) NOT NULL,
MIN_SALARY DECIMAL NOT NULL,
MAX_SALARY DECIMAL NOT NULL
);
CREATE TABLE EMPLOYEES
(EMPLOYEE_ID NUMBER PRIMARY KEY,
FIRST_NAME VARCHAR(20) NOT NULL,
LAST_NAME VARCHAR(25) NOT NULL,
EMAIL VARCHAR(25) NOT NULL,
PHONE_NUMBER VARCHAR(20) NOT NULL,
HIRE_DATE DATE NOT NULL,
JOB_ID NUMBER NOT NULL,
SALARY DECIMAL NOT NULL,
DEPARTMENT_ID NUMBER NOT NULL,
CONSTRAINT emp_job_fk FOREIGN KEY(JOB_ID) REFERENCES JOBS(JOB_ID),
CONSTRAINT emp_department_fk FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(DEPARTMENT_ID)
);
INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME)
VALUES(1,'IT');
INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME)
VALUES(2,'Sales');
INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (1,'IT Administrator',250000.00,50000.00);
INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (2,'Salesman',200000.00,40000.00);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (1,'Tony','Starc','starc#gmail.com','0123456789',TO_DATE('15/1/2008','DD/MM/YYYY'),1,45000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (2,'Bruce','Wayne','bruce#gmail.com','0123456788',TO_DATE('15/1/2009','DD/MM/YYYY'),1,40000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (3,'Larry','Ellison','larry#gmail.com','0123456787',TO_DATE('15/1/2010','DD/MM/YYYY'),1,30000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (4,'Steve','Jobs','steve#gmail.com','0123456786',TO_DATE('15/1/2011','DD/MM/YYYY'),2,35000.00,2);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (5,'Remy','Lebeau','remy#gmail.com','0123456785',TO_DATE('15/1/2012','DD/MM/YYYY'),2,30000.00,2);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (6,'Clark','Kent','clark#gmail.com','0123456784',TO_DATE('15/1/2013','DD/MM/YYYY'),2,35000.00,2);
Now in my assignment question, I have been asked to solve the following question:
Write a function called fn_emps_per_dept_jc450912 to retrieve EMPLOYEE_ID,FIRST_NAME,LAST_NAME AND JOB_TITLE with a given DEPARTMENT_ID. This function should have DEPARTMENT_ID as input parameter and this function should have EMPLOYEE_ID,FIRST_NAME,LAST_NAME AND JOB_TITLE as output parameters. It should return TRUE if found and FALSE if not found.
In order to display the information of employees from a particular department, I have written the following function:
CREATE OR REPLACE FUNCTION fn_emps_per_dept_jc450912 (f_dept_id IN NUMBER,f_emp_id OUT NUMBER,f_first_name OUT VARCHAR,f_last_name OUT VARCHAR,f_job_title OUT VARCHAR)
RETURN BOOLEAN
AS
BEGIN
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
INTO f_emp_id,f_first_name,f_last_name,f_job_title
FROM EMPLOYEES,JOBS,DEPARTMENT
WHERE DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
AND JOBS.JOB_ID = EMPLOYEES.JOB_ID
AND EMPLOYEES.DEPARTMENT_ID = f_dept_id;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE('Employee not found');
RETURN FALSE;
END fn_emps_per_dept_jc450912;
Function FN_EMPS_PER_DEPT_JC450912 compiled
As you can see from the above that the function has been successfully compiled.
Then I tried executing the function:
DECLARE
f_dept_id NUMBER;
f_emp_id NUMBER;
f_first_name VARCHAR(30) ;
f_last_name VARCHAR(30) ;
f_job_title VARCHAR(30);
f_return BOOLEAN;
BEGIN
f_dept_id := 1;
f_return := fn_emps_per_dept_jc450912(f_dept_id,f_emp_id,f_first_name,f_last_name,f_job_title);
DBMS_OUTPUT.PUT_LINE('Employee_ID: ' || f_emp_id);
DBMS_OUTPUT.PUT_LINE('First Name: ' || f_first_name);
DBMS_OUTPUT.PUT_LINE('Last Name: ' || f_last_name);
DBMS_OUTPUT.PUT_LINE('Job: ' || f_job_title);
END;
I'm getting the following error:
Error report -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYSTEM.FN_EMPS_PER_DEPT_JC450912", line 5
ORA-06512: at line 10
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
I need the solution code for the execution body to fix this error.
Firstly please use modern join syntax (ANSI standard since 92!).
So your SELECT should be:
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
INTO f_emp_id,f_first_name,f_last_name,f_job_title
FROM EMPLOYEES INNER JOIN JOBS ON JOBS.JOB_ID = EMPLOYEES.JOB_ID
INNER JOIN DEPARTMENT ON DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
WHERE EMPLOYEES.DEPARTMENT_ID = f_dept_id;
Next when you get a problem like this, you should just run the query in a query window, like this:
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
FROM EMPLOYEES INNER JOIN JOBS ON JOBS.JOB_ID = EMPLOYEES.JOB_ID
INNER JOIN DEPARTMENT ON DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
WHERE EMPLOYEES.DEPARTMENT_ID = 1;
This will reveal the cause of your problem as the output looks like this
EMPLOYEE_ID FIRST_NAME LAST_NAME JOB_TITLE
----------- -------------------- ------------------------- -----------------------------------
1 Tony Starc IT Administrator
2 Bruce Wayne IT Administrator
3 Larry Ellison IT Administrator
I.e the field employees.department_id is not unique. Therefore on execution the stored procedure is trying to put multiple values in a single variable. This it cannot do, hence the error. The procedure compiles ok, because at compile time, the procedure can have no idea that it will be passed a parameter which results in more than one record in the result set.

SQL Using an OBJECT as parameter for an ORDER mthod

I have a TYPE called Employee which has an ORDER method which takes an Employee as a parameter. I have created a table of Employee and inserted some data. I am trying to test this ORDER method using SELECT however i am having difficulty satisfying the parameter. here is my code
CREATE OR REPLACE TYPE Employee AS OBJECT(
EmpID VARCHAR(15),
eName VARCHAR(30),
ePhone NUMBER,
eAddress VARCHAR(15),
ePosition VARCHAR(15),
eHireDt DATE,
salary NUMBER,
ORDER MEMBER FUNCTION orderSalary (e Employee) RETURN NUMBER)
NOT FINAL;
/
CREATE OR REPLACE TYPE BODY Employee AS
ORDER MEMBER FUNCTION orderSalary(e Employee) return number IS
BEGIN
IF(self.salary > e.salary) then
return(1);
ELSIF (self.salary < e.salary) then
return(-1);
ELSE
return(0);
END IF;
END;
END;
/
CREATE TABLE Emp OF Employee (EmpID PRIMARY KEY)
OBJECT IDENTIFIER PRIMARY KEY;
insert into Emp values('001','kabir',6477732272,'Pharmacy','clerk','2016-03-28',2000);
Here is the line that is giving me trouble:
SELECT p.orderSalary(Employee s) FROM Emp p;
All i need to do is test this method to make sure it works, is there any way i can create an instance of Employee to use as a parameter, or perhaps take a row from the Emp table? Thanks!
SELECT p.orderSalary( VALUE( p ) ) FROM Emp p;
Or:
SELECT p.orderSalary( DEREF( REF( p ) ) ) FROM Emp p;
Or:
SET SERVEROUTPUT ON;
DECLARE
e1 EMPLOYEE := NEW EMPLOYEE('001','kabir',6477732272,'Pharmacy','clerk',DATE '2016-03-28',2000);
e2 EMPLOYEE := NEW EMPLOYEE('002','bob',1234567890,'Library','assistant',DATE '2016-03-07',1000);
BEGIN
DBMS_OUTPUT.PUT_LINE( e1.orderSalary( e2 ) );
END;
/
Update - Select different rows:
insert into Emp values('001','kabir',6477732272,'Pharmacy','clerk','2016-03-28',2000);
insert into Emp values('002','bob',1234567890,'Library','assistant',DATE '2016-03-07',1000);
SELECT e1.ename AS name1,
e2.ename AS name2,
e1.orderSalary( VALUE( e2 ) )
FROM Emp e1
CROSS JOIN Emp e2;
Outputs:
NAME1 NAME2 E1.ORDERSALARY(VALUE(E2))
------ ------ -------------------------
kabir kabir 0
kabir bob 1
bob kabir -1
bob bob 0

Find out what are all the columns having NULL values in the table for a given row in Oracle

For Example if the table is like below
ID FIRST_NAME LAST_NAME START_DAT END_DATE SALARY CITY DESCRIPTION
---- ---------- ---------- --------- --------- ---------- -------------------
01 Jason Martin 25-JUL-96 NULL 1234.56 NULL Programmer
02 Alison Mathews 21-MAR-76 21-FEB-86 6661.78 Vancouver Tester
For the record ID "1", END_DATE and CITY are having null values. How to get these values in a single query?
You can use case to figure out what has a NULL value and concatenate the results together:
select ((case when id is null then 'id;' end) ||
(case when first_name is null then 'firstname;' end) ||
. . .
(case when description is null then 'description;' end)
) as NullColumns
from table;
Note: Oracle treats NULL values as empty strings for the concatenation operator.
You can use this function:
create or replace function list_null_cols(i_table in varchar2,
i_filter in varchar2 default '') return varchar2 is
v_sql varchar2(32000);
cursor cols is
select column_name cn from user_tab_cols
where table_name = upper(i_table) and nullable='Y';
ret varchar2(32000);
begin
for c in cols loop
v_sql := v_sql || 'max(nvl2('||c.cn||',null,'''||c.cn||',''))||';
end loop;
if length(v_sql) = 0 then
return 'no columns found';
end if;
v_sql := 'select '||rtrim(v_sql, '|| ') ||' from '||i_table||' '||i_filter;
begin
execute immediate v_sql into ret;
exception when others then
return 'error: '||sqlerrm;
end;
return rtrim(ret, ',');
end;
First parameter is table name, second, optional is where... filter. If you omit second parameter all rows in table will be analyzed, like in examples:
create table test_table (ID varchar2(2), FIRST_NAME number, LAST_NAME number,
START_DATE number, END_DATE number, SALARY number, CITY number, DESCRIPTION number);
insert into test_table values ('01', 1, 1, 1, null, 1, 1, 1);
insert into test_table values ('02', 2, 2, 2, 2, 2, null, 2);
select list_null_cols('test_table') list from dual;
LIST
-------------------
END_DATE,CITY
select list_null_cols('test_table', ' where id=''01''') list from dual;
LIST
-------------------
END_DATE
select list_null_cols('test_table', ' where salary=2') list from dual;
LIST
-------------------
CITY