<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1338996429997174255</id><updated>2011-11-27T17:22:26.784-06:00</updated><category term='xml generation'/><category term='JPA'/><category term='package'/><category term='SQL'/><category term='group by'/><category term='java'/><category term='creating xml'/><category term='PL/SQL'/><category term='object'/><category term='pipelined'/><category term='analytic function'/><category term='XML'/><category term='row number'/><category term='column'/><category term='pipe'/><category term='Oracle'/><category term='query'/><category term='java.lang.Class'/><category term='JDBC'/><category term='Object-Oriented'/><category term='row_number()'/><category term='annotation'/><category term='multiple objects'/><category term='grouping id'/><category term='function'/><category term='OOP'/><category term='lag'/><category term='bean'/><category term='Spring'/><category term='constants'/><category term='limit'/><category term='pipe row'/><category term='tables to xml'/><category term='Class'/><title type='text'>Nick's Coding Blog</title><subtitle type='html'>A blog about different programming subjects, mainly Java, SQL and PL/SQL that will help address topics that I have found useful.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-8510141298821002452</id><published>2008-10-07T21:00:00.003-05:00</published><updated>2008-10-07T21:19:13.994-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='analytic function'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='lag'/><title type='text'>Oracle Lag Analytic Function</title><content type='html'>It is rare that you may use the lag function, however, if you do need it, it can be a life saver.  I've only had to use it once.... ever.  The reason for it was so convoluted and asinine that I'll spare you those painful details.  The lag function allows you to access data from previous rows.  Let's take a look at a simple example:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;product,&amp;nbsp;order_date,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;lag(order_date,1)&amp;nbsp;over&amp;nbsp;(&lt;span class="keyword"&gt;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;order_date)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;prev_order_date&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;orders;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And the result:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;PRODUCT                   ORDER_DATE                PREV_ORDER_DATE           &lt;br /&gt;------------------------- ------------------------- ------------------------- &lt;br /&gt;Basketball                07-OCT-07                                           &lt;br /&gt;Baseball                  27-OCT-07                 07-OCT-07                 &lt;br /&gt;Football                  16-DEC-07                 27-OCT-07                 &lt;br /&gt;Basketball                11-MAR-08                 16-DEC-07                 &lt;br /&gt;Football                  04-AUG-08                 11-MAR-08                 &lt;br /&gt;Basketball                07-OCT-08                 04-AUG-08                 &lt;br /&gt;&lt;br /&gt;6 rows selected&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So basically allowed me to query my orders table and get the previous order date, without some complicated inline query to try to figure that out.  Well that isn't very interesting.  So I got the previous order date on the current line, big deal.  The cool part of this is what it now allows me to do.  I can now answer questions like, "how many days is it between orders?".  Let's take a look.&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;product,&amp;nbsp;order_date,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;nvl(order_date&amp;nbsp;-&amp;nbsp;lag(order_date,1)&amp;nbsp;over&amp;nbsp;(&lt;span class="keyword"&gt;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;order_date),0)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;days_since_last_order&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;orders;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And the resutls:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;PRODUCT                   ORDER_DATE                DAYS_SINCE_LAST_ORDER  &lt;br /&gt;------------------------- ------------------------- ---------------------- &lt;br /&gt;Basketball                07-OCT-07                 0                      &lt;br /&gt;Baseball                  27-OCT-07                 20                     &lt;br /&gt;Football                  16-DEC-07                 50                     &lt;br /&gt;Basketball                11-MAR-08                 86                     &lt;br /&gt;Football                  04-AUG-08                 146                    &lt;br /&gt;Basketball                07-OCT-08                 64                     &lt;br /&gt;&lt;br /&gt;6 rows selected&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Its look as if Nick's Basketball, Baseball and Football Emporium will be going out of business.   Especially if there are 146 days between orders.  Okay so all this looks cool on a report, but I really need to know the average time between orders.  Ask and ye shall receive.  Sorry to go all biblely on you.&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="func"&gt;avg&lt;/span&gt;&lt;span&gt;(days_since_last_order)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;(&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;order_date&amp;nbsp;-&amp;nbsp;lag(order_date,1)&amp;nbsp;over&amp;nbsp;(&lt;span class="keyword"&gt;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;order_date)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;days_since_last_order&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;orders);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And the answer: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;AVG(DAYS_SINCE_LAST_ORDER) &lt;br /&gt;-------------------------- &lt;br /&gt;73.2                       &lt;br /&gt;&lt;br /&gt;1 rows selected&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(Note:  Oracle doesn't include nulls in the average, which is precisely what we want.  If we wanted the first record to show zero, I would have left the nvl function in there.)&lt;br /&gt;So the average days between orders is 73.2.  So apparently selling basketballs, baseballs and footballs is not my calling.  One more thing, the number that appears inside the parenthesis tells Oracle how far back to go.  So if you say 1 it looks at the previous row, 2 the row before the previous row and so on.  Let's take a look.&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;product,&amp;nbsp;order_date,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;lag(order_date,2)&amp;nbsp;over&amp;nbsp;(&lt;span class="keyword"&gt;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;order_date)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;prev_prev_order_date&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;orders&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And the results:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;PRODUCT                   ORDER_DATE                PREV_PREV_ORDER_DATE      &lt;br /&gt;------------------------- ------------------------- ------------------------- &lt;br /&gt;Basketball                07-OCT-07                                           &lt;br /&gt;Baseball                  27-OCT-07                                           &lt;br /&gt;Football                  16-DEC-07                 07-OCT-07                 &lt;br /&gt;Basketball                11-MAR-08                 27-OCT-07                 &lt;br /&gt;Football                  04-AUG-08                 16-DEC-07                 &lt;br /&gt;Basketball                07-OCT-08                 11-MAR-08                 &lt;br /&gt;&lt;br /&gt;6 rows selected&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice now it gives me the order date for the record two rows back.  Pretty cool stuff.  Again, you may never use it, but its nice to have in your arsenal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-8510141298821002452?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/8510141298821002452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=8510141298821002452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8510141298821002452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8510141298821002452'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/10/oracle-lag-analytic-function.html' title='Oracle Lag Analytic Function'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-7796990983301138764</id><published>2008-09-23T20:36:00.008-05:00</published><updated>2008-10-07T21:22:37.521-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='group by'/><category scheme='http://www.blogger.com/atom/ns#' term='grouping id'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Group By and Grouping Id - Determining Levels of Aggregation</title><content type='html'>&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;In Oracle, the ability to do aggregates are a very powerful feature.  However, at times it can be confusing when you have several layers of aggregation or nulls in the columns that are being grouped by.  For instance, take the following query:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt; department_id, &lt;/span&gt;&lt;span class="func"&gt;sum&lt;/span&gt;&lt;span&gt;(salary)  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt; employees  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;rollup&lt;/span&gt;&lt;span&gt; (department_id);  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Which yields the following results:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;DEPARTMENT_ID &lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;SUM(SALARY)          &lt;br /&gt;---------------------- ----------------------&lt;br /&gt;10 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;4400                 &lt;br /&gt;20 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;19000                &lt;br /&gt;30 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;24900                &lt;br /&gt;40 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;6500                 &lt;br /&gt;50 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;156400               &lt;br /&gt;60 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;28800                &lt;br /&gt;70 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;10000                &lt;br /&gt;80 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;304500               &lt;br /&gt;90 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;58000                &lt;br /&gt;100 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;51600                &lt;br /&gt;110 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;20300                &lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;7000                 &lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;691400               &lt;br /&gt;&lt;br /&gt;13 rows selected&lt;br /&gt;&lt;br /&gt;Notice I want to rollup the results to get a sum total, however I have 2 rows  with null, which one is the rollup value?  While its very easy to spot for a human, when attempting to present the data to a user in a meaningful fashion, knowing which row that is the total is very handy.  To help with this problem, Oracle has something called a grouping_id, which identifies the level of aggregation.  Take the following query:&lt;br /&gt;&lt;br /&gt;&lt;div class="dp-highlighter" id="hlDiv"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol start="1" class="dp-sql"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt; department_id, &lt;/span&gt;&lt;span class="func"&gt;sum&lt;/span&gt;&lt;span&gt;(salary), grouping_id(department_id)   &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt; employees  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;rollup&lt;/span&gt;&lt;span&gt; (department_id);  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Which yields the following results...&lt;br /&gt;&lt;br /&gt;DEPARTMENT_ID&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;          SUM(SALARY) &lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;GROUPING_ID(DEPARTMENT_ID)&lt;br /&gt;---------------------- ---------------------- --------------------------&lt;br /&gt;10 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;4400 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;20 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;19000 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;30 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;24900 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;40&lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;6500 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;50 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;156400 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;60 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;28800 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;70 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;10000 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;80 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;304500 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;90 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;58000 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;100 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;51600 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;110 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;20300 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;7000 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;0                        &lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;     &lt;/span&gt;691400 &lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;1                        &lt;br /&gt;&lt;br /&gt;13 rows selected&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Notice in the grouping_id column, the total is indicated by the number 1, which identifies the level of aggregation.  Let's look at a more complex example that gives more explicitly indicates what is taking place.&lt;br /&gt;&lt;br /&gt;&lt;div class="dp-highlighter" id="hlDiv"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol start="1" class="dp-sql"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt; department_id, job_id, &lt;/span&gt;&lt;span class="func"&gt;sum&lt;/span&gt;&lt;span&gt;(salary),   &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;grouping_id(department_id) dept_g, grouping_id(job_id) job_g,  &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="func"&gt;case&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'00'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Detail Both'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'10'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Agg over department'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'01'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Agg over job'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'11'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Agg over both'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      description  &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt; employees  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;rollup&lt;/span&gt;&lt;span&gt; (department_id, job_id);  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Which yields the following:&lt;br /&gt;&lt;div style="width: 400px; height: 750px; overflow: auto; padding: 4px;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DEPT                   JOB_ID     SUM(SALARY)            DEPT_G                 JOB_G                  DESCRIPTION         &lt;br /&gt;---------------------- ---------- ---------------------- ---------------------- ---------------------- ------------------- &lt;br /&gt;                       SA_REP     7000                   0                      0                      Detail Both         &lt;br /&gt;                                  7000                   0                      1                      Agg over job        &lt;br /&gt;10                     AD_ASST    4400                   0                      0                      Detail Both         &lt;br /&gt;10                                4400                   0                      1                      Agg over job        &lt;br /&gt;20                     MK_MAN     13000                  0                      0                      Detail Both         &lt;br /&gt;20                     MK_REP     6000                   0                      0                      Detail Both         &lt;br /&gt;20                                19000                  0                      1                      Agg over job        &lt;br /&gt;30                     PU_MAN     11000                  0                      0                      Detail Both         &lt;br /&gt;30                     PU_CLERK   13900                  0                      0                      Detail Both         &lt;br /&gt;30                                24900                  0                      1                      Agg over job        &lt;br /&gt;40                     HR_REP     6500                   0                      0                      Detail Both         &lt;br /&gt;40                                6500                   0                      1                      Agg over job        &lt;br /&gt;50                     ST_MAN     36400                  0                      0                      Detail Both         &lt;br /&gt;50                     SH_CLERK   64300                  0                      0                      Detail Both         &lt;br /&gt;50                     ST_CLERK   55700                  0                      0                      Detail Both         &lt;br /&gt;50                                156400                 0                      1                      Agg over job        &lt;br /&gt;60                     IT_PROG    28800                  0                      0                      Detail Both         &lt;br /&gt;60                                28800                  0                      1                      Agg over job        &lt;br /&gt;70                     PR_REP     10000                  0                      0                      Detail Both         &lt;br /&gt;70                                10000                  0                      1                      Agg over job        &lt;br /&gt;80                     SA_MAN     61000                  0                      0                      Detail Both         &lt;br /&gt;80                     SA_REP     243500                 0                      0                      Detail Both         &lt;br /&gt;80                                304500                 0                      1                      Agg over job        &lt;br /&gt;90                     AD_VP      34000                  0                      0                      Detail Both         &lt;br /&gt;90                     AD_PRES    24000                  0                      0                      Detail Both         &lt;br /&gt;90                                58000                  0                      1                      Agg over job        &lt;br /&gt;100                    FI_MGR     12000                  0                      0                      Detail Both         &lt;br /&gt;100                    FI_ACCOUNT 39600                  0                      0                      Detail Both         &lt;br /&gt;100                               51600                  0                      1                      Agg over job        &lt;br /&gt;110                    AC_MGR     12000                  0                      0                      Detail Both         &lt;br /&gt;110                    AC_ACCOUNT 8300                   0                      0                      Detail Both         &lt;br /&gt;110                               20300                  0                      1                      Agg over job        &lt;br /&gt;                                  691400                 1                      1                      Agg over both       &lt;br /&gt;&lt;br /&gt;33 rows selected&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;With the rollup clause, it clearly identifies which rows are the aggregate rows for job_id and which row is the grand total row.  Just for completeness, lets look at cubing our querying, which provides aggregate totals for each column.&lt;br /&gt;&lt;br /&gt;&lt;div class="dp-highlighter" id="hlDiv"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol start="1" class="dp-sql"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt; department_id dept, job_id, &lt;/span&gt;&lt;span class="func"&gt;sum&lt;/span&gt;&lt;span&gt;(salary),   &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;grouping_id(department_id) dept_g, grouping_id(job_id) job_g,  &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="func"&gt;case&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'00'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Detail Both'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'10'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Agg over department'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'01'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Agg over job'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;when&lt;/span&gt;&lt;span&gt; grouping_id(department_id)||grouping_id(job_id) = &lt;/span&gt;&lt;span class="string"&gt;'11'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;'Agg over both'&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;      description  &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt; employees  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;cube&lt;/span&gt;&lt;span&gt; (department_id, job_id);  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Which yields the following:&lt;br /&gt;&lt;div style="width: 400px; height: 750px; overflow: auto; padding: 4px;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DEPT                   JOB_ID     SUM(SALARY)            DEPT_G                 JOB_G                  DESCRIPTION         &lt;br /&gt;---------------------- ---------- ---------------------- ---------------------- ---------------------- ------------------- &lt;br /&gt;                                  7000                   0                      1                      Agg over job        &lt;br /&gt;                                  691400                 1                      1                      Agg over both       &lt;br /&gt;                       AD_VP      34000                  1                      0                      Agg over department &lt;br /&gt;                       AC_MGR     12000                  1                      0                      Agg over department &lt;br /&gt;                       FI_MGR     12000                  1                      0                      Agg over department &lt;br /&gt;                       HR_REP     6500                   1                      0                      Agg over department &lt;br /&gt;                       MK_MAN     13000                  1                      0                      Agg over department &lt;br /&gt;                       MK_REP     6000                   1                      0                      Agg over department &lt;br /&gt;                       PR_REP     10000                  1                      0                      Agg over department &lt;br /&gt;                       PU_MAN     11000                  1                      0                      Agg over department &lt;br /&gt;                       SA_MAN     61000                  1                      0                      Agg over department &lt;br /&gt;                       SA_REP     7000                   0                      0                      Detail Both         &lt;br /&gt;                       SA_REP     250500                 1                      0                      Agg over department &lt;br /&gt;                       ST_MAN     36400                  1                      0                      Agg over department &lt;br /&gt;                       AD_ASST    4400                   1                      0                      Agg over department &lt;br /&gt;                       AD_PRES    24000                  1                      0                      Agg over department &lt;br /&gt;                       IT_PROG    28800                  1                      0                      Agg over department &lt;br /&gt;                       PU_CLERK   13900                  1                      0                      Agg over department &lt;br /&gt;                       SH_CLERK   64300                  1                      0                      Agg over department &lt;br /&gt;                       ST_CLERK   55700                  1                      0                      Agg over department &lt;br /&gt;                       AC_ACCOUNT 8300                   1                      0                      Agg over department &lt;br /&gt;                       FI_ACCOUNT 39600                  1                      0                      Agg over department &lt;br /&gt;10                                4400                   0                      1                      Agg over job        &lt;br /&gt;10                     AD_ASST    4400                   0                      0                      Detail Both         &lt;br /&gt;20                                19000                  0                      1                      Agg over job        &lt;br /&gt;20                     MK_MAN     13000                  0                      0                      Detail Both         &lt;br /&gt;20                     MK_REP     6000                   0                      0                      Detail Both         &lt;br /&gt;30                                24900                  0                      1                      Agg over job        &lt;br /&gt;30                     PU_MAN     11000                  0                      0                      Detail Both         &lt;br /&gt;30                     PU_CLERK   13900                  0                      0                      Detail Both         &lt;br /&gt;40                                6500                   0                      1                      Agg over job        &lt;br /&gt;40                     HR_REP     6500                   0                      0                      Detail Both         &lt;br /&gt;50                                156400                 0                      1                      Agg over job        &lt;br /&gt;50                     ST_MAN     36400                  0                      0                      Detail Both         &lt;br /&gt;50                     SH_CLERK   64300                  0                      0                      Detail Both         &lt;br /&gt;50                     ST_CLERK   55700                  0                      0                      Detail Both         &lt;br /&gt;60                                28800                  0                      1                      Agg over job        &lt;br /&gt;60                     IT_PROG    28800                  0                      0                      Detail Both         &lt;br /&gt;70                                10000                  0                      1                      Agg over job        &lt;br /&gt;70                     PR_REP     10000                  0                      0                      Detail Both         &lt;br /&gt;80                                304500                 0                      1                      Agg over job        &lt;br /&gt;80                     SA_MAN     61000                  0                      0                      Detail Both         &lt;br /&gt;80                     SA_REP     243500                 0                      0                      Detail Both         &lt;br /&gt;90                                58000                  0                      1                      Agg over job        &lt;br /&gt;90                     AD_VP      34000                  0                      0                      Detail Both         &lt;br /&gt;90                     AD_PRES    24000                  0                      0                      Detail Both         &lt;br /&gt;100                               51600                  0                      1                      Agg over job        &lt;br /&gt;100                    FI_MGR     12000                  0                      0                      Detail Both         &lt;br /&gt;100                    FI_ACCOUNT 39600                  0                      0                      Detail Both         &lt;br /&gt;110                               20300                  0                      1                      Agg over job        &lt;br /&gt;110                    AC_MGR     12000                  0                      0                      Detail Both         &lt;br /&gt;110                    AC_ACCOUNT 8300                   0                      0                      Detail Both         &lt;br /&gt;&lt;br /&gt;52 rows selected&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Notice now I can't just assume the aggregates come in the order I expect them, i.e., the grand total is at the bottom.  If you were like me, rollups and cubes held more mystery that help in most cases, however with grouping_ids it becomes more apparent the meaning of each row and what exactly Oracle is aggregating for you.  (Note: All queries were run against the HR schema that comes with Oracle 10g Express Edition (XE)).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt; &lt;tr&gt;&lt;th&gt;DEPARTMENT_ID&lt;/th&gt; &lt;th&gt;JOB_ID&lt;/th&gt; &lt;th&gt;SUM(SALARY)&lt;/th&gt; &lt;th&gt;DEPT_G&lt;/th&gt; &lt;th&gt;JOB_G&lt;/th&gt; &lt;th&gt;DESCRIPTION&lt;/th&gt; &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;SA_REP&lt;/td&gt;&lt;td&gt;7000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;7000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;AD_ASST&lt;/td&gt;&lt;td&gt;4400&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;4400&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;MK_MAN&lt;/td&gt;&lt;td&gt;13000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;MK_REP&lt;/td&gt;&lt;td&gt;6000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;19000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;PU_MAN&lt;/td&gt;&lt;td&gt;11000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;PU_CLERK&lt;/td&gt;&lt;td&gt;13900&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;24900&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;40&lt;/td&gt;&lt;td&gt;HR_REP&lt;/td&gt;&lt;td&gt;6500&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;40&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;6500&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;ST_MAN&lt;/td&gt;&lt;td&gt;36400&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;SH_CLERK&lt;/td&gt;&lt;td&gt;64300&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;ST_CLERK&lt;/td&gt;&lt;td&gt;55700&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;156400&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;60&lt;/td&gt;&lt;td&gt;IT_PROG&lt;/td&gt;&lt;td&gt;28800&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;60&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;28800&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;70&lt;/td&gt;&lt;td&gt;PR_REP&lt;/td&gt;&lt;td&gt;10000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;70&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;10000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;80&lt;/td&gt;&lt;td&gt;SA_MAN&lt;/td&gt;&lt;td&gt;61000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;80&lt;/td&gt;&lt;td&gt;SA_REP&lt;/td&gt;&lt;td&gt;243500&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;80&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;304500&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;90&lt;/td&gt;&lt;td&gt;AD_VP&lt;/td&gt;&lt;td&gt;34000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;90&lt;/td&gt;&lt;td&gt;AD_PRES&lt;/td&gt;&lt;td&gt;24000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;90&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;58000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;FI_MGR&lt;/td&gt;&lt;td&gt;12000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;FI_ACCOUNT&lt;/td&gt;&lt;td&gt;39600&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;51600&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;110&lt;/td&gt;&lt;td&gt;AC_MGR&lt;/td&gt;&lt;td&gt;12000&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;110&lt;/td&gt;&lt;td&gt;AC_ACCOUNT&lt;/td&gt;&lt;td&gt;8300&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;Detail Both&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;110&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;20300&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over manager&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;691400&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agg over both&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-7796990983301138764?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/7796990983301138764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=7796990983301138764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/7796990983301138764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/7796990983301138764'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/09/group-by-and-grouping-id-determining.html' title='Group By and Grouping Id - Determining Levels of Aggregation'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-8314906272231839286</id><published>2008-09-14T19:29:00.002-05:00</published><updated>2008-09-14T19:34:36.344-05:00</updated><title type='text'>Oracle Extract function</title><content type='html'>Here is a function I ran across in Oracle that I consider very helpful.  I used to use the to_char function to get the piece or pieces of a date I needed to display or for calculations or what have you.  Now I simply use the EXTRACT function to, well, extract the piece of the date I need.&lt;br /&gt;&lt;br /&gt;If I needed the year, I would simply issue the following:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;extract(&lt;/span&gt;&lt;span class="func"&gt;YEAR&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;sysdate)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;dual;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Or if I needed the month:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;extract(&lt;/span&gt;&lt;span class="func"&gt;MONTH&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;sysdate)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;dual;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This function works with dates, timestamps and even the interval datatype.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-8314906272231839286?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/8314906272231839286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=8314906272231839286' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8314906272231839286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8314906272231839286'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/09/oracle-extract-function.html' title='Oracle Extract function'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-8051266367694075092</id><published>2008-07-01T21:53:00.003-05:00</published><updated>2008-07-01T22:42:48.901-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tables to xml'/><category scheme='http://www.blogger.com/atom/ns#' term='creating xml'/><category scheme='http://www.blogger.com/atom/ns#' term='xml generation'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Oracle XML Generation</title><content type='html'>Even though Oracle is a relational database, it handles XML quite well.  Specifically, its actually very efficient at generating XML from data in relational tables.  There are a couple of different options when it comes to XML generation, using the dbms_xmlgen package or the SQL set of XML functions.  &lt;br /&gt;&lt;br /&gt;The dbms_xmlgen package provides a very easy to way to generate xml.  Basically you give it a query and it gives you xml.  Let's take a look:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;declare&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;ctx&amp;nbsp;dbms_xmlgen.ctxHandle;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;xml&amp;nbsp;xmlType;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;begin&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;ctx&amp;nbsp;:=&amp;nbsp;dbms_xmlgen.newContext(&lt;span class="string"&gt;'select&amp;nbsp;*&amp;nbsp;from&amp;nbsp;employees&amp;nbsp;where&amp;nbsp;employee_id&amp;nbsp;=&amp;nbsp;:emp_id'&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;dbms_xmlgen.setbindvalue(ctx,&lt;span class="string"&gt;'emp_id'&lt;/span&gt;&lt;span&gt;,100);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;xml&amp;nbsp;:=&amp;nbsp;dbms_xmlgen.getXMLType(ctx);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;dbms_output.put_line(substr(xml.getClobVal(),0,4000));&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And here is the result....&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;ROWSET&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;ROW&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;EMPLOYEE_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;EMPLOYEE_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;FIRST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;Steven&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;FIRST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;LAST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;King&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;LAST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;EMAIL&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;SKING&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;EMAIL&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;PHONE_NUMBER&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;515.123.4567&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;PHONE_NUMBER&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;HIRE_DATE&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;17-JUN-87&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;HIRE_DATE&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;JOB_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;AD_PRES&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;JOB_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;SALARY&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;24000&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;SALARY&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;DEPARTMENT_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;90&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;DEPARTMENT_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;ROW&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;ROWSET&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;All right so that is pretty cool.  Query in, XML out.  This package has major pros and cons.  Pros:  For hierarchical data, specifically data created using a connect by statement, it really cannot be beat.  (The method is called, newContextFromHierarchy, and you'll have to use the "level" psuedo-column in conjunction with the connect by to use that feature.) Cons:  You really can't nest calls in there and expect it to be performant.  Well you may ask, why would I want to nest those calls?  In my experience, you'll need to pull data in from other tables to include as children xml elements on the main record.  When you do that too much then you can have some problems with performance AND you may even experience actual memory errors from the underlying C code.  Moral of the story: Just be careful if you are generating large amounts of XML.  Another con, most of the cool features are 10g only, so you 9i'ers out there, will have to use the SQL XML functions.&lt;br /&gt;&lt;br /&gt;Speaking of the SQL XML functions, that would be the second method of XML generation to discuss.  If you look at these tags in the documentation, they are scary.  No, really, like see your grandmother naked kind of scary. However, after you actually use the tags, they are very powerful and very performant even when generating lots of XML.  Basically the tags you'll use most frequently are the xmlelement, xmlagg and xmlforest functions.  Let's see them in action...&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;xmlelement(&lt;/span&gt;&lt;span class="string"&gt;"ROWSET"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlagg(&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlelement(&lt;span class="string"&gt;"ROW"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlforest(employee_id,&amp;nbsp;first_name,&amp;nbsp;last_name,&amp;nbsp;email,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;phone_number,&amp;nbsp;hire_date,&amp;nbsp;job_id,&amp;nbsp;salary,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;department_id))))&amp;nbsp;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;employees&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;where&lt;/span&gt;&lt;span&gt;&amp;nbsp;employee_id&amp;nbsp;=&amp;nbsp;100;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And the result is....&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;ROWSET&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;ROW&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;EMPLOYEE_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;EMPLOYEE_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;FIRST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;Steven&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;FIRST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;LAST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;King&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;LAST_NAME&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;EMAIL&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;SKING&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;EMAIL&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;PHONE_NUMBER&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;515.123.4567&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;PHONE_NUMBER&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;HIRE_DATE&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;1987-06-17&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;HIRE_DATE&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;JOB_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;AD_PRES&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;JOB_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;SALARY&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;24000&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;SALARY&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;DEPARTMENT_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;90&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;DEPARTMENT_ID&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;ROW&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;ROWSET&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;Okay so basically the same XML we got from the dbms_xmlgen package.  A little more work, sure, but your DBA's will love you for it.  Let's analyze what each function does in a little more detail.  &lt;br /&gt;Xmlelement, basically takes a varchar as the element name ("name" is different from "NAME") and the data you want to xml-ize.  &lt;br /&gt;Xmlagg will basically take your row xml and concatenate each together in one big xml document. &lt;br /&gt;Xmlforest takes the list of columns and xml-izes them all, using the column name or the alias that you give it as the tag name.  &lt;br /&gt;&lt;br /&gt;Using those 3 tags will generate most of the xml you will need, however there are others like xmlattribute and xmlcomment that may come in handy.  &lt;br /&gt;&lt;br /&gt;Good luck XMLing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-8051266367694075092?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/8051266367694075092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=8051266367694075092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8051266367694075092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8051266367694075092'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/07/oracle-xml-generation.html' title='Oracle XML Generation'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-8067511267228813359</id><published>2008-06-30T20:28:00.004-05:00</published><updated>2008-06-30T20:49:41.266-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='query'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple objects'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Oracle and JDBC, multiple objects one query</title><content type='html'>In a world of JPA and various ORM's, sometimes the lowly JDBC is completely forgotten.  However, JDBC has a powerful advantage over ORM and that is that it gives the developer complete control over what is executed and how the data is mapped relationally.  More often than not, we retrieve data from multiple tables that we then map to multiple objects.  There are several ways to accomplish this, we can make a "super-query" with all the columns for all the tables we need on one row and we do some fancy "if" statement fun to model the data to our objects.  Or we can make a proc on the Oracle side and declare cursors and the whole deal to get what we want.  I'm actually not a big fan of other one, because there is a little heavy lifting involved either way.  My preferred method of getting records back is to use Oracle's "cursor expressions".  Cursor expressions are simply queries embedded in the SQL that come back as ref cursors.  So let's see them in action.&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;d.*,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;cursor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;e.*&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;employees&amp;nbsp;e&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;where&lt;/span&gt;&lt;span&gt;&amp;nbsp;e.department_id&amp;nbsp;=&amp;nbsp;d.department_id)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;employees&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;departments&amp;nbsp;d;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Using Oracle 10g Express Edition's hr schema, I wanted all departments, with all the employees in each department in one call.  Using the cursor keyword, I now have a ref cursor pointing to those employees per department record.&lt;br /&gt;&lt;br /&gt;Enough already!  Show me how to get this back in JDBC.  Alright, since you were so nice about it.  Its actually dirt simple.  &lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;//...&amp;nbsp;normal&amp;nbsp;jdbc&amp;nbsp;type&amp;nbsp;execution&amp;nbsp;code&amp;nbsp;here&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;//my&amp;nbsp;result&amp;nbsp;set&amp;nbsp;object&amp;nbsp;is&amp;nbsp;called&amp;nbsp;rs&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;ResultSet&amp;nbsp;employees&amp;nbsp;=&amp;nbsp;(ResultSet)rs.getObject(&lt;span class="string"&gt;"employees"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You simply use the getObject call using the ResultSet object returned by JDBC when executing a select statement, and then cast it to a ResultSet object, which in my example will be a ResultSet containing employee information.  &lt;br /&gt;&lt;br /&gt;So why should you use this?  Um, because its fast and its easy.  The way to get the most out of your database call is to get the most amount of data back at a time as you can.  Using cursor expressions allows you to do that, without creating lots of procedures to return various ref cursors.  &lt;br /&gt;&lt;br /&gt;But Nick, what about all those open cursors won't I exceed max number of cursors on Oracle?  The answer is no, you won't.  You just have to remember to close those ResultSet object you are creating.  So if you do get that message, check to make sure all your ResultSet's are being closed properly.&lt;br /&gt;&lt;br /&gt;Have fun with your fast JDBC code, your customers will love you for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-8067511267228813359?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/8067511267228813359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=8067511267228813359' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8067511267228813359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8067511267228813359'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/06/oracle-and-jdbc-multiple-objects-one.html' title='Oracle and JDBC, multiple objects one query'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-4497539922658947591</id><published>2008-02-29T20:57:00.003-06:00</published><updated>2008-02-29T21:19:39.944-06:00</updated><title type='text'>Decode Function</title><content type='html'>I will admit that this isn't the best name Oracle could have given to this function.  This is a very powerful SQL function that can really help developers.  Its main purpose is to provide a pseudo if statement inside an sql statement.  The decode statement takes the following parameters:&lt;br /&gt;&lt;br /&gt;decode(text_to_compare,value_to_compare,result_if_true,result_if_false);&lt;br /&gt;&lt;br /&gt;Let's see decode in action to firm up everyone's understanding.&lt;br /&gt;&lt;br /&gt;&lt;!-- Code --&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;decode(&lt;/span&gt;&lt;span class="string"&gt;'test'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class="string"&gt;'test'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class="string"&gt;'They&amp;nbsp;are&amp;nbsp;equal!'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class="string"&gt;'Um..&amp;nbsp;not&amp;nbsp;so&amp;nbsp;much.'&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;dual;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;DECODE(&lt;span class="string"&gt;'TEST'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class="string"&gt;'TEST'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class="string"&gt;'THEY&amp;nbsp;ARE&amp;nbsp;EQUAL!'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class="string"&gt;'UM..NOT&amp;nbsp;SO&amp;nbsp;MUCH.'&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;------------------------------------------------------&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;They&amp;nbsp;are&amp;nbsp;equal!&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;                                      &lt;br /&gt;&lt;br /&gt;1 rows selected&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, when 'test' equals 'test' then we get 'They are equal!'.  Okay, so that's pretty boring on a good day.  Let's dig in a more complex example.  I have a table called decode_test for obvious reasons that contains information about products that have been sold by yours truly.  &lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;name&lt;/span&gt;&lt;span&gt;,&amp;nbsp;product_id,&amp;nbsp;decode(product_id,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1,&lt;span class="string"&gt;'Stereo&amp;nbsp;System'&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2,&lt;span class="string"&gt;'Blu-Ray&amp;nbsp;DVD&amp;nbsp;Player'&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3,&lt;span class="string"&gt;'Brick&amp;nbsp;of&amp;nbsp;Gold'&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="string"&gt;'Other&amp;nbsp;stuff&amp;nbsp;laying&amp;nbsp;around&amp;nbsp;store.'&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;decode_test;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;NAME&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PRODUCT_ID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PRODUCT_NAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;--------------------&amp;nbsp;----------------------&amp;nbsp;--------------------------------&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;Nicholas&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Stereo&amp;nbsp;System&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;Nicholas&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Brick&amp;nbsp;&lt;span class="keyword"&gt;of&lt;/span&gt;&lt;span&gt;&amp;nbsp;Gold&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;Nicholas&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Blu-Ray&amp;nbsp;DVD&amp;nbsp;Player&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;Nicholas&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Stereo&amp;nbsp;System&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;4&amp;nbsp;&lt;span class="keyword"&gt;rows&lt;/span&gt;&lt;span&gt;&amp;nbsp;selected&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Okay so what happened here?  Basically in my test, each product_id represented some text I wanted to display in there query.  You'll notice decode can take multiple value pairs to test against the input text.&lt;br /&gt;&lt;br /&gt;So I'll admit the previous example won't win any "Example of the Year" awards.  So here is a more practical use of decode that involves dates and conditional summation.&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;name&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="func"&gt;sum&lt;/span&gt;&lt;span&gt;(decode(to_char(date_sold,&lt;/span&gt;&lt;span class="string"&gt;'MMYYYY'&lt;/span&gt;&lt;span&gt;),current_month,amount_sold,&lt;/span&gt;&lt;span class="op"&gt;null&lt;/span&gt;&lt;span&gt;))&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;sales_month_to_date,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="func"&gt;sum&lt;/span&gt;&lt;span&gt;(decode(to_char(date_sold,&lt;/span&gt;&lt;span class="string"&gt;'YYYY'&lt;/span&gt;&lt;span&gt;),current_year,amount_sold,&lt;/span&gt;&lt;span class="op"&gt;null&lt;/span&gt;&lt;span&gt;))&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;sales_year_to_date&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;decode_test,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;(&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;to_char(sysdate,&lt;/span&gt;&lt;span class="string"&gt;'MMYYYY'&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;current_month,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;to_char(sysdate,&lt;span class="string"&gt;'YYYY'&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;current_year&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;dual)&amp;nbsp;d&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;group&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;name&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;NAME&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SALES_MONTH_TO_DATE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SALES_YEAR_TO_DATE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;--------------------&amp;nbsp;----------------------&amp;nbsp;----------------------&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;Nicholas&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;67.5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;132.5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;1&amp;nbsp;&lt;span class="keyword"&gt;rows&lt;/span&gt;&lt;span&gt;&amp;nbsp;selected&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Well, well, that was halfway slick.  In the previous example, I needed to sum only the sales for the current month and for year to date.  Decode helped me to sum the amount_sold, when it was appropriate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-4497539922658947591?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/4497539922658947591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=4497539922658947591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/4497539922658947591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/4497539922658947591'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/02/decode-function.html' title='Decode Function'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-1952494381746818675</id><published>2008-01-09T20:06:00.000-06:00</published><updated>2008-01-09T20:24:56.320-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='limit'/><category scheme='http://www.blogger.com/atom/ns#' term='row number'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='row_number()'/><title type='text'>SQL - Row Numbers and Limits</title><content type='html'>A common occurrence that most programmers face are numbering rows in Oracle.  There are several misconceptions about how to do this and what are the costs of such methods.  I personally use the row_number() analytic function, available since version 9 to accomplish this.&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;my_table.*,&amp;nbsp;row_number()&amp;nbsp;over&amp;nbsp;(&lt;/span&gt;&lt;span class="keyword"&gt;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;id&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;desc&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;my_table;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Note in the above code the syntax of the call, you call the analytic function and then tell Oracle how you want the data to be ordered.  If you used "rownum" to accomplish this you would get some interesting result when changing the order by or introducing a where clause.  &lt;br /&gt;&lt;br /&gt;So obviously row numbering is pretty easily accomplished, however there are times when I only need a certain amount of rows.  For instance, I need 10 rows at a time or 20.  Having written my share of web applications, I can say that feature is needed a lot.  So how can we get say the first 5 results returned, its accomplished by the following:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;(&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;my_table.*,&amp;nbsp;row_number()&amp;nbsp;over&amp;nbsp;(&lt;/span&gt;&lt;span class="keyword"&gt;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;by&lt;/span&gt;&lt;span&gt;&amp;nbsp;id&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;desc&lt;/span&gt;&lt;span&gt;)&amp;nbsp;rn&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;my_table&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;where&lt;/span&gt;&lt;span&gt;&amp;nbsp;rn&amp;nbsp;&lt;/span&gt;&lt;span class="op"&gt;between&lt;/span&gt;&lt;span&gt;&amp;nbsp;1&amp;nbsp;&lt;/span&gt;&lt;span class="op"&gt;and&lt;/span&gt;&lt;span&gt;&amp;nbsp;5;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Okay, now we have limited the number of results returned by our query.  In addition, we can now accomplish things like pagination through a result set of data.  As with most things, there is a cost associated.  Notice my inner query has no where clause, thereby inducing a full table scan.  You may say, 'Now wait, didn't we just limit the amount of results returned?'.  And yes, we did, however Oracle has to run through the  full set of results of the inner query to correctly row_number() the rows and then it can parse out the first five or the last five or whatever combination we need.&lt;br /&gt;&lt;br /&gt;All of that being said, this is the most efficient way to row number and limit are result set of data based purely on the number of results returned in Oracle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-1952494381746818675?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/1952494381746818675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=1952494381746818675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/1952494381746818675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/1952494381746818675'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2008/01/sql-row-numbers-and-limits.html' title='SQL - Row Numbers and Limits'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-3959522693915740106</id><published>2007-12-22T11:40:00.000-06:00</published><updated>2007-12-22T16:06:53.955-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Object-Oriented'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='object'/><category scheme='http://www.blogger.com/atom/ns#' term='OOP'/><title type='text'>PL/SQL and Object-Oriented Programming</title><content type='html'>A little known fact about PL/SQL is that Oracle has been introducing ever-increasing support for Object-Oriented Programming (OOP) ever since version 8.  I have some examples below that will help illustrate some of the OOP concepts. (Note: The following examples are run using Oracle 10g, you'll have to try for yourself to see if they work with a different version.)&lt;br /&gt;&lt;br /&gt;To get started, lets review some terminology and I'm going to assume you are familiar with Java or C++.  Most terms are the same, for instance in Java class methods are still methods in PL/SQL.  However, class variables or fields are called attributes in pl/sql.  Enough with the talking, time for code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- Code --&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;CREATE&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="op"&gt;OR&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="func"&gt;REPLACE&lt;/span&gt;&lt;span&gt;&amp;nbsp;TYPE&amp;nbsp;user_object&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;AS&lt;/span&gt;&lt;span&gt;&amp;nbsp;OBJECT&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;(&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;id&amp;nbsp;number,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;first_name&amp;nbsp;varchar2(250),&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;--&amp;nbsp;attribute&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;last_name&amp;nbsp;varchar2(250),&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;email_address&amp;nbsp;varchar2(1000),&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;--&amp;nbsp;constructor&amp;nbsp;specification&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;CONSTRUCTOR&amp;nbsp;&lt;span class="keyword"&gt;FUNCTION&lt;/span&gt;&lt;span&gt;&amp;nbsp;user_object&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;(&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;id&amp;nbsp;number,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;first_name&amp;nbsp;varchar2,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;last_name&amp;nbsp;varchar2,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;email_address&amp;nbsp;varchar2)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;RETURN&lt;/span&gt;&lt;span&gt;&amp;nbsp;SELF&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;AS&lt;/span&gt;&lt;span&gt;&amp;nbsp;RESULT,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;--&amp;nbsp;member&amp;nbsp;procedure&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;MEMBER&amp;nbsp;&lt;span class="keyword"&gt;PROCEDURE&lt;/span&gt;&lt;span&gt;&amp;nbsp;set_first_name&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;(first_name&amp;nbsp;varchar2),&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;--&amp;nbsp;member&amp;nbsp;function&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;MEMBER&amp;nbsp;&lt;span class="keyword"&gt;FUNCTION&lt;/span&gt;&lt;span&gt;&amp;nbsp;get_first_name&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;RETURN&lt;/span&gt;&lt;span&gt;&amp;nbsp;varchar2)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;INSTANTIABLE&amp;nbsp;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt;&amp;nbsp;FINAL;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;CREATE&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="op"&gt;OR&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="func"&gt;REPLACE&lt;/span&gt;&lt;span&gt;&amp;nbsp;TYPE&amp;nbsp;BODY&amp;nbsp;user_object&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;AS&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;CONSTRUCTOR&amp;nbsp;&lt;span class="keyword"&gt;FUNCTION&lt;/span&gt;&lt;span&gt;&amp;nbsp;user_object&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;(&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;id&amp;nbsp;number,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;first_name&amp;nbsp;varchar2,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;last_name&amp;nbsp;varchar2,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;email_address&amp;nbsp;varchar2)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;RETURN&lt;/span&gt;&lt;span&gt;&amp;nbsp;SELF&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;AS&lt;/span&gt;&lt;span&gt;&amp;nbsp;RESULT&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;IS&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;BEGIN&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;self.id&amp;nbsp;:=&amp;nbsp;id;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;self.first_name&amp;nbsp;:=&amp;nbsp;first_name;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;self.last_name&amp;nbsp;:=&amp;nbsp;last_name;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;self.email_address&amp;nbsp;:=&amp;nbsp;email_address;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;RETURN&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;END&lt;/span&gt;&lt;span&gt;&amp;nbsp;user_object;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;MEMBER&amp;nbsp;&lt;span class="keyword"&gt;PROCEDURE&lt;/span&gt;&lt;span&gt;&amp;nbsp;set_first_name&amp;nbsp;(first_name&amp;nbsp;varchar2)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;is&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;BEGIN&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;self.first_name&amp;nbsp;:=&amp;nbsp;first_name;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;END&lt;/span&gt;&lt;span&gt;&amp;nbsp;set_first_name;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;MEMBER&amp;nbsp;&lt;span class="keyword"&gt;FUNCTION&lt;/span&gt;&lt;span&gt;&amp;nbsp;get_first_name&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;RETURN&lt;/span&gt;&lt;span&gt;&amp;nbsp;varchar2&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;IS&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;BEGIN&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;RETURN&lt;/span&gt;&lt;span&gt;&amp;nbsp;self.first_name;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;END&lt;/span&gt;&lt;span&gt;&amp;nbsp;get_first_name;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;END&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Okay, so what are we looking at here?  We're looking at an OOP representation of a data structure.  Thank you, Captain Obvious.  The top statement is the object specification, notice I've specified 4 attributes, a constructor and two member methods.  The constructor takes 4 parameters, one for each attribute.  The member methods "set" and "get" the first name attribute.  &lt;br /&gt;&lt;br /&gt;So your next question, wow, this is great and all, but how can this be useful to me.  The answer is simple, lets say I have a function that I need to return several pieces of information.  You can then declare your function to return an object type.  &lt;br /&gt;&lt;br /&gt;This is a huge subject, however if there are some specifics that you are wondering about, just leave a comment and I'll try to answer them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-3959522693915740106?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/3959522693915740106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=3959522693915740106' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/3959522693915740106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/3959522693915740106'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2007/12/plsql-and-object-oriented-programming.html' title='PL/SQL and Object-Oriented Programming'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-6726611511000187735</id><published>2007-12-14T22:45:00.000-06:00</published><updated>2007-12-22T16:18:06.289-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='function'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='pipelined'/><category scheme='http://www.blogger.com/atom/ns#' term='pipe'/><category scheme='http://www.blogger.com/atom/ns#' term='pipe row'/><title type='text'>PL/SQL - Using a function as a table</title><content type='html'>Occasionally, there is a need to output the data of a function in such a way it can be used as a table.  In a recent project, we were wrapped the output of a "c" external procedure using this feature.  For instance:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;some_func();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The syntax there isn't exactly correct, but that is the jist of what we want.  To accomplish the following, you need two things.  A user defined type of type table and a pipelined function.  Below is a very simple example:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;create&lt;/span&gt;&lt;span&gt;&amp;nbsp;type&amp;nbsp;num_as_table&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;table&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;of&lt;/span&gt;&lt;span&gt;&amp;nbsp;number;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;create&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="op"&gt;or&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="func"&gt;replace&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt;&amp;nbsp;work_as_table&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;num_as_table&amp;nbsp;pipelined&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;is&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;begin&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;pipe&amp;nbsp;row(1);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;Now the above function, while not very interesting does demonstrate the point.  I created a new type called, "num_as_table" which basically represents a number.  I then created a pipelined function that simply pipes the number 1.  Now I can simply query my function using the following select statement: &lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-sql" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;select&lt;/span&gt;&lt;span&gt;&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;from&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;table&lt;/span&gt;&lt;span&gt;(work_as_table());&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As we would expect from that snippet, the output will be one.  Obviously, this is a very powerful tool as you can do some heavy duty data manipulations then pipe it out as if it were a table.  (Note: I have only done extensive testing of this on Oracle 10g, however it will work on 9i as well.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-6726611511000187735?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/6726611511000187735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=6726611511000187735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/6726611511000187735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/6726611511000187735'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2007/12/plsql-using-function-as-table.html' title='PL/SQL - Using a function as a table'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-2966093515009926919</id><published>2007-12-13T23:08:00.000-06:00</published><updated>2007-12-14T22:26:22.860-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='package'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='constants'/><title type='text'>PL/SQL - Constants Package</title><content type='html'>Occasionally, there is a need in PL/SQL to have a package of constants.  In one such project I had, there were some drop down values that we stored in the database and we allowed the users to change the text.  We had to write some logic based on the drop down value, but couldn't count on the text remaining the same.  So I wrote a constants package:&lt;br /&gt;&lt;br /&gt;&lt;div style="overflow: scroll; width: 425px; height:500px"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace package CONSTANTS&lt;br /&gt;as&lt;br /&gt;TYPE constants is table of NUMBER(38) INDEX BY VARCHAR2(100);&lt;br /&gt;enum constants;&lt;br /&gt;enum_size = 4;&lt;br /&gt;function getContstant(in_val varchar2) return number;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;create or replace package body CONSTANTS&lt;br /&gt;as&lt;br /&gt;PROCEDURE load_data IS&lt;br /&gt;BEGIN&lt;br /&gt;  enum('CONST1') := 50;&lt;br /&gt;  enum('CONST2') := 51;&lt;br /&gt;  enum('CONST3') := 52;&lt;br /&gt;  enum('CONST4') := 53;&lt;br /&gt;end load_data;&lt;br /&gt;&lt;br /&gt;function getConstant(in_val varchar2) return number&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt;  if enum.COUNT &lt;&gt; enum_size THEN&lt;br /&gt;    load_data();&lt;br /&gt;  end if;&lt;br /&gt;  return enum(upper(in_val));&lt;br /&gt;  EXCEPTION WHEN OTHERS THEN RETURN -1;&lt;br /&gt;end getConstant;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;-- usage&lt;br /&gt;select * from some_table where constant_id = CONSTANTS.getConstant('const1');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You may ask and rightfully so, why not just create a package with a bunch of variables that represent that value?  Good question. The key to the package is the load_data function.  It can be modified to support any implementation of the way you save your constants.  In the example above, I hard coded them in the package, but I could have just as easily read them from the database to avoid my constants table from getting a lot of database hits.  Hopefully, you'll be able to use the above to your advantage.  (Note: The following has only been compiled and tested on Oracle 10g.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-2966093515009926919?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/2966093515009926919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=2966093515009926919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/2966093515009926919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/2966093515009926919'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2007/12/plsql-constants-package.html' title='PL/SQL - Constants Package'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-8208957690003896951</id><published>2007-12-12T21:23:00.000-06:00</published><updated>2007-12-12T22:14:38.499-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='column'/><category scheme='http://www.blogger.com/atom/ns#' term='annotation'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>JPA - Column annotation tip</title><content type='html'>Being an Oracle guy, I always have enjoyed getting into the guts of the SQL language.  Recently I have been using JPA quite a bit recently and was frustrated by a particular problem.  I needed to include a column that was generated off of other columns.  For instance:&lt;br /&gt;&lt;br /&gt;&lt;div class="sql" style="font-family: monospace;color: #006; border: 1px solid #d0d0d0; background-color: #f0f0f0;"&gt;&lt;ol&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;&lt;span style="color: #993333; font-weight: bold;"&gt;SELECT&lt;/span&gt; a, b, a+b &lt;span style="color: #993333; font-weight: bold;"&gt;FROM&lt;/span&gt; uninteresting_table;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In JPA-land, I started by writing my own fetch query and added a dummy field to the database table to accomplish this.  Class, let's say this together, "This sucks.".  However, I did perform a little bit of JPA trickery to get what I want, with the custom fetch query and no dummy data field.  In your persistent bean you'll simply annotate your column as follows:&lt;br /&gt;&lt;br /&gt;&lt;div class="java5" style="font-family: monospace;color: #006; border: 1px solid #d0d0d0; background-color: #f0f0f0;"&gt;&lt;ol&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;&lt;span style="color: #808080; font-style: italic;"&gt;// Java code above....&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt; &lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;@Column&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;name=&lt;span style="color: #ff0000;"&gt;"a+b"&lt;/span&gt;, insertable=&lt;span style="color: #b13366;"&gt;false&lt;/span&gt;, updatable=&lt;span style="color: #b13366;"&gt;false&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;&lt;a style="color: #000060;" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Long.html"&gt;&lt;span style="color: #aaaadd; font-weight: bold;"&gt;Long&lt;/span&gt;&lt;/a&gt; myNewColumn;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-weight: bold;font-weight: bold; color: #006060;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt; &lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;&lt;span style="color: #808080; font-style: italic;"&gt;//Java code below....&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the example above, you'll see I just injected my sql I want as that column name and the rest JPA handles for you.  Other examples include:&lt;br /&gt;&lt;br /&gt;&lt;div class="java5" style="font-family: monospace;color: #006; border: 1px solid #d0d0d0; background-color: #f0f0f0;"&gt;&lt;ol&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;@Column&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;name=&lt;span style="color: #ff0000;"&gt;"myFunc(a)"&lt;/span&gt;, insertable=&lt;span style="color: #b13366;"&gt;false&lt;/span&gt;, updatable=&lt;span style="color: #b13366;"&gt;false&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;&lt;a style="color: #000060;" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html"&gt;&lt;span style="color: #aaaadd; font-weight: bold;"&gt;String&lt;/span&gt;&lt;/a&gt; functionResult;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt; &lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;@Column&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;name=&lt;span style="color: #ff0000;"&gt;"select count(*) from other_table where id = a"&lt;/span&gt;, insertable=&lt;span style="color: #b13366;"&gt;false&lt;/span&gt;, updateable = &lt;span style="color: #b13366;"&gt;false&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="font-weight: bold;font-weight: bold; color: #006060;"&gt;&lt;div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;color: #000020;"&gt;&lt;a style="color: #000060;" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html"&gt;&lt;span style="color: #aaaadd; font-weight: bold;"&gt;String&lt;/span&gt;&lt;/a&gt; queryResult;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-8208957690003896951?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/8208957690003896951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=8208957690003896951' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8208957690003896951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/8208957690003896951'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2007/12/jpa-column-annotation-tips.html' title='JPA - Column annotation tip'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1338996429997174255.post-4383207398362660883</id><published>2007-12-09T18:52:00.000-06:00</published><updated>2007-12-22T16:16:05.127-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java.lang.Class'/><category scheme='http://www.blogger.com/atom/ns#' term='bean'/><category scheme='http://www.blogger.com/atom/ns#' term='Class'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring - Create bean of type Class</title><content type='html'>I had a need recently to create a bean using Spring of type Class (java.lang.Class).  I also wanted to be able to specify the actual class.  So for instance I wanted a bean called "productClass" and wanted to pass in my class name "com.example.product.Product" and let Spring instantiate the bean for me.  To accomplish this, I created the bean in the context xml file using the following:&lt;br /&gt;&lt;br /&gt;&lt;div id="hlDiv" class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;bean&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"productClass"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"java.lang.Class"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="attribute"&gt;factory-method&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"forName"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;constructor-arg&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"com.example.product.Product"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;bean&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This worked great for my purposes, I received my com.example.product.Product Class object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1338996429997174255-4383207398362660883?l=nickscodingblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nickscodingblog.blogspot.com/feeds/4383207398362660883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1338996429997174255&amp;postID=4383207398362660883' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/4383207398362660883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1338996429997174255/posts/default/4383207398362660883'/><link rel='alternate' type='text/html' href='http://nickscodingblog.blogspot.com/2007/12/spring-create-bean-of-type-class.html' title='Spring - Create bean of type Class'/><author><name>Nick</name><uri>http://www.blogger.com/profile/13694292091907654813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
