plsql error invalid number - sql

I'm getting an invalid number error when
procedure Afficher(opt int,id int) is
type emp is record(fn employees.first_name%type,
lname employees.last_name%type,
job jobs.job_title%type,
dep departments.department_id%type);
emp1 emp;
begin
select e1.first_name,e1.last_name,j.job_title,d.department_name into emp1
from employees e1 ,jobs j,departments d where e1.employee_id= 'id' and
e1.job_id=j.job_id and e1.department_id =d.department_id ;
dbms_output.put_line('Name Job Department');
dbms_output.put_line(emp1.fn||''|| emp1.lname||' '
||emp1.job||' '||emp1.dep);
end Afficher;

You're looking for e1.employee_id='id'; is it actually a string, or a number?

You probably want:
procedure Afficher(opt int,id int) is
type emp is record(fn employees.first_name%type,
lname employees.last_name%type,
job jobs.job_title%type,
dep departments.department_id%type);
emp1 emp;
begin
select e1.first_name,e1.last_name,j.job_title,d.department_name into emp1
from employees e1 ,jobs j,departments d where e1.employee_id= id and
e1.job_id=j.job_id and e1.department_id =d.department_id ;
dbms_output.put_line('Name Job Department');
dbms_output.put_line(emp1.fn||''|| emp1.lname||' '
||emp1.job||' '||emp1.dep);
end Afficher;
I.e. no quotes around the id variable.
It's probably better to rename the variable to *emp_id* or something similar.

Related

How to start procedure in oracle?

So I have this SELECT statement:
SELECT emp.emp_name, pos_emp.POSITION_NAME
from EMPLOYEE emp
join POSITION_EMPLOYEE pos_emp
on emp.POSITION_EMPLOYEE_POSITION_ID=pos_emp.POSITION_ID
where emp.EMP_NAME='&employee_name';
When I enter employee name from keyboard it returns me his name(from EMPLOYEE table) and position(from POSITION_EMPLOYEE table). But I want to do this with stored procedure:
create or replace PROCEDURE emp_pos( EMPLOYEE_NAME IN EMPLOYEE.EMP_NAME%TYPE,
POSITION_NAME OUT POSITION_EMPLOYEE.POSITION_NAME%TYPE )
AS
BEGIN
SELECT pos_emp.POSITION_NAME
INTO
POSITION_NAME
FROM EMPLOYEE emp
JOIN
POSITION_EMPLOYEE pos_emp
ON
emp.POSITION_EMPLOYEE_POSITION_ID
= pos_emp.POSITION_ID
WHERE emp.EMP_NAME
= EMPLOYEE_NAME
;
END;
I am trying to start the procedure with begin:
begin emp_pos('&employee_name');
end;
The compiler gives me error:wrong number or types of arguments in call to 'EMP_POS'. Where am I wrong?
SQL>set serveroutput on;
SQL> create or replace PROCEDURE emp_pos( EMPLOYEE_NAME IN EMPLOYEE.EMP_NAME%TYPE,
POSITION_NAME OUT POSITION_EMPLOYEE.POSITION_NAME%TYPE )
AS
BEGIN
SELECT pos_emp.POSITION_NAME
INTO
POSITION_NAME
FROM EMPLOYEE emp
JOIN
POSITION_EMPLOYEE pos_emp
ON
emp.POSITION_EMPLOYEE_POSITION_ID
= pos_emp.POSITION_ID
WHERE emp.EMP_NAME
= EMPLOYEE_NAME
;
dbms_output.put_line(EMPLOYEE_NAME||'''s position is : '||POSITION_NAME);
END;
after defining this procedure, you may use in this way :
SQL>var v_emp_pos varchar2;
SQL>exec emp_pos('&employee_name',:v_emp_pos);
SQL>print v_emp_pos; -- just to print out this "out" parameter.

Error when creating cursor in Oracle

I have a very simple script to try the cursor function but it reported invalid CREATE COMMAND. Anyone know what could be the cause? Thank you!
create lot_1 cursor for select * from temp_minj1.lot
In Oracle, the SQL syntax is thus :
DECLARE
my_emp_id NUMBER(6); -- variable for employee_id
my_job_id VARCHAR2(10); -- variable for job_id
my_sal NUMBER(8,2); -- variable for salary
CURSOR c1 IS SELECT employee_id, job_id, salary FROM employees
WHERE salary > 2000;
my_dept departments%ROWTYPE; -- variable for departments row
CURSOR c2 RETURN departments%ROWTYPE IS
SELECT * FROM departments WHERE department_id = 110;
see source

Update employees table

Guys I have the following problem:
Increase salary 15% for employees whose salary is less than 50% of their manager's salary.
Write PL/SQL procedure using cursor, loop and update.
Procedure header
Create or replace procedure inc_salary is:
. Exception if their salary after increase is more than 50% of their manager's salary.
Actually, we can do it directly like this:
update emp e
set e.salary+=e.salary*0.15
where e.salary<(select e.mgr from emp e, group by e.mgr)
Here is a picture of this table:
But I don't understand how to use the procedure. If I declare it like this, create or replace procedure inc_salary, then what should be its parameters? We can use of course loop, like
declare
for r in (select * from emp e) loop
update emp e
set r.salary+=r.salary*0.15;
where r.salary<r.mgr
exception
if r.salary >r.mgr*1.15 then
dbms.output_putline(' it can't increase');
end loop;
end;
But how to combine it together?
Why would you need a PL/SQL procedure? A simple query would do this job!
UPDATE emp
SET salary = salary * 1.15
WHERE empno IN (
SELECT e.empno
FROM emp e
JOIN emp m ON e.mgr = m.empno
WHERE e.salary < m.salary * 0.5
)
That's it!
But, if at all you need to use a procedure, you have to decide for yourself what exactly you want to do with it.
Every procedure has a set of formal parameters, which can even be an empty set. It is you who decides what to pass to a procedure. Consult your manager or architect for these situations.
declare
prec number;
procedure inc_salary(prcin number)
is
cursor cl is * from employees;
msal number(8,2);
mid number(6);
begin
for r in cl loop
mid := nvl(r.manager_id, r.employee_id);
select salary into msal from employees where employee_id = mid;
if r.salary < (msal * 0.5) then
update employees set
salary = salary * prc
where employee_id = r.employee_id;
end if;
end loop;
end inc_salary;
begin
prec := 1.5;
inc_salary(prec);
end ;

Return every employees department name

Write function returning every employee's department name.
Write a block printing all the employees name and department name in 20 dept.
Function header:
Create or replace function empdnm (empno number) return varchar2 is
Try to write exception if there is no such empno.
I have tried the following code, but it shows me some errors, namely
SQL statment ignored and missing expression. What is the problem?
create or replace function empdnm (empno1 number) return varchar2 is
deptname varchar (30);
BEGIN
Select into deptname(select d.dname from dept d
join emp e on e.deptno=d.deptno
Where e.empno= empno1
)
exception
WHEN no_data_found THEN
dbms_output.put_line('no employee with no:'|| empno1);
return(deptname);
end;
BEGIN
FOR r IN (SELECT * FROM emp where dept_id = 20) loop
dbms_output.put_line( 'employee '|| r.emp_name || ' is in department '|| empdnm(empno1) );
END loop;
end;
Try like this:
create or replace function empdnm (empno1 number) return varchar2 is
deptname varchar (30);
BEGIN
SELECT d.dname
INTO deptname
FROM dept d
JOIN emp e on e.deptno = d.deptno
WHERE e.empno = empno1;
return(deptname);
exception
WHEN no_data_found THEN
dbms_output.put_line('no employee with no:'|| empno1);
end;
Use below one :
create or replace function empdnm (empno1 number) return varchar2 is
deptname varchar (30);
BEGIN
SELECT d.dname
INTO deptname
FROM dept d
JOIN emp e on e.deptno = d.deptno
WHERE e.empno = empno1;
return(deptname);
exception
WHEN no_data_found THEN
dbms_output.put_line('no employee with no:'|| empno1);
end;
BEGIN
FOR r IN (SELECT * FROM emp where dept_id = 20) loop
dbms_output.put_line( 'employee '|| r.emp_name || ' is in department '|| empdnm(r.empno1) );
END loop;
end;

PL/SQL how to write multiple statement in a single stored procedure

I need to do the following problem,
Write a procedure that decreases the salary by a 10% for all employees who earn
less than the current average salary.
Treat the content of table EMP as “all employees”. Have your procedure print the name and salary of the first
person whose salary is just below the average.
What should be the approach to solve the problem?
Write a procedure that decreases the salary by a 10% for all employees who earn less than the current average salary.
CREATE OR REPLACE PROCEDURE UPDATE_EMP IS
BEGIN
UPDATE EMP
SET SAL= SAL-(SAL*0.1)
WHERE SAL<(SELECT AVG(SAL) FROM EMP);
END;
AND THE OTHER ONE :
Have your procedure print the name and salary of the first person whose salary is just below the average.
SELECT e.ename
, e.sal
from
(select ename
, sal
from emp
where sal < (select avg(sal)
from emp
)
order by sal desc
)e
where ROWNUM =1;
Now I need to connect both.. How could I do that ...
It sounds like you are a bit fuzzy on what a stored procedure is and how it can help you do complicated tasks involving many SQL statements.
You follow these directions on how a construct a stored procedure.
http://www.devshed.com/c/a/Oracle/Oracle-Stored-Procedures/
Stored procedures are wonderful structures that allow you to put multiple SQL statements into one structure, saving out variables for use in the next SQL statement. So all you have to do is invoke the stored procedure, and all the sql statements are run, and your answer is returned or table modification is committed.
You need something like this:
CREATE OR REPLACE PROCEDURE UPDATE_EMP RETURN name, value IS
BEGIN
UPDATE EMP
SET SAL= SAL-(SAL*0.1)
WHERE SAL<(SELECT AVG(SAL) FROM EMP);
SELECT e.ename INTO name_to_return, e.sal INTO sal_to_return from
(select ename, sal from emp where sal < (select
avg(sal)from emp) order by sal desc)e where ROWNUM =1;
RETURN name_to_return, sal_to_return;
END;
The syntax may be a bit off, when you get it working, post your answer here as a new answer, and check mark it as the answer, and you are much more likely to get help like this in the future.
CREATE OR REPLACE PROCEDURE DISPLAY_EMP IS
IS
CURSOR emp_cur
IS
SELECT ename
,sal
FROM emp
WHERE SAL<( SELECT AVG(SAL) FROM EMP)
ORDER BY sal desc;
v_emp_row emp_cur%ROWTYPE;
BEGIN
--update all the employee having sal less than avg sal
UPDATE EMP
SET SAL= SAL-(SAL*0.1)
WHERE SAL<(SELECT AVG(SAL) FROM EMP);
--display all the employee having sal less than avg sal
OPEN emp_cur ;
LOOP
FETCH emp_cur INTO v_emp_row;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('EMPLOYEE NAME : '||v_emp_row.ename||' '
||'SALARY : '||v_emp_row.sal);
END LOOP;
CLOSE emp_cur;
END DISPLAY_EMP;
--call the display_emp proc to display all the emp
BEGIN
DISPLAY_EMP ;
END;
You need one procedure to do the update, and another function or select statement to print the name and salary of the first person whose salary is just below the average.
CREATE OR REPLACE PROCEDURE DISPLAY_EMP IS
IS
CURSOR emp_cur
IS
SELECT ename
,sal
FROM emp
WHERE SAL<( SELECT AVG(SAL) FROM EMP)
ORDER BY sal desc;
v_emp_row emp_cur%ROWTYPE;
BEGIN
--update all the employee having sal less than avg sal
UPDATE EMP
SET SAL= SAL-(SAL*0.1)
WHERE SAL<(SELECT AVG(SAL) FROM EMP);
--display all the employee having sal less than avg sal
OPEN emp_cur ;
LOOP
FETCH emp_cur INTO v_emp_row;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('EMPLOYEE NAME : '||v_emp_row.ename||' '
||'SALARY : '||v_emp_row.sal);
END LOOP;
CLOSE emp_cur;
END DISPLAY_EMP;
--call the display_emp proc to display all the emp
BEGIN
DISPLAY_EMP ;
END;