Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Steven.

Asked: July 10, 2001 - 10:11 am UTC

Last updated: July 25, 2002 - 10:24 am UTC

Version: 8.1.6

Viewed 1000+ times

You Asked

Dear Tom,
I am having a BIG problem with PL/SQL static SQL versus (pure) SQL.
I need to use the SQL CASE Expression and PL/SQL keeps choking on it:
LINE/COL ERROR
-------- -----------------------------------------------------------------
16/6 PLS-00103: Encountered the symbol "CASE" when expecting one of
the following:
( ) - + mod not null others <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
table avg count current exists max min prior sql stddev sum
variance execute multiset the both leading trailing forall
time timestamp interval date
<a string literal with character set specification>
<a number> <a single-quoted SQL string>

The same SELECT statement works just fine if I run it directly via SQL*Plus. I need it in a PL/SQL Stored-Procedure.
I know that I could use Dynamic SQL, but that would "open a whole other can of worms". I want to keep it static for %ROWTYPE etc.

Thanks,
Steven

and Tom said...

Your choices in 8i are:

o create a view that "hides" the case from PLSQL
o use dynamic sql

the PLSQL sql parser quite simply does not understand certain constructs like

o order by in a subquery
o CASE
o group by rollup | cube
o select ( select ... ) from t;
o TO_LOB()

In 9i, the PLSQL and database engine share a common parser meaning that as feaures are added to SQL, they'll instantly be avaialble in PLSQL.


You can use dynamic sql and use a %ROWTYPE using a "template" cursor. Consider:

ops$tkyte@ORA817.US.ORACLE.COM> declare
2 type rc is ref cursor;
3
4 cursor TEMPLATE is select ename, empno, rpad( '*', 30, '*' ) case_exp from emp;
5
6 l_rec TEMPLATE%rowtype;
7
8 l_cursor rc;
9
10 l_job varchar2(25) default 'CLERK';
11 begin
12 open l_cursor for
13 'select ename, empno, case when sal between 0 and 500 then ''LOW''
14 when sal between 501 and 1000 then ''MED''
15 else ''HIGH''
16 end
17 from emp
18 where job = :x'
19 using l_job;
20
21 loop
22 fetch l_cursor into l_rec;
23 exit when l_cursor%notfound;
24 dbms_output.put_line( l_rec.case_exp );
25 end loop;
26
27 close l_cursor;
28 end;
29 /
MED
HIGH
MED
HIGH

PL/SQL procedure successfully completed.


you just need to make a static cursor (no WHERE clause is ever needed) that selects representative columns.


followup to comment one

No -- the reason is simple.

In PLSQL, using the following block of code:

declare
l_ename varchar2(5) default '%A%';
begin
for x in ( select * from emp where ename like l_ename and sal > 55 )
loop
.....


the SQL submited will be:

SELECT * FROM EMP WHERE ENAME LIKE :b0 AND SAL > 55


PLSQL leaves constants along and just finds its variables and binds them. In SQLPLUS you would query:


select * from emp where ename like '%A%' and sal > 55;


Now, in sqlplus, if you want that to be "bound" for you -- in 816 and up you can:


SQL> alter session set cursor_sharing=force;
SQL> select * from emp where ename like '%A%' and sal > 55;

Now what gets executed is

select * from emp where ename like :sys_bv_0 and sal > :sys_bv_1

using this "autobind" feature, you have have applications that do not bind (bad application) and environments like SQLPlus use bind variables for you.


Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

common parser

A reader, July 10, 2001 - 4:58 pm UTC

I'm under the impression that In PLSQL -- when you use STATIC SQL -- everything is bound for you already. Now, since both SQl and PL/SQL uses the same parser does it mean that all our SQL statements (From SQL*PLUS) will be binded too?

template cursors

A reader, May 13, 2002 - 12:39 pm UTC

I like that, mostly because I came up with that a few months ago for the exact same reason and just stumbled upon your solution while looking at other related topics.

This site is great!

SQL Books

A reader, July 25, 2002 - 5:54 am UTC

Hi Tom,
Can u pls suggest any book for sql just sql, i mean which says these are the ways u can write a query etc.
simple but very descriptive book on sql

Thanks


Tom Kyte
July 25, 2002 - 6:58 am UTC

Have you read the SQL reference manual? It is free

Joe Celko has a good "sql for dummies" book as well. search amazon.com for it.

dummie, smartie..whatever

Robert, July 25, 2002 - 9:44 am UTC

>>Joe Celko has a good "sql for dummies" book as well. >>search amazon.com for it.

Guess I got myself a wrong book...mine says "SQL for Smarties" ;)

RE: Guess I got myself a wrong book

A reader, July 25, 2002 - 10:24 am UTC

In regard to "Guess I got myself a wrong book", perhaps you should invest in a book on grammar instead?

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library