Home » SQL & PL/SQL » SQL & PL/SQL » using case when ..need suggestion (4.1.3 sql developer)
icon5.gif  using case when ..need suggestion [message #647830] Tue, 09 February 2016 17:17 Go to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

CREATE OR REPLACE PROCEDURE as1(annual_sal dept.salary%TYPE, bonus dept.salary%TYPE);

 BEGIN annual_sal := salary *12;

 CASE WHEN annual_sal>=20000 THEN bonus := salary+2000;

 WHEN annual_sal >=10000
AND <=19999 THEN bonus :=salary+1000;

 WHEN annual_sal <= 9999 THEN bonus :=salary+500;

 ELSE EXCEPTION WHEN CASE_NOT_FOUND THEN DBMS_OUTPUT.PUT_LINE('No increment');

 END CASE;

 END;


trying to use case when logic for creating bonus variable and updating salary based on annual salary and the department table dept has following variables.
Name Null Type
------ ---- ------------
JOB VARCHAR2(20)
JOBID VARCHAR2(20)
EMPID VARCHAR2(20)
SALARY NUMBER(21)

it shows error while compilation
Error(5,1): PLS-00103: Encountered the symbol "BEGIN"
Error(10,36): PLS-00103: Encountered the symbol "=" when expecting one of the following: ( - + case mod new not null <an identifier> <a double-quoted delimited-identifier> <a bind variable> continue avg count current exists max min prior sql stddev sum variance execute forall merge time timestamp interval date <a string literal with character set specification> <a number> <a single-quoted SQL string> pipe <an alternatively-quoted string literal with character set specification> <an alternatively
Error(13,5): PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following: ( begin case declare exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge
Error(16,7): PLS-00103: Encountered the symbol "CASE" when expecting one of the following: ; <an identifier> <a double-quoted delimited-identifier> current delete exists prior <a single-quoted SQL string>

[Updated on: Tue, 09 February 2016 17:39]

Report message to a moderator

Re: using case when ..need suggestion [message #647831 is a reply to message #647830] Tue, 09 February 2016 18:05 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
Your code has too many errors, staring with semi-colon at the end of parameter list instead of IS keyword, EXCEPTION block starting inside CASE statement, some undeclared user defined exceptions...

SY.
Re: using case when ..need suggestion [message #647832 is a reply to message #647831] Tue, 09 February 2016 18:08 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

ok let me check those mistakes will try again
Re: using case when ..need suggestion [message #647833 is a reply to message #647832] Tue, 09 February 2016 18:20 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
M123 wrote on Tue, 09 February 2016 16:08
ok let me check those mistakes will try again


Please consider the following approach to writing PL/SQL code.
NEVER write more than 3 new lines at any 1 time until you can consistently write error free code.
Re: using case when ..need suggestion [message #647835 is a reply to message #647830] Tue, 09 February 2016 18:37 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

declare
annual_sal number;
bonus number;
v_sal number;
begin
select salary into v_sal from dept;
annual_sal := v_sal *12;

  case when
    annual_sal>=20000 then bonus := v_sal+2000;
       when annual_sal >=10000 and <=19999  then  bonus :=v_sal+1000;
        when annual_sal <= 9999 then bonus :=v_sal+500;
        else
        dbms_output.put_line('no incmrent');
         end case;
   else
end;



I certainly know somewhere i am missing / logic in declaration and passing the value ? need to try again

error:
Error report -
ORA-06550: line 11, column 36:
PLS-00103: Encountered the symbol "=" when expecting one of the following:

( - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current exists max min prior sql stddev
sum variance execute forall merge time timestamp interval
date <a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set specification>
<an alternatively
ORA-06550: line 16, column 4:
PLS-00103: Encountered the symbol "ELSE" when expecting one of the following:

( begin case declare end exception exit for goto if loop mod
null pragma raise return select update while with
<an identifier> <a double-quoted delimi
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

[Updated on: Tue, 09 February 2016 18:56]

Report message to a moderator

Re: using case when ..need suggestion [message #647837 is a reply to message #647835] Tue, 09 February 2016 18:56 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
I suggest you start reading PL/SQL documentation. SELECT INTO statement MUST select one and only one row. Parameter annual_sal is declared as IN mode parameter - it ca't be assigned value. Keep working...

SY.
Re: using case when ..need suggestion [message #647838 is a reply to message #647837] Tue, 09 February 2016 19:00 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

not using paramter this time, trying to achieve through anonymous block
Re: using case when ..need suggestion [message #647841 is a reply to message #647838] Tue, 09 February 2016 22:32 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9090
Registered: November 2002
Location: California, USA
Senior Member
If you want to process each of the salaries, then try using a "cursor for loop". Please click on the link below for syntax, explanation, and examples.

http://docs.oracle.com/database/121/LNPLS/cursor_for_loop_statement.htm#LNPLS1143

especially the following example:

http://docs.oracle.com/database/121/LNPLS/static.htm#CHDBJBJE
Re: using case when ..need suggestion [message #647842 is a reply to message #647838] Tue, 09 February 2016 22:36 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9090
Registered: November 2002
Location: California, USA
Senior Member
If you want to process just one salary, then you need to add a where clause to your select statement that selects only one salary, such as for just one person. Your case statement also has some errors. Once again, it would help if you would explain what it is that you are trying to do, as it is impossible to tell from your attempted code.

Re: using case when ..need suggestion [message #647843 is a reply to message #647830] Tue, 09 February 2016 22:40 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9090
Registered: November 2002
Location: California, USA
Senior Member
From your first post in this thread:

trying to use case when logic for creating bonus variable and updating salary based on annual salary and the department table dept has following variables

then all you need is one SQL update statement that includes a case statement, no anonymous PL/SQL block and no PL/SQL stored procedure.
Re: using case when ..need suggestion [message #647853 is a reply to message #647843] Wed, 10 February 2016 03:39 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

declare
v_sal number;
annual_sal number;
bonus number;
begin
SELECT SALARY INTO v_sal from dept ;
annual_sal :=v_sal*12;
  case when
    annual_sal>=20000 then bonus := v_sal+2000;
       when annual_sal >=10000 and <=19999  then  bonus :=v_sal+1000;
        when annual_sal <= 9999 then bonus :=v_sal+500;
        else
        dbms_output.put_line('no incmrent');
         end case;
   else
end;


missing some logic here ? can someone suggest .
need to update salary based on annualsal, annual_sal and bonus are new variables.

Error report -
ORA-06550: line 10, column 36:
PLS-00103: Encountered the symbol "=" when expecting one of the following:

( - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current exists max min prior sql stddev
sum variance execute forall merge time timestamp interval
date <a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set specification>
<an alternatively
ORA-06550: line 15, column 4:
PLS-00103: Encountered the symbol "ELSE" when expecting one of the following:

( begin case declare end exception exit for goto if loop mod
null pragma raise return select update while with
<an identifier> <a double-quoted delimi

[Updated on: Wed, 10 February 2016 03:41]

Report message to a moderator

Re: using case when ..need suggestion [message #647855 is a reply to message #647853] Wed, 10 February 2016 03:46 Go to previous messageGo to next message
Littlefoot
Messages: 21807
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Should be something like this:
bonus := case when annual_sal >= 20000 then v_sal + 2000
              when ...
              else ...
         end;

Note that - when you fix syntax errors - the first SELECT SALARY ... statement is likely to produce TOO-MANY-ROWS if you don't restrict it with the WHERE clause (and, of course, if DEPT table contains more than a single record).
Re: using case when ..need suggestion [message #647856 is a reply to message #647855] Wed, 10 February 2016 03:52 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Every time you use a comparison operator (=, <=, >= etc) you need to actually have something to compare on each side of the operator.
You don't on line 10.
Re: using case when ..need suggestion [message #647857 is a reply to message #647856] Wed, 10 February 2016 04:01 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member


create or replace procedure p1(emp_id in varchar2)is
v_sal number;
annual_sal number;
bonus number;
begin
SELECT SALARY INTO v_sal from dept where empid=emp_id;
annual_sal :=v_sal*12;
  case when
    annual_sal>=20000 then bonus := v_sal+2000;
       when annual_sal >=10000 and annual_sal<=19999  then  bonus :=v_sal+1000;
        when annual_sal <= 9999 then bonus :=v_sal+500;
        dbms_output.put_line(bonus);
        else
        dbms_output.put_line('no incmrent');
         end case;
   
end;
/


comparison operator issue solved.but what should i do to apply this logic to all rows in a table ?

i used a procedure and executed like this:
execute p1(1) ;
here empid is 1, and in table it has salary of 2000

it shows plsql procedure completed successfully. but bonus is not displayed in end result ?????

[Updated on: Wed, 10 February 2016 04:19]

Report message to a moderator

Re: using case when ..need suggestion [message #647858 is a reply to message #647857] Wed, 10 February 2016 04:23 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
have you set serveroutput on?
Re: using case when ..need suggestion [message #647859 is a reply to message #647857] Wed, 10 February 2016 04:26 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
M123 wrote on Wed, 10 February 2016 10:01
but what should i do to apply this logic to all rows in a table ?


Do you want to update all the rows in the table or display the bonus for all rows along with some other information?
If update - write a single update that uses case to set the appropriate column.
If display - write a single select that has case logic in the select clause to calculate bonus.
Re: using case when ..need suggestion [message #647860 is a reply to message #647859] Wed, 10 February 2016 04:38 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

yes i want to update all rows

create or replace procedure p1(emp_id in varchar2)is
v_sal number;
annual_sal number;
bonus number;
begin
SELECT SALARY INTO v_sal from dept where empid=emp_id;
annual_sal :=v_sal*12;
update dept   
set
  case when
    annual_sal>=20000 then bonus := v_sal+2000;
       when annual_sal >=10000 and annual_sal<=19999  then  bonus :=v_sal+1000;
        when annual_sal <= 9999 then bonus :=v_sal+500;
        dbms_output.put_line(bonus);
        else
        dbms_output.put_line('no incmrent');
         end case;
   
end;
/

what i have to give in SET... ?
Re: using case when ..need suggestion [message #647861 is a reply to message #647860] Wed, 10 February 2016 05:38 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Look at Littlefoots example above.

And get rid of the select you don't need it - the update can access salary directly.
Re: using case when ..need suggestion [message #647864 is a reply to message #647861] Wed, 10 February 2016 06:57 Go to previous messageGo to next message
msol25
Messages: 396
Registered: June 2011
Senior Member
@M123

Please can you suggest why you stick on creating pl/sql for this requirement.

I hope you can resolve your query using sql script only.
Re: using case when ..need suggestion [message #647866 is a reply to message #647864] Wed, 10 February 2016 07:08 Go to previous messageGo to next message
Michel Cadot
Messages: 68643
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

If you read M123 previous posts you see he is learning PL/SQL.
And once again, you point to something that has already been said:

Barbara Boehmer wrote on Wed, 10 February 2016 05:40
...
then all you need is one SQL update statement that includes a case statement, no anonymous PL/SQL block and no PL/SQL stored procedure.


Re: using case when ..need suggestion [message #647869 is a reply to message #647866] Wed, 10 February 2016 07:13 Go to previous messageGo to next message
msol25
Messages: 396
Registered: June 2011
Senior Member
Dear Michel,

He is learning Pl/sql.I hope this one is good and first he should refer good pl/sql book.

Simply writing anything is not the way to learn pl/sql. You should know when we need to write pl/sql or when we need to write sql.

As per my knowledge,He should refer one good book to learn basics.Please find below mentioned url for the same:

https://docs.oracle.com/cd/B28359_01/appdev.111/b28370.pdf

Re: using case when ..need suggestion [message #647871 is a reply to message #647869] Wed, 10 February 2016 07:19 Go to previous messageGo to next message
Michel Cadot
Messages: 68643
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

I already pointed him many times to Oracle documentation, and also to those that refer to the version he is using not a previous one as you do.
But I will add it once more then you can also see it:
PL/SQL User's Guide and Reference
Database 2 Day Developer's Guide
Database Advanced Application Developer's Guide


Re: using case when ..need suggestion [message #647873 is a reply to message #647871] Wed, 10 February 2016 09:08 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

Thankyou Smile
Re: using case when ..need suggestion [message #647885 is a reply to message #647873] Wed, 10 February 2016 16:30 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9090
Registered: November 2002
Location: California, USA
Senior Member
One of the most important things that you need to do when posting a question here is explain what you are trying to accomplish. It appears that you want to update the salary for all rows of your dept table based on some bonus formula that is dependent upon the annual salary (salary * 12). If this is what you want to do, then you do not need a pl/sql procedure or a pl/sql block or any parameters. All you need is a sql update statement containing a case statement. If this is what you want to do, then you should focus on just a sql update statement containing a case statement and stop posting procedures and pl/sql blocks. If this is not what you want, then you should explain what you do want. Please see the following example that updates the sal column of the emp table using your bonus formula for all rows in the table. I have shown the values before and after the update. I have intentionally left part of the code blank. You need to figure out what goes in the blanks marked by three dots.

-- data before update:
SCOTT@orcl> select empno, ename, sal, sal*12 annual_sal from emp order by sal desc
  2  /

     EMPNO ENAME             SAL ANNUAL_SAL
---------- ---------- ---------- ----------
      7839 KING             5000      60000
      7902 FORD             3000      36000
      7788 SCOTT            3000      36000
      7566 JONES            2975      35700
      7698 BLAKE            2850      34200
      7782 CLARK            2450      29400
      7499 ALLEN            1600      19200
      7844 TURNER           1500      18000
      7934 MILLER           1300      15600
      7521 WARD             1250      15000
      7654 MARTIN           1250      15000
      7876 ADAMS            1100      13200
      7900 JAMES             950      11400
      7369 SMITH             800       9600

14 rows selected.


-- SQL update statement with some of the code replaced by ...:
SCOTT@orcl> update emp
  2  set    sal =
  3  	    case when ... then ...
  4  		 when ... then ...
  5  		 when ... then ...
  6  		 else ...
  7  	    end
  8  /

14 rows updated.


-- data after update:
SCOTT@orcl> select empno, ename, sal from emp order by sal desc
  2  /

     EMPNO ENAME             SAL
---------- ---------- ----------
      7839 KING             7000
      7902 FORD             5000
      7788 SCOTT            5000
      7566 JONES            4975
      7698 BLAKE            4850
      7782 CLARK            4450
      7499 ALLEN            2600
      7844 TURNER           2500
      7934 MILLER           2300
      7521 WARD             2250
      7654 MARTIN           2250
      7876 ADAMS            2100
      7900 JAMES            1950
      7369 SMITH            1300

14 rows selected.

Re: using case when ..need suggestion [message #647886 is a reply to message #647885] Wed, 10 February 2016 16:49 Go to previous messageGo to next message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

Hello Barbara,

Thank you for your detailed explanation ,previously my intention was to use a procedure or cursor to achieve the result ,i know every time we have to check the efficient way of programming or writing statements and the below one i tried with some others help

SELECT CASE WHEN salary*12 >=20000 THEN salary+2000
WHEN salary*12 >=10000 AND salary*12 <=19999 THEN salary+1000
END
FROM dept;


Smile

Re: using case when ..need suggestion [message #647887 is a reply to message #647886] Wed, 10 February 2016 17:21 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9090
Registered: November 2002
Location: California, USA
Senior Member
That will select and display the desired values, but will not update anything. You need to use an update statement if you want to permanently change the salary values in the dept table.
Re: using case when ..need suggestion [message #647888 is a reply to message #647887] Wed, 10 February 2016 17:23 Go to previous message
M123
Messages: 47
Registered: February 2016
Location: USA
Member

ok thankyou
Previous Topic: Not Exists vs Left Outer Join with NULL
Next Topic: Materialised view refresh on commit
Goto Forum:
  


Current Time: Tue Apr 23 22:40:23 CDT 2024