<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: CASE gotcha in Oracle 8i</title>
	<atom:link href="http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/feed/" rel="self" type="application/rss+xml" />
	<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/</link>
	<description>News, views, tips and tricks on Oracle and other fun stuff</description>
	<pubDate>Thu, 07 Aug 2008 23:52:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
		<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-52025</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Mon, 10 Mar 2008 17:49:13 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-52025</guid>
		<description>@santhosh: You can try something like the following, or use  &lt;a href="http://www.oracle.com/pls/db102/print_hit_summary?search_string=dbms_sql" rel="nofollow"&gt;dbms_sql&lt;/a&gt;.

&lt;pre&gt;
DECLARE
  l_my_cursor   sys_refcursor;
  l_stmt_str    VARCHAR2(32767);
  l_var         NUMBER;
BEGIN
  l_stmt_str := 
  'SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual
   UNION
   SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual';
  OPEN l_my_cursor FOR l_stmt_str; 
    LOOP
      FETCH l_my_cursor 
        INTO l_var; 
       EXIT WHEN l_my_cursor%NOTFOUND;
      dbms_output.put_line('l_var='&#124;&#124;to_char(l_var));
    END LOOP; 
  CLOSE l_my_cursor;
END;  
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>@santhosh: You can try something like the following, or use  <a href="http://www.oracle.com/pls/db102/print_hit_summary?search_string=dbms_sql" rel="nofollow">dbms_sql</a>.</p>
<pre>
DECLARE
  l_my_cursor   sys_refcursor;
  l_stmt_str    VARCHAR2(32767);
  l_var         NUMBER;
BEGIN
  l_stmt_str :=
  'SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual
   UNION
   SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual';
  OPEN l_my_cursor FOR l_stmt_str;
    LOOP
      FETCH l_my_cursor
        INTO l_var;
       EXIT WHEN l_my_cursor%NOTFOUND;
      dbms_output.put_line('l_var='||to_char(l_var));
    END LOOP;
  CLOSE l_my_cursor;
END;
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: santhosh</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-52023</link>
		<dc:creator>santhosh</dc:creator>
		<pubDate>Mon, 10 Mar 2008 12:14:52 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-52023</guid>
		<description>apps@dev1&#62; declare
  2      l_var number;
  3      sql_string varchar2(100);
  4  begin
  5      sql_string := 'select case when 1=1 then 1 else 2 end ' &#124;&#124;
  6          'from dual';
  7      execute immediate sql_string into l_var;
  8      dbms_output.put_line('l_var='&#124;&#124;to_char(l_var));
  9  end;
 10  /
l_var=1

The above is applicable, when the sql returns only one value (1 row, 1 column)

How do I implement the same using curser,
ie, if the sql statement returns a tabular data (M rows, N columns:: where M &#38; N &#62;2)?</description>
		<content:encoded><![CDATA[<p>apps@dev1&gt; declare<br />
  2      l_var number;<br />
  3      sql_string varchar2(100);<br />
  4  begin<br />
  5      sql_string := &#8217;select case when 1=1 then 1 else 2 end &#8216; ||<br />
  6          &#8216;from dual&#8217;;<br />
  7      execute immediate sql_string into l_var;<br />
  8      dbms_output.put_line(&#8217;l_var=&#8217;||to_char(l_var));<br />
  9  end;<br />
 10  /<br />
l_var=1</p>
<p>The above is applicable, when the sql returns only one value (1 row, 1 column)</p>
<p>How do I implement the same using curser,<br />
ie, if the sql statement returns a tabular data (M rows, N columns:: where M &amp; N &gt;2)?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oracle Functions</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-50461</link>
		<dc:creator>Oracle Functions</dc:creator>
		<pubDate>Sat, 31 Mar 2007 07:11:24 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-50461</guid>
		<description>&lt;p&gt;Excuse me, i don't understand...
How i can you DECODE functions?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Excuse me, i don&#8217;t understand&#8230;<br />
How i can you DECODE functions?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-14650</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Sat, 03 Jun 2006 04:34:43 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-14650</guid>
		<description>&lt;p&gt;Steve, 
Your SQL syntax does not look correct. However, I tried the following in 10gXE:&lt;/p&gt;

&lt;pre&gt;
SELECT (CASE
           WHEN 1 = 1
              THEN CURSOR (SELECT 1
                             FROM DUAL)
           WHEN 1 = 2
              THEN CURSOR (SELECT 1
                             FROM DUAL)
           ELSE NULL
        END
       ) x
  FROM DUAL
/
&lt;/pre&gt;

&lt;p&gt;It returned an error:
ORA-22902: CURSOR expression not allowed 
Cause: CURSOR on a subquery is allowed only in the top-level SELECT list of a query.&lt;/p&gt;

&lt;p&gt;That means you cannot use cursor expressions in a CASE or even DECODE.&lt;/p&gt;

&lt;p&gt;Another solution may be the use of Dynamic SQL.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Steve,<br />
Your SQL syntax does not look correct. However, I tried the following in 10gXE:</p>
<pre>
SELECT (CASE
           WHEN 1 = 1
              THEN CURSOR (SELECT 1
                             FROM DUAL)
           WHEN 1 = 2
              THEN CURSOR (SELECT 1
                             FROM DUAL)
           ELSE NULL
        END
       ) x
  FROM DUAL
/
</pre>
<p>It returned an error:<br />
ORA-22902: CURSOR expression not allowed<br />
Cause: CURSOR on a subquery is allowed only in the top-level SELECT list of a query.</p>
<p>That means you cannot use cursor expressions in a CASE or even DECODE.</p>
<p>Another solution may be the use of Dynamic SQL.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: STEVE</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-13233</link>
		<dc:creator>STEVE</dc:creator>
		<pubDate>Tue, 30 May 2006 23:18:22 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-13233</guid>
		<description>&lt;p&gt;so how would you code something that returns a cursor nested in a table based on a case statment in 9i?&lt;/p&gt;

&lt;p&gt;select *,
(case 
when tb1.item=100 then
cursor(select * from tb2 where id=5 from mytable2 tb2)
when tb2.item=200 then
cursor(select * from tb3 where id=6 from mytable3 tb3)
else null
end ) curval
from mytable1&lt;/p&gt;

&lt;p&gt;or would you have to used "decode"&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>so how would you code something that returns a cursor nested in a table based on a case statment in 9i?</p>
<p>select *,<br />
(case<br />
when tb1.item=100 then<br />
cursor(select * from tb2 where id=5 from mytable2 tb2)<br />
when tb2.item=200 then<br />
cursor(select * from tb3 where id=6 from mytable3 tb3)<br />
else null<br />
end ) curval<br />
from mytable1</p>
<p>or would you have to used &#8220;decode&#8221;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-1243</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Mon, 23 Jan 2006 23:44:36 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-1243</guid>
		<description>&lt;p&gt;SaSantos, what do you mean by "heavy"? Have you measured the performance of your query and found it to be slow? Have you run your query through an explain plan? a tkprof?&lt;/p&gt;

&lt;p&gt;I suggest you post your question on forums.oracle.com. I also suggest you read:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://oraclesponge.blogspot.com/2005/04/writing-good-sql.html" rel="nofollow"&gt;http://oraclesponge.blogspot.com/2005/04/writing-good-sql.html&lt;/a&gt;&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>SaSantos, what do you mean by &#8220;heavy&#8221;? Have you measured the performance of your query and found it to be slow? Have you run your query through an explain plan? a tkprof?</p>
<p>I suggest you post your question on forums.oracle.com. I also suggest you read:</p>
<p><a href="http://oraclesponge.blogspot.com/2005/04/writing-good-sql.html" rel="nofollow">http://oraclesponge.blogspot.com/2005/04/writing-good-sql.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SaSantos</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-1241</link>
		<dc:creator>SaSantos</dc:creator>
		<pubDate>Mon, 23 Jan 2006 21:42:00 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-1241</guid>
		<description>&lt;p&gt;Eddie,
the ideal would be to only run the first OR if there weren't any rows returned for the "first conditions":
   (to_char(Adate, 'YYYYMMDD') = to_char(I_date, 'YYYYMMDD')
   and "more_conditions")&lt;/p&gt;

&lt;p&gt;And run the second OR if the:
(to_char(Adate, 'YYYYMM') = to_char(I_date, 'YYYYMM')
and "more_conditions")
DidnÂ´t returned rows.&lt;/p&gt;

&lt;p&gt;But with the OR's or with the UNION's the query is to "heavy".
Thats why the ideal would be run the query (based on three small queries) from the start to end, and "stop" at the first that returned rows.
I don't know if thats possible. Besides the optional solution I refered before.&lt;/p&gt;

&lt;p&gt;TIA,
SaSantos&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Eddie,<br />
the ideal would be to only run the first OR if there weren&#8217;t any rows returned for the &#8220;first conditions&#8221;:<br />
   (to_char(Adate, &#8216;YYYYMMDD&#8217;) = to_char(I_date, &#8216;YYYYMMDD&#8217;)<br />
   and &#8220;more_conditions&#8221;)</p>
<p>And run the second OR if the:<br />
(to_char(Adate, &#8216;YYYYMM&#8217;) = to_char(I_date, &#8216;YYYYMM&#8217;)<br />
and &#8220;more_conditions&#8221;)<br />
DidnÂ´t returned rows.</p>
<p>But with the OR&#8217;s or with the UNION&#8217;s the query is to &#8220;heavy&#8221;.<br />
Thats why the ideal would be run the query (based on three small queries) from the start to end, and &#8220;stop&#8221; at the first that returned rows.<br />
I don&#8217;t know if thats possible. Besides the optional solution I refered before.</p>
<p>TIA,<br />
SaSantos</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-1233</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Mon, 23 Jan 2006 02:33:18 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-1233</guid>
		<description>&lt;p&gt;SASantos, it looks like you are selecting the same fields from the same table in all three queries, So, why don't you use one query like this:&lt;/p&gt;

&lt;p&gt;select "fields"
from table
where 
(to_char(Adate, 'YYYYMMDD') = to_char(I_date, 'YYYYMMDD')
and "more_conditions") 
OR
(to_char(Adate, 'YYYYMM') = to_char(I_date, 'YYYYMM')
and "more_conditions")
OR
(to_char(Adate, 'YYYY') = to_char(I_date, 'YYYY')
and "more_conditions")&lt;/p&gt;

&lt;p&gt;Moreover, if Adate and I_date are of a date datatype, why converting to to_char? you can just use TRUNC.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>SASantos, it looks like you are selecting the same fields from the same table in all three queries, So, why don&#8217;t you use one query like this:</p>
<p>select &#8220;fields&#8221;<br />
from table<br />
where<br />
(to_char(Adate, &#8216;YYYYMMDD&#8217;) = to_char(I_date, &#8216;YYYYMMDD&#8217;)<br />
and &#8220;more_conditions&#8221;)<br />
OR<br />
(to_char(Adate, &#8216;YYYYMM&#8217;) = to_char(I_date, &#8216;YYYYMM&#8217;)<br />
and &#8220;more_conditions&#8221;)<br />
OR<br />
(to_char(Adate, &#8216;YYYY&#8217;) = to_char(I_date, &#8216;YYYY&#8217;)<br />
and &#8220;more_conditions&#8221;)</p>
<p>Moreover, if Adate and I_date are of a date datatype, why converting to to_char? you can just use TRUNC.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: "Hierarchy" cursor query</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-1226</link>
		<dc:creator>"Hierarchy" cursor query</dc:creator>
		<pubDate>Sat, 21 Jan 2006 14:39:11 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-1226</guid>
		<description>&lt;p&gt;Hi!
I'm using Oracle's version 8.1.7. 
There's a cursor query in a PL/SQL package like the following one:&lt;/p&gt;

&lt;p&gt;select "fields",
            1 qry_condition
  from table
where to_char(Adate, 'YYYYMMDD') = to_char(I_date, 'YYYYMMDD')
    and "more_conditions"
union all
select "fields",
            2 qry_condition
  from table
where to_char(Adate, 'YYYYMM') = to_char(I_date, 'YYYYMM')
    and "more_conditions"
union all
select "fields",
            3 qry_condition
  from table
where to_char(Adate, 'YYYY') = to_char(I_date, 'YYYY')
    and "more_conditions"
order by "2" -- qry_condition;&lt;/p&gt;

&lt;p&gt;The idea is to execute (only) the first query if results are returned, execute the next query if the first doesn't returned rows, and execute the third query if none of the previous two return data. 
But as we can conclude, everytime this cursor is executed it runs
all of the three queries that belong to it, which is impacting negatively the cursor perfomance.&lt;/p&gt;

&lt;p&gt;One possible solution would be to divide it in three querys and use,
something like this:&lt;/p&gt;

&lt;p&gt;open cursor1(L_date);
fetch cursor1 into ...
if cursor1.notfound 
then
   open cursor2(L_date);
   fetch cursor2 into ...
   if cursor2.notfound 
   then
      open cursor3(L_date);
      fetch cursor3 into ...
      if cursor3.notfound then
      (...)&lt;/p&gt;

&lt;p&gt;end if;&lt;/p&gt;

&lt;p&gt;(...)&lt;/p&gt;

&lt;p&gt;But personally I dont like this solution. I was thinking in use the CASE keyword to help me solving it, continuing to have only a single cursor. Something like this (I don't know if this is possible):&lt;/p&gt;

&lt;p&gt;select "fields",
            1 qry_condition
  from table
where (
CASE when to_char(Adate, 'YYYYMMDD') = to_char(I_date, 'YYYYMMDD')
            and "more_conditions"
          then 1
          ----
          when to_char(Adate, 'YYYYMM') = to_char(I_date, 'YYYYMM')
             and "more_conditions"
          then 2
          ----
          when to_char(Adate, 'YYYY') = to_char(I_date, 'YYYY')
             and "more_conditions"
          then 3
         end IN (1, 2, 3)
;&lt;/p&gt;

&lt;p&gt;I know that this Oracle version of the PL/SQL doesn't support the CASE, so I was thinking in using dynamic Sql to do it.
What's your opinion,  does the CASE solves my request or do you have a better solution?&lt;/p&gt;

&lt;p&gt;Thanks in advance&lt;/p&gt;

&lt;p&gt;SASantos&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi!<br />
I&#8217;m using Oracle&#8217;s version 8.1.7.<br />
There&#8217;s a cursor query in a PL/SQL package like the following one:</p>
<p>select &#8220;fields&#8221;,<br />
            1 qry_condition<br />
  from table<br />
where to_char(Adate, &#8216;YYYYMMDD&#8217;) = to_char(I_date, &#8216;YYYYMMDD&#8217;)<br />
    and &#8220;more_conditions&#8221;<br />
union all<br />
select &#8220;fields&#8221;,<br />
            2 qry_condition<br />
  from table<br />
where to_char(Adate, &#8216;YYYYMM&#8217;) = to_char(I_date, &#8216;YYYYMM&#8217;)<br />
    and &#8220;more_conditions&#8221;<br />
union all<br />
select &#8220;fields&#8221;,<br />
            3 qry_condition<br />
  from table<br />
where to_char(Adate, &#8216;YYYY&#8217;) = to_char(I_date, &#8216;YYYY&#8217;)<br />
    and &#8220;more_conditions&#8221;<br />
order by &#8220;2&#8243; &#8212; qry_condition;</p>
<p>The idea is to execute (only) the first query if results are returned, execute the next query if the first doesn&#8217;t returned rows, and execute the third query if none of the previous two return data.<br />
But as we can conclude, everytime this cursor is executed it runs<br />
all of the three queries that belong to it, which is impacting negatively the cursor perfomance.</p>
<p>One possible solution would be to divide it in three querys and use,<br />
something like this:</p>
<p>open cursor1(L_date);<br />
fetch cursor1 into &#8230;<br />
if cursor1.notfound<br />
then<br />
   open cursor2(L_date);<br />
   fetch cursor2 into &#8230;<br />
   if cursor2.notfound<br />
   then<br />
      open cursor3(L_date);<br />
      fetch cursor3 into &#8230;<br />
      if cursor3.notfound then<br />
      (&#8230;)</p>
<p>end if;</p>
<p>(&#8230;)</p>
<p>But personally I dont like this solution. I was thinking in use the CASE keyword to help me solving it, continuing to have only a single cursor. Something like this (I don&#8217;t know if this is possible):</p>
<p>select &#8220;fields&#8221;,<br />
            1 qry_condition<br />
  from table<br />
where (<br />
CASE when to_char(Adate, &#8216;YYYYMMDD&#8217;) = to_char(I_date, &#8216;YYYYMMDD&#8217;)<br />
            and &#8220;more_conditions&#8221;<br />
          then 1<br />
          &#8212;-<br />
          when to_char(Adate, &#8216;YYYYMM&#8217;) = to_char(I_date, &#8216;YYYYMM&#8217;)<br />
             and &#8220;more_conditions&#8221;<br />
          then 2<br />
          &#8212;-<br />
          when to_char(Adate, &#8216;YYYY&#8217;) = to_char(I_date, &#8216;YYYY&#8217;)<br />
             and &#8220;more_conditions&#8221;<br />
          then 3<br />
         end IN (1, 2, 3)<br />
;</p>
<p>I know that this Oracle version of the PL/SQL doesn&#8217;t support the CASE, so I was thinking in using dynamic Sql to do it.<br />
What&#8217;s your opinion,  does the CASE solves my request or do you have a better solution?</p>
<p>Thanks in advance</p>
<p>SASantos</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tom_Fox</title>
		<link>http://awads.net/wp/2005/10/20/case-gotcha-in-oracle-8i/#comment-241</link>
		<dc:creator>Tom_Fox</dc:creator>
		<pubDate>Fri, 21 Oct 2005 18:58:53 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/?p=148#comment-241</guid>
		<description>&lt;p&gt;Ahhh.. wikipedia... didn't think of that.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Ahhh.. wikipedia&#8230; didn&#8217;t think of that.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
