<?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-4720517759143243102</id><updated>2011-04-21T12:53:16.256-07:00</updated><title type='text'>My World</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-8632863263124921988</id><published>2009-02-12T04:55:00.000-08:00</published><updated>2009-02-15T22:00:04.534-08:00</updated><title type='text'>IN vs EXISTS - They are all the same today.</title><content type='html'>When ever it comes to performance of a query, for a very long time there was a&lt;br /&gt;difference noticed between the usage of IN and EXIST.&lt;br /&gt;&lt;br /&gt;Back then, when i was using a 8i database an improper use of IN where you could have used EXISTS can&lt;br /&gt;result in a very bad performance of your query.&lt;br /&gt;&lt;br /&gt;The execution plan chosen by the optimizer is completely different for both the query.&lt;br /&gt;&lt;br /&gt;Check this out.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ORACLE VERSION: Oracle8i Enterprise Edition Release 8.1.7.2.1 - Production&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; create table big_table&lt;br /&gt;  2  as&lt;br /&gt;  3  select *&lt;br /&gt;  4    from all_objects&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; create table small_table&lt;br /&gt;  2  as&lt;br /&gt;  3  select distinct object_type&lt;br /&gt;  4    from all_objects&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; create index big_table_idx on big_table(object_type)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;Index created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec dbms_stats.gather_table_stats(user,'BIG_TABLE',cascade=&amp;gt;true)&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec dbms_stats.gather_table_stats(user,'SMALL_TABLE',cascade=&amp;gt;true)&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now i want to pick up records from my SMALL_TABLE for which object_type exists in my&lt;br /&gt;BIG_TABLE.&lt;br /&gt;&lt;br /&gt;First iam using IN for this purpose.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select *&lt;br /&gt;  2    from small_table s&lt;br /&gt;  3   where object_type in (select object_type&lt;br /&gt;  4                      from big_table)&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=182 Card=15 Bytes=285)&lt;br /&gt;   1    0   HASH JOIN (Cost=182 Card=15 Bytes=285)&lt;br /&gt;   2    1     VIEW OF 'VW_NSO_1' (Cost=180 Card=15 Bytes=165)&lt;br /&gt;   3    2       SORT (UNIQUE) (Cost=180 Card=15 Bytes=90)&lt;br /&gt;   4    3         TABLE ACCESS (FULL) OF 'BIG_TABLE' (Cost=55 Card=43794 Bytes=262764)&lt;br /&gt;   5    1     TABLE ACCESS (FULL) OF 'SMALL_TABLE' (Cost=1 Card=15 Byt es=120)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The optimizer goes for a full scan on the BIG_TABLE even though i have a index created on it. I can do it&lt;br /&gt;in a better way using EXISTS. See this.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select *&lt;br /&gt;  2    from small_table s&lt;br /&gt;  3   where exists(select null&lt;br /&gt;  4             from big_table b&lt;br /&gt;  5            where b.object_type = s.object_type)&lt;br /&gt;  6  /&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=8)&lt;br /&gt;   1    0   FILTER&lt;br /&gt;   2    1     TABLE ACCESS (FULL) OF 'SMALL_TABLE' (Cost=1 Card=1 Bytes=8)&lt;br /&gt;   3    1     INDEX (RANGE SCAN) OF 'BIG_TABLE_IDX' (NON-UNIQUE) (Cost=7 Card=2920 Bytes=17520)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can notice a nice RANGE SCAN is been done on the BIG_TABLE. So those days it made&lt;br /&gt;a lot of difference. The optimizer could not understand what you are trying to mean. It just gives what you ask for.&lt;br /&gt;&lt;br /&gt;But today, things are different. With the smart CBO on place it understands what you want. It rewrites your query for you.&lt;br /&gt;&lt;br /&gt;Check this out.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;ORACLE VERSION: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With both IN and EXIST you don't find any difference. Its both the same. CBO knows exactly what you want. It &lt;br /&gt;knows so well that it even does only a SEMI join. It comes out of your big table once it finds a single match. It&lt;br /&gt;does not go thought the entire table or the index.&lt;br /&gt;&lt;br /&gt;See how it works.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select *&lt;br /&gt;  2    from small_table s&lt;br /&gt;  3   where exists(select null&lt;br /&gt;  4             from big_table b&lt;br /&gt;  5            where b.object_type = s.object_type)&lt;br /&gt;  6  /&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=34 Card=19 Bytes=323)&lt;br /&gt;   1    0   NESTED LOOPS (SEMI) (Cost=34 Card=19 Bytes=323)&lt;br /&gt;   2    1     TABLE ACCESS (FULL) OF 'SMALL_TABLE' (TABLE) (Cost=3 Card=31 Bytes=279)&lt;br /&gt;   3    1     INDEX (RANGE SCAN) OF 'BIG_TABLE_IDX' (INDEX) (Cost=1 Card=71414 Bytes=571312)&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select *&lt;br /&gt;  2    from small_table s&lt;br /&gt;  3   where object_type in (select object_type&lt;br /&gt;  4                      from big_table)&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=34 Card=19 Bytes=323)&lt;br /&gt;   1    0   NESTED LOOPS (SEMI) (Cost=34 Card=19 Bytes=323)&lt;br /&gt;   2    1     TABLE ACCESS (FULL) OF 'SMALL_TABLE' (TABLE) (Cost=3 Card=31 Bytes=279)&lt;br /&gt;   3    1     INDEX (RANGE SCAN) OF 'BIG_TABLE_IDX' (INDEX) (Cost=1 Card=71414 Bytes=571312)  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Isn't that a beauty!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-8632863263124921988?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/8632863263124921988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=8632863263124921988' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8632863263124921988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8632863263124921988'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2009/02/in-vs-exists-they-are-all-same-today.html' title='IN vs EXISTS - They are all the same today.'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-8562833545624089172</id><published>2009-01-15T22:28:00.000-08:00</published><updated>2009-01-16T04:20:19.258-08:00</updated><title type='text'>INDEX SKIP SCAN</title><content type='html'>A new feature called  INDEX SKIP SCAN was introduced in Oracle 9i. By which oracle has the ability to skip some column of the index and go with the rest.&lt;br /&gt;&lt;br /&gt;For example if you have a index with column (NAME, EMPLID), before 9i when you specify a where condition which just have EMPLID then the index is not considered.&lt;br /&gt;&lt;br /&gt;But from 9i the new feature enables the optimizer to skip the NAME field of the index a go for the EMPLID.&lt;br /&gt;&lt;br /&gt;A simple test case can explain this. See below.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; create table t&lt;br /&gt;  2  as&lt;br /&gt;  3  select 'MY_TEST_DATA' obj_desc, object_id, object_name, object_type&lt;br /&gt;  4    from all_objects&lt;br /&gt;  5  / &lt;br /&gt; &lt;br /&gt;Table created.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; create index t_idx on t(obj_desc, object_id)&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Index created.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; exec dbms_stats.gather_table_stats(user, 'T', cascade=&amp;gt;true)&lt;br /&gt; &lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; select * from t where object_id = 40&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=1 Bytes=45)&lt;br /&gt;   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=4 Card=1 Bytes=45)&lt;br /&gt;   2    1     INDEX (SKIP SCAN) OF 'T_IDX' (INDEX) (Cost=3 Card=1)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;SQL&amp;gt; select * from t where obj_desc = 'MY_TEST_DATA' and object_id = 40&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=1 Bytes=45)&lt;br /&gt;   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=4 Card=1 Bytes=45)&lt;br /&gt;   2    1     INDEX (RANGE SCAN) OF 'T_IDX' (INDEX) (Cost=3 Card=1)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But i am not sure if SKIP SCAN is as good as RANGE SCAN. But you can be certain that its better than FULL SCAN.&lt;br /&gt;&lt;br /&gt;But again the selection of this option by the optimizer depends on the cardinality of the first field. In the above example we saw that OBJ_DESC had one value and hence the optimizer went for a SKIP SCAN.&lt;br /&gt;&lt;br /&gt;Lets take a case where the first column of the index has a high cardinality. Here i am going to create OBJ_DESC field with unique values. lets see what happens.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; drop table t&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Table dropped.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; create table t&lt;br /&gt;  2  as&lt;br /&gt;  3  select 'MY_TEST_DATA'&amp;#124;&amp;#124;rownum obj_desc, object_id, object_name, object_type&lt;br /&gt;  4    from all_objects&lt;br /&gt;  5  / &lt;br /&gt; &lt;br /&gt;Table created.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; create index t_idx on t(obj_desc, object_id)&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Index created.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; exec dbms_stats.gather_table_stats(user, 'T', cascade=&amp;gt;true)&lt;br /&gt; &lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; select * from t where object_id = 40&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=209 Card=1 Bytes=50)&lt;br /&gt;   1    0   TABLE ACCESS (FULL) OF 'T' (TABLE) (Cost=209 Card=1 Bytes=50)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;SQL&amp;gt; select * from t where obj_desc = 'MY_TEST_DATA' and object_id = 40&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=1 Bytes=50)&lt;br /&gt;   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=4 Card=1 Bytes=50)&lt;br /&gt;   2    1     INDEX (RANGE SCAN) OF 'T_IDX' (INDEX) (Cost=3 Card=1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you can very well see that the Optimizer decides to go for a FULL SCAN.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-8562833545624089172?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/8562833545624089172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=8562833545624089172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8562833545624089172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8562833545624089172'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2009/01/index-skip-scan.html' title='INDEX SKIP SCAN'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-3079456516463415884</id><published>2008-12-16T03:19:00.000-08:00</published><updated>2009-04-15T01:47:13.984-07:00</updated><title type='text'>When the optimizer goes for a FULL SCAN</title><content type='html'>It is often asked why a SQL is going for a Full Table Scan. And also its widely considered that &lt;br /&gt;Full Table Scan means BAD performance.&lt;br /&gt;&lt;br /&gt;So i would try to explain the possible caused when a CBO decides to go for a full table&lt;br /&gt;scan. And also the concept of FULL TABLE SCAN IS NOT EVIL.&lt;br /&gt;&lt;br /&gt;To do that i have created a small test setup.&lt;br /&gt;&lt;br /&gt;I have create a table FULL_TABLE_SCAN_TEST from all_objects.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;SQL&amp;gt; create table full_table_scan_test&lt;br /&gt;  2  as&lt;br /&gt;  3  select *&lt;br /&gt;  4    from all_objects&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select count(1) from full_table_scan_test&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;    930360&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I have indexed the column OBJECT_TYPE.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; create index full_table_scan_test_idx on full_table_scan_test(object_type)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;Index created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec dbms_stats.gather_table_stats(user,'FULL_TABLE_SCAN_TEST',cascade=&amp;gt;TRUE)&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;CASE 1: &lt;/span&gt;The optimizer normally goes for a FULL TABLE SCAN when it has to retreive a &lt;br /&gt; large portion of data from the table. This is because when accessing a large&lt;br /&gt; portion of data, a scan through the index can be a overhead.&lt;br /&gt; &lt;br /&gt; Below is a little demonstration of the same.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Now below query shows the count of records for object_type FUNCTION.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select count(1)&lt;br /&gt;  2    from full_table_scan_test&lt;br /&gt;  3   where object_type in ('FUNCTION')&lt;br /&gt;  4  /&lt;br /&gt;&lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;      2408&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a very small portion when compared to the total count which is 930360&lt;br /&gt;&lt;br /&gt;So a condition like this must result in a INDEX RANGE SCAN. Lets try it.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select *&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5   where object_type in ('FUNCTION')&lt;br /&gt;  6  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 607499257&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation                   &amp;#124; Name                     &amp;#124; Rows  &amp;#124; Bytes &amp;#124; Cost (%CPU)&amp;#124; Time     &amp;#124;&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT            &amp;#124;                          &amp;#124;  1833 &amp;#124;   161K&amp;#124;    65   (0)&amp;#124; 00:00:01 &amp;#124;&lt;br /&gt;&amp;#124;   1 &amp;#124;  TABLE ACCESS BY INDEX ROWID&amp;#124; FULL_TABLE_SCAN_TEST     &amp;#124;  1833 &amp;#124;   161K&amp;#124;    65   (0)&amp;#124; 00:00:01 &amp;#124;&lt;br /&gt;&amp;#124;*  2 &amp;#124;   INDEX RANGE SCAN          &amp;#124; FULL_TABLE_SCAN_TEST_IDX &amp;#124;  1833 &amp;#124;       &amp;#124;     7   (0)&amp;#124; 00:00:01 &amp;#124;&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;   2 - access(&amp;quot;OBJECT_TYPE&amp;quot;='FUNCTION')&lt;br /&gt;&lt;br /&gt;14 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As expected we got a INDEX RANGE SCAN.&lt;br /&gt;&lt;br /&gt;But now a filter criteria on the same column which will return a large protion of record will go for&lt;br /&gt;a FULL SCAN. This can easily be illustrated. &lt;br /&gt;&lt;br /&gt;A filter for object_type TABLE, INDEX returns a vast protion for data as shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select count(1)&lt;br /&gt;  2    from full_table_scan_test&lt;br /&gt;  3   where object_type IN ('TABLE','INDEX')&lt;br /&gt;  4  /&lt;br /&gt;&lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;    428688&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So when a filtering is done for this condition you can see the optimizer going for a FULL TABLE SCAN.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select *&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5   where object_type in ('TABLE','INDEX')&lt;br /&gt;  6  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 798910834&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation         &amp;#124; Name                 &amp;#124; Rows  &amp;#124; Bytes &amp;#124; Cost (%CPU)&amp;#124; Time     &amp;#124;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT  &amp;#124;                      &amp;#124;   437K&amp;#124;    37M&amp;#124;  2796   (3)&amp;#124; 00:00:34 &amp;#124;&lt;br /&gt;&amp;#124;*  1 &amp;#124;  TABLE ACCESS FULL&amp;#124; FULL_TABLE_SCAN_TEST &amp;#124;   437K&amp;#124;    37M&amp;#124;  2796   (3)&amp;#124; 00:00:34 &amp;#124;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;   1 - filter(&amp;quot;OBJECT_TYPE&amp;quot;='INDEX' OR &amp;quot;OBJECT_TYPE&amp;quot;='TABLE')&lt;br /&gt;&lt;br /&gt;13 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Most of the time people assume that this is bad and try to HINT the optimizer to use the index.&lt;br /&gt;&lt;br /&gt;This could turn to be expensive. Lets hint the above query and see what happens.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; delete from plan_table&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;2 rows deleted.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select /*+ INDEX(full_table_scan_test full_table_scan_test_idx) */ *&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5   where object_type in ('TABLE','INDEX')&lt;br /&gt;  6  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 279860542&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation                    &amp;#124; Name                     &amp;#124; Rows  &amp;#124; Bytes &amp;#124; Cost (%CPU)&amp;#124; Time  &amp;#124;&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT             &amp;#124;                          &amp;#124;   437K&amp;#124;    37M&amp;#124; 14723   (1)&amp;#124; 00:02:57 &amp;#124;&lt;br /&gt;&amp;#124;   1 &amp;#124;  INLIST ITERATOR             &amp;#124;                          &amp;#124;       &amp;#124;       &amp;#124;            &amp;#124;       &amp;#124;&lt;br /&gt;&amp;#124;   2 &amp;#124;   TABLE ACCESS BY INDEX ROWID&amp;#124; FULL_TABLE_SCAN_TEST     &amp;#124;   437K&amp;#124;    37M&amp;#124; 14723   (1)&amp;#124; 00:02:57 &amp;#124;&lt;br /&gt;&amp;#124;*  3 &amp;#124;    INDEX RANGE SCAN          &amp;#124; FULL_TABLE_SCAN_TEST_IDX &amp;#124;   437K&amp;#124;       &amp;#124;  1053   (2)&amp;#124; 00:00:13 &amp;#124;&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;&lt;br /&gt;   3 - access(&amp;quot;OBJECT_TYPE&amp;quot;='INDEX' OR &amp;quot;OBJECT_TYPE&amp;quot;='TABLE')&lt;br /&gt;&lt;br /&gt;15 rows selected.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here you can see there is a drastic increase in the CPU Cost.&lt;br /&gt;&lt;br /&gt;Conclution: FULL TABLE SCAN is one of the optimal way when trying to access a large portion of data.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;CASE 2: &lt;/span&gt;Use of NOT leads to a FULL TABLE SCAN.&lt;br /&gt; &lt;br /&gt; Even though the optimizer is a very smart program it has its owne assumptions and limitations. &lt;br /&gt; One such thing is, when a NOT operatior is used the optimizer assumes that its going to &lt;br /&gt; fetch a large portion of data and directly goes for a FULL TABLE SCAN.&lt;br /&gt; &lt;br /&gt; So the use of NOT operator leads to a full table scan even though the data retrived is &lt;br /&gt; less. See the demonstration below.&lt;br /&gt; &lt;br /&gt;The follwing condition shown in the below query results in a very small portion of the table&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select count(*)&lt;br /&gt;  2    from full_table_scan_test&lt;br /&gt;  3   where object_type not in ('TABLE','INDEX','VIEW','SYNONYM',&lt;br /&gt;  4                             'TYPE','JAVA CLASS','PACKAGE','PACKAGE BODY')&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;     21184&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But you can see that the optimizer decides to go for a FULL TABLE SCAN. Check this out.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select *&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5   where object_type not in ('TABLE','INDEX','VIEW','SYNONYM',&lt;br /&gt;  6                             'TYPE','JAVA CLASS','PACKAGE','PACKAGE BODY')&lt;br /&gt;  7  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 798910834&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation         &amp;#124; Name                 &amp;#124; Rows  &amp;#124; Bytes &amp;#124; Cost (%CPU)&amp;#124; Time     &amp;#124;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT  &amp;#124;                      &amp;#124;   313K&amp;#124;    26M&amp;#124;  2813   (4)&amp;#124; 00:00:34 &amp;#124;&lt;br /&gt;&amp;#124;*  1 &amp;#124;  TABLE ACCESS FULL&amp;#124; FULL_TABLE_SCAN_TEST &amp;#124;   313K&amp;#124;    26M&amp;#124;  2813   (4)&amp;#124; 00:00:34 &amp;#124;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;   1 - filter(&amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'INDEX' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'TABLE' AND&lt;br /&gt;              &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'SYNONYM' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'VIEW' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'JAVA&lt;br /&gt;              CLASS' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'TYPE' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'PACKAGE BODY' AND&lt;br /&gt;              &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'PACKAGE')&lt;br /&gt;&lt;br /&gt;16 rows selected.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Even hinting will lead only to a INDEX FULL SCAN. A RANGE SCAN is never an option with NOT operator.&lt;br /&gt;&lt;br /&gt;Lets hint and see.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select /*+ INDEX(full_table_scan_test full_table_scan_test_idx) */ *&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5   where object_type not in ('TABLE','INDEX','VIEW','SYNONYM',&lt;br /&gt;  6                             'TYPE','JAVA CLASS','PACKAGE','PACKAGE BODY')&lt;br /&gt;  7  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 2742810082&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation                   &amp;#124; Name                     &amp;#124; Rows  &amp;#124; Bytes &amp;#124; Cost (%CPU)&amp;#124; Time     &amp;#124;&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT            &amp;#124;                          &amp;#124;   313K&amp;#124;    26M&amp;#124; 12196   (1)&amp;#124; 00:02:27 &amp;#124;&lt;br /&gt;&amp;#124;   1 &amp;#124;  TABLE ACCESS BY INDEX ROWID&amp;#124; FULL_TABLE_SCAN_TEST     &amp;#124;   313K&amp;#124;    26M&amp;#124; 12196   (1)&amp;#124; 00:02:27 &amp;#124;&lt;br /&gt;&amp;#124;*  2 &amp;#124;   INDEX FULL SCAN           &amp;#124; FULL_TABLE_SCAN_TEST_IDX &amp;#124;   313K&amp;#124;       &amp;#124;  2412   (3)&amp;#124; 00:00:29 &amp;#124;&lt;br /&gt;--------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;   2 - filter(&amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'INDEX' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'TABLE' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'SYNONYM'&lt;br /&gt;              AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'VIEW' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'JAVA CLASS' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'TYPE' AND&lt;br /&gt;              &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'PACKAGE BODY' AND &amp;quot;OBJECT_TYPE&amp;quot;&amp;lt;&amp;gt;'PACKAGE')&lt;br /&gt;&lt;br /&gt;16 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Conclution: Use NOT operation while retreiving a large portion of data. If you are going to retreive&lt;br /&gt;     a small portion of data try to be positive ;) and do not use NOT operator. One work around &lt;br /&gt;     could be use of &gt; and &lt; together.&lt;br /&gt;     &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;CASE 3: &lt;/span&gt;A NULL column is not an option for INDEX FAST FULL SCAN.&lt;br /&gt; &lt;br /&gt; Normally when we do a COUNT on a table that has a index on a column we expect it to use that&lt;br /&gt; index. But that is possible only when the indexed column is NOT NULL. &lt;br /&gt; &lt;br /&gt; This is simply because the NULL values of a column are not indexed. And hence the optimizer &lt;br /&gt; cant scan throught the index to give you the exact count of a table.&lt;br /&gt; &lt;br /&gt;A little demonstration about this is given below.&lt;br /&gt;&lt;br /&gt;The column OBJECT_TYPE is a NULL'able column. Hence when you do a COUNT on the table it goes for a FULL SCAN.&lt;br /&gt;&lt;br /&gt;Check this out.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select count(*)&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 3323906207&lt;br /&gt;-----------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation          &amp;#124; Name                 &amp;#124; Rows  &amp;#124; Cost (%CPU)&amp;#124; Time     &amp;#124;&lt;br /&gt;-----------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT   &amp;#124;                      &amp;#124;     1 &amp;#124;  2755   (2)&amp;#124; 00:00:34 &amp;#124;&lt;br /&gt;&amp;#124;   1 &amp;#124;  SORT AGGREGATE    &amp;#124;                      &amp;#124;     1 &amp;#124;            &amp;#124;          &amp;#124;&lt;br /&gt;&amp;#124;   2 &amp;#124;   TABLE ACCESS FULL&amp;#124; FULL_TABLE_SCAN_TEST &amp;#124;   930K&amp;#124;  2755   (2)&amp;#124; 00:00:34 &amp;#124;&lt;br /&gt;-----------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;9 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now lets modify the column OBJECT_TYPE as NOT NULL and see what happens.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; alter table full_table_scan_test modify object_type not null&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;Table altered.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec dbms_stats.gather_table_stats(user,'FULL_TABLE_SCAN_TEST',cascade=&amp;gt;TRUE)&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now i execute the same query.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; explain plan&lt;br /&gt;  2  for&lt;br /&gt;  3  select count(*)&lt;br /&gt;  4    from full_table_scan_test&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from table(dbms_xplan.display)&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;Plan hash value: 2070121381&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124; Id  &amp;#124; Operation             &amp;#124; Name                     &amp;#124; Rows  &amp;#124; Cost (%CPU)&amp;#124; Time     &amp;#124;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&amp;#124;   0 &amp;#124; SELECT STATEMENT      &amp;#124;                          &amp;#124;     1 &amp;#124;   536   (5)&amp;#124; 00:00:07 &amp;#124;&lt;br /&gt;&amp;#124;   1 &amp;#124;  SORT AGGREGATE       &amp;#124;                          &amp;#124;     1 &amp;#124;            &amp;#124;          &amp;#124;&lt;br /&gt;&amp;#124;   2 &amp;#124;   INDEX FAST FULL SCAN&amp;#124; FULL_TABLE_SCAN_TEST_IDX &amp;#124;   937K&amp;#124;   536   (5)&amp;#124; 00:00:07 &amp;#124;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;9 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Conclution: Optimizer can't trust a INDEX on a NULL'able column to getting all the data of that column.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-3079456516463415884?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/3079456516463415884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=3079456516463415884' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/3079456516463415884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/3079456516463415884'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/12/it-is-often-asked-why-sql-is-going-for.html' title='When the optimizer goes for a FULL SCAN'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-5211268698540838991</id><published>2008-11-12T21:53:00.000-08:00</published><updated>2008-11-12T22:03:06.137-08:00</updated><title type='text'>Index is not all GOD</title><content type='html'>Another case to prove that index is not all GOD and FULL TABLE SCAN is not evil.&lt;br /&gt;&lt;br /&gt;Today i saw this question on the OTN forum.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Hi All,&lt;br /&gt;&lt;br /&gt;I need to execute a query like this :&lt;br /&gt;SELECT * FROM ORDERS WHERE APPROVE_DATE IS NULL&lt;br /&gt;&lt;br /&gt;I read anywhere that this will cause unnecessary FTS so that I should create function based index.&lt;br /&gt;&lt;br /&gt;I have tried one below , but not sure that this is correct approach :&lt;br /&gt;&lt;br /&gt;CREATE INDEX idx_1&lt;br /&gt;ON ORDERS (NVL(APPROVE_DATE, '01-JAN-1900'));&lt;br /&gt;&lt;br /&gt;SELECT * FROM ORDERS WHERE NVL(APPROVE_DATE, '01-JAN-1900') = '01-JAN-1900'&lt;br /&gt;&lt;br /&gt;Is this a correct approach ?&lt;br /&gt;&lt;br /&gt;Thank you,&lt;br /&gt;xtanto&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is what i gave in reply. I prepared a simple test case to show that an index be USED as well as IGNORED.&lt;br /&gt;&lt;br /&gt;A SQL_TRACE output will explain clearly what Justin has stated.&lt;br /&gt;&lt;br /&gt;I have created a table T based on all_objects.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; desc t&lt;br /&gt; Name                                      Null?    Type&lt;br /&gt; ----------------------------------------- -------- -----------------------&lt;br /&gt; OWNER                                     NOT NULL VARCHAR2(30)&lt;br /&gt; OBJECT_NAME                               NOT NULL VARCHAR2(30)&lt;br /&gt; SUBOBJECT_NAME                                     VARCHAR2(30)&lt;br /&gt; OBJECT_ID                                 NOT NULL NUMBER&lt;br /&gt; DATA_OBJECT_ID                                     NUMBER&lt;br /&gt; OBJECT_TYPE                                        VARCHAR2(19)&lt;br /&gt; CREATED                                            DATE&lt;br /&gt; LAST_DDL_TIME                             NOT NULL DATE&lt;br /&gt; TIMESTAMP                                          VARCHAR2(19)&lt;br /&gt; STATUS                                             VARCHAR2(7)&lt;br /&gt; TEMPORARY                                          VARCHAR2(1)&lt;br /&gt; GENERATED                                          VARCHAR2(1)&lt;br /&gt; SECONDARY                                          VARCHAR2(1)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;CASE I&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select count(1) from t&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;    934320&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; select count(1) from t where created is null&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;      2376&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The number of null values in CREATED column is proportionately very small.&lt;br /&gt;&lt;br /&gt;Now i execute the query without function based index.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;select *&lt;br /&gt;  from t&lt;br /&gt; where created is null&lt;br /&gt; &lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.00       0.09          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch      160      0.04       0.10          0      12662          0        2376&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total      162      0.04       0.19          0      12662          0        2376&lt;br /&gt; &lt;br /&gt;Rows     Execution Plan&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;      0  SELECT STATEMENT   GOAL: ALL_ROWS&lt;br /&gt;   2376   TABLE ACCESS   GOAL: ANALYZED (FULL) OF 'T' (TABLE)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And here is the query that uses the function based index&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;select *&lt;br /&gt;  from t&lt;br /&gt; where nvl(created,to_date('01-01-1900','DD-MM-YYYY')) = to_date('01-01-1900','DD-MM-YYYY')&lt;br /&gt; &lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.01       0.00          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch      160      0.01       0.01          0        698          0        2376&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total      162      0.03       0.01          0        698          0        2376&lt;br /&gt; &lt;br /&gt;Rows     Execution Plan&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;      0  SELECT STATEMENT   GOAL: ALL_ROWS&lt;br /&gt;   2376   TABLE ACCESS   GOAL: ANALYZED (BY INDEX ROWID) OF 'T' (TABLE)&lt;br /&gt;   2376    INDEX   GOAL: ANALYZED (RANGE SCAN) OF 'T_FN_IDX' (INDEX)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Its very obvious from the above output that the Function Based Index as increased the performance.&lt;br /&gt;&lt;br /&gt;CASE II&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; select count(1) from t&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;    934320&lt;br /&gt; &lt;br /&gt;SQL&amp;gt; select count(1) from t where created is null&lt;br /&gt;  2  / &lt;br /&gt; &lt;br /&gt;  COUNT(1)&lt;br /&gt;----------&lt;br /&gt;    202168&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now the null values in the CREATED column is proportionately large than the first test case.&lt;br /&gt;&lt;br /&gt;Now lets see without using the function based index&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;select *&lt;br /&gt;  from t&lt;br /&gt; where created is null&lt;br /&gt; &lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch    13479      0.46       0.71          2      25832          0      202168&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total    13481      0.46       0.71          2      25832          0      202168&lt;br /&gt; &lt;br /&gt;Rows     Execution Plan&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;      0  SELECT STATEMENT   GOAL: ALL_ROWS&lt;br /&gt; 202168   TABLE ACCESS   GOAL: ANALYZED (FULL) OF 'T' (TABLE)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now iam trying to use the function based index&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;select *&lt;br /&gt;  from t&lt;br /&gt; where nvl(created,to_date('01-01-1900','DD-MM-YYYY')) = to_date('01-01-1900','DD-MM-YYYY')&lt;br /&gt; &lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch    13479      0.54       0.84          0      33826          0      202168&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total    13481      0.54       0.84          0      33826          0      202168&lt;br /&gt; &lt;br /&gt;Rows     Execution Plan&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;      0  SELECT STATEMENT   GOAL: ALL_ROWS&lt;br /&gt; 202168   TABLE ACCESS   GOAL: ANALYZED (FULL) OF 'T' (TABLE)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Its obvious from the result that oracle has decided to go for a FULL TABLE SCAN even when an index was available.&lt;br /&gt;&lt;br /&gt;So just having a function based index is not going to increase the query performance. There are lot of other factors to be considered as stated above.&lt;br /&gt;&lt;br /&gt;The original link to the OTN Thread is&lt;br /&gt;&lt;br /&gt;http://forums.oracle.com/forums/thread.jspa?threadID=825995&amp;tstart=0&lt;br /&gt;&lt;br /&gt;Thanks,&lt;br /&gt;Karthick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-5211268698540838991?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/5211268698540838991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=5211268698540838991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/5211268698540838991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/5211268698540838991'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/11/index-is-not-all-god.html' title='Index is not all GOD'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-4839362196115006225</id><published>2008-07-02T02:45:00.000-07:00</published><updated>2008-07-02T02:49:02.512-07:00</updated><title type='text'>Loding XML using external table</title><content type='html'>A small example to load XML using external table.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; CREATE DIRECTORY my_xml_dir AS 'E:\oracle\Log_files\UTL_AKIVATST'&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;Directory created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; DROP TABLE my_xml_et&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;Table dropped.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; CREATE TABLE my_xml_et&lt;br /&gt;  2  (  EMPNO NUMBER,&lt;br /&gt;  3     EMPNAME VARCHAR2(10),&lt;br /&gt;  4     JOB VARCHAR2(10),&lt;br /&gt;  5     HIREDATE DATE,&lt;br /&gt;  6     SAL NUMBER&lt;br /&gt;  7  )&lt;br /&gt;  8  ORGANIZATION EXTERNAL&lt;br /&gt;  9  (&lt;br /&gt; 10     TYPE ORACLE_LOADER&lt;br /&gt; 11     DEFAULT DIRECTORY my_xml_dir&lt;br /&gt; 12     ACCESS PARAMETERS&lt;br /&gt; 13     (&lt;br /&gt; 14             records delimited by &amp;quot;&amp;lt;/EMP&amp;gt;&amp;quot;&lt;br /&gt; 15             badfile my_xml_dir:'empxt%a_%p.bad'&lt;br /&gt; 16             logfile my_xml_dir:'empxt%a_%p.log'&lt;br /&gt; 17             FIELDS&lt;br /&gt; 18             (&lt;br /&gt; 19                     filler            char(2000) terminated by &amp;quot;&amp;lt;EMP&amp;gt;&amp;quot;,&lt;br /&gt; 20                     EMPNO             char(2000) enclosed by &amp;quot;&amp;lt;EMPNO&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/EMPNO&amp;gt;&amp;quot;,&lt;br /&gt; 21                     EMPNAME           char(2000) enclosed by &amp;quot;&amp;lt;ENAME&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/ENAME&amp;gt;&amp;quot;,&lt;br /&gt; 22                     JOB               char(2000) enclosed by &amp;quot;&amp;lt;JOB&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/JOB&amp;gt;&amp;quot;,&lt;br /&gt; 23                     HIREDATE          char(2000) enclosed by &amp;quot;&amp;lt;HIREDATE&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/HIREDATE&amp;gt;&amp;quot;,&lt;br /&gt; 24                     SAL               char(2000) enclosed by &amp;quot;&amp;lt;SAL&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/SAL&amp;gt;&amp;quot;&lt;br /&gt; 25             )&lt;br /&gt; 26     )&lt;br /&gt; 27     LOCATION ('emp.xml')&lt;br /&gt; 28  )&lt;br /&gt; 29  PARALLEL&lt;br /&gt; 30  REJECT LIMIT UNLIMITED&lt;br /&gt; 31  /&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; SELECT * FROM my_xml_et&lt;br /&gt;  2  /&lt;br /&gt;&lt;br /&gt;     EMPNO EMPNAME    JOB        HIREDATE         SAL&lt;br /&gt;---------- ---------- ---------- --------- ----------&lt;br /&gt;      7369 SMITH      CLERK      17-DEC-80        800&lt;br /&gt;      7499 ALLEN      SALESMAN   20-FEB-81       1600&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is the sample XML that i used.&lt;br /&gt;&lt;br /&gt;emp.xml&lt;br /&gt;----------------&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;EMPLOYEES&amp;gt;&lt;br /&gt;&amp;lt;EMP&amp;gt;&lt;br /&gt;&amp;lt;EMPNO&amp;gt;7369&amp;lt;/EMPNO&amp;gt;&lt;br /&gt;&amp;lt;ENAME&amp;gt;SMITH&amp;lt;/ENAME&amp;gt;&lt;br /&gt;&amp;lt;JOB&amp;gt;CLERK&amp;lt;/JOB&amp;gt;&lt;br /&gt;&amp;lt;HIREDATE&amp;gt;17-DEC-80&amp;lt;/HIREDATE&amp;gt;&lt;br /&gt;&amp;lt;SAL&amp;gt;800&amp;lt;/SAL&amp;gt;&lt;br /&gt;&amp;lt;/EMP&amp;gt;&lt;br /&gt;&amp;lt;EMP&amp;gt;&lt;br /&gt;&amp;lt;EMPNO&amp;gt;7499&amp;lt;/EMPNO&amp;gt;&lt;br /&gt;&amp;lt;ENAME&amp;gt;ALLEN&amp;lt;/ENAME&amp;gt;&lt;br /&gt;&amp;lt;JOB&amp;gt;SALESMAN&amp;lt;/JOB&amp;gt;&lt;br /&gt;&amp;lt;HIREDATE&amp;gt;20-FEB-81&amp;lt;/HIREDATE&amp;gt;&lt;br /&gt;&amp;lt;SAL&amp;gt;1600&amp;lt;/SAL&amp;gt;&lt;br /&gt;&amp;lt;COMM&amp;gt;300&amp;lt;/COMM&amp;gt;&lt;br /&gt;&amp;lt;/EMP&amp;gt;&lt;br /&gt;&amp;lt;/EMPLOYEES&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-4839362196115006225?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/4839362196115006225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=4839362196115006225' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/4839362196115006225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/4839362196115006225'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/07/loding-xml-using-external-table.html' title='Loding XML using external table'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-8515403526558905890</id><published>2008-06-18T03:12:00.000-07:00</published><updated>2008-06-18T03:18:59.889-07:00</updated><title type='text'>Find out Blocking Session</title><content type='html'>I came across this pieace of code in Oracle form which helps us to find the blocking sessions. I tought of sharing it here.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; SET ECHO OFF&lt;br /&gt;SQL&amp;gt; SET LINE 10000&lt;br /&gt;SQL&amp;gt; COLUMN BLOCKER FORMAT A11;&lt;br /&gt;SQL&amp;gt; COLUMN BLOCKEE FORMAT A10;&lt;br /&gt;SQL&amp;gt; COLUMN SID FORMAT 99999;&lt;br /&gt;SQL&amp;gt; COLUMN BLOCKER_MODULE FORMAT A15 TRUNC;&lt;br /&gt;SQL&amp;gt; COLUMN BLOCKEE_MODULE FORMAT A15 TRUNC;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;SQL&amp;gt; ALTER SESSION SET OPTIMIZER_MODE=RULE;&lt;br /&gt;&lt;br /&gt;Session altered.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;SQL&amp;gt;  SELECT a.inst_id,&lt;br /&gt;  2     (SELECT username FROM gv$session s WHERE s.inst_id=a.inst_id AND s.sid=a.sid) blocker,&lt;br /&gt;  3     a.sid,&lt;br /&gt;  4     (SELECT module FROM gv$session s WHERE s.inst_id=a.inst_id AND s.sid=a.sid) blocker_module ,&lt;br /&gt;  5     ' is blocking ' &amp;quot;IS BLOCKING&amp;quot;,&lt;br /&gt;  6     b.inst_id,&lt;br /&gt;  7     (SELECT username FROM gv$session s WHERE s.inst_id=b.inst_id AND s.sid=b.sid) blockee,&lt;br /&gt;  8     b.sid ,&lt;br /&gt;  9     (SELECT module FROM gv$session s WHERE s.inst_id=b.inst_id AND s.sid=b.sid) blockee_module&lt;br /&gt; 10     FROM gv$lock a, gv$lock b&lt;br /&gt; 11    where a.block &amp;lt;&amp;gt;0&lt;br /&gt; 12      AND b.request &amp;gt; 0&lt;br /&gt; 13      AND a.id1 = b.id1&lt;br /&gt; 14      AND a.id2 = b.id2&lt;br /&gt; 15      AND a.sid &amp;lt;&amp;gt; b.sid&lt;br /&gt; 16    order by 1, 2&lt;br /&gt; 17  /&lt;br /&gt;&lt;br /&gt;   INST_ID BLOCKER        SID BLOCKER_MODULE  IS BLOCKING      INST_ID BLOCKEE       SID BLOCKEE_MODULE&lt;br /&gt;---------- ----------- ------ --------------- ------------- ---------- ---------- ------ ---------------&lt;br /&gt;         1 SYSADM          15 SQL*Plus         is blocking           1 SYSADM         11 T.O.A.D.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;SQL&amp;gt; ALTER SESSION SET OPTIMIZER_MODE=CHOOSE;&lt;br /&gt;&lt;br /&gt;Session altered.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; BEGIN&lt;br /&gt;  2     dbms_output.enable(1000000);&lt;br /&gt;  3     FOR do_loop IN (SELECT session_id, a.object_id, xidsqn, oracle_username, b.owner owner,&lt;br /&gt;  4                                                b.object_name object_name, b.object_type object_type&lt;br /&gt;  5                                       FROM v$locked_object a, dba_objects b&lt;br /&gt;  6                                      WHERE xidsqn != 0&lt;br /&gt;  7                                        and b.object_id = a.object_id)&lt;br /&gt;  8     LOOP&lt;br /&gt;  9             dbms_output.put_line('.');&lt;br /&gt; 10             dbms_output.put_line('Blocking Session   : '&amp;#124;&amp;#124;do_loop.session_id);&lt;br /&gt; 11             dbms_output.put_line('Object (Owner/Name): '&amp;#124;&amp;#124;do_loop.owner&amp;#124;&amp;#124;'.'&amp;#124;&amp;#124;do_loop.object_name);&lt;br /&gt; 12             dbms_output.put_line('Object Type        : '&amp;#124;&amp;#124;do_loop.object_type);&lt;br /&gt; 13             FOR next_loop IN (SELECT sid&lt;br /&gt; 14                                                 FROM v$lock&lt;br /&gt; 15                                                WHERE id2 = do_loop.xidsqn&lt;br /&gt; 16                                                  AND sid != do_loop.session_id)&lt;br /&gt; 17             LOOP&lt;br /&gt; 18                     dbms_output.put_line('Sessions being blocked   :  '&amp;#124;&amp;#124;next_loop.sid);&lt;br /&gt; 19             END LOOP;&lt;br /&gt; 20     END LOOP;&lt;br /&gt; 21  END;&lt;br /&gt; 22  /&lt;br /&gt;.&lt;br /&gt;Blocking Session   : 15&lt;br /&gt;Object (Owner/Name): SYSADM.T&lt;br /&gt;Object Type        : TABLE&lt;br /&gt;Sessions being blocked   :  11&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-8515403526558905890?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/8515403526558905890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=8515403526558905890' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8515403526558905890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8515403526558905890'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/06/find-out-blocking-session.html' title='Find out Blocking Session'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-3800127469984087550</id><published>2008-06-16T03:48:00.000-07:00</published><updated>2008-06-16T03:49:52.778-07:00</updated><title type='text'>Lesson for the day</title><content type='html'>With cost based optimizer if you don’t collect statistics properly then it means that you are screwed.&lt;br /&gt;&lt;br /&gt;This is what I did.&lt;br /&gt;&lt;br /&gt;Connected to:&lt;br /&gt;Oracle9i Enterprise Edition Release 9.2.0.1.0 - 64bit Production&lt;br /&gt;With the Partitioning, OLAP and Oracle Data Mining options&lt;br /&gt;JServer Release 9.2.0.1.0 - Production&lt;br /&gt;&lt;br /&gt;I created the following table.&lt;br /&gt;&lt;br /&gt;SQL&gt; create table hx_index_test_tbl(&lt;br /&gt;  2  no integer not null,&lt;br /&gt;  3  name varchar2(50) not null,&lt;br /&gt;  4  old_value varchar2(100),&lt;br /&gt;  5  new_value varchar2(100));&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;Next I added these two indexes to the table.&lt;br /&gt;&lt;br /&gt;SQL&gt; create index hx_index_test_tbl_idx on hx_index_test_tbl(name,no);&lt;br /&gt;&lt;br /&gt;Index created.&lt;br /&gt;&lt;br /&gt;SQL&gt; create index hx_index_test_tbl_idx_001 on hx_index_test_tbl(name);&lt;br /&gt;&lt;br /&gt;Index created.&lt;br /&gt;&lt;br /&gt;Then I populated some data.&lt;br /&gt;&lt;br /&gt;SQL&gt; insert into hx_index_test_tbl&lt;br /&gt;  2  select row_number() over(partition by name order by 1) no, name, rpad('*',100,'*') old_value, rpad('*',100,'*') new_value&lt;br /&gt;  3    from (select 'A'mod(level,100) name from dual connect by level &lt;=1000);&lt;br /&gt;&lt;br /&gt;1000 rows created.&lt;br /&gt;&lt;br /&gt;SQL&gt; commit;&lt;br /&gt;&lt;br /&gt;Commit complete.&lt;br /&gt;&lt;br /&gt;Got the statistics gathered.&lt;br /&gt;&lt;br /&gt;SQL&gt; exec dbms_stats.gather_table_stats(user,'hx_index_test_tbl',method_opt=&gt;'for all indexed columns');&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&gt; set serveroutput on&lt;br /&gt;SQL&gt; set autotrace traceonly explain&lt;br /&gt;SQL&gt; select * from hx_index_test_tbl where name = 'A0';&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=10 Bytes=1000)&lt;br /&gt;   1    0   TABLE ACCESS (FULL) OF 'HX_INDEX_TEST_TBL' (Cost=5 Card=10 Bytes=1000)&lt;br /&gt;  &lt;br /&gt;Oops its going for a full scan. It’s not considering my index. I want it to pick up the index HX_INDEX_TEST_TBL_IDX_001.&lt;br /&gt;&lt;br /&gt;SQL&gt; select * from hx_index_test_tbl where name = 'A0' and no = 1;&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=100)&lt;br /&gt;   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'HX_INDEX_TEST_TBL' (Cost=2 Card=1 Bytes=100)&lt;br /&gt;   2    1     INDEX (RANGE SCAN) OF 'HX_INDEX_TEST_TBL_IDX' (NON-UNIQUE) (Cost=1 Card=1)&lt;br /&gt;  &lt;br /&gt;But when I add no in the where clause its considering the index why is it so???&lt;br /&gt;&lt;br /&gt;The reason is very simple. See how I have gathered statistics.&lt;br /&gt;&lt;br /&gt;dbms_stats.gather_table_stats(user,'hx_index_test_tbl',method_opt=&gt;'for all indexed columns');&lt;br /&gt;&lt;br /&gt;I forgot to gather for Index of this table. Now let me gather for the index of this table also.&lt;br /&gt;&lt;br /&gt;SQL&gt; EXEC dbms_stats.gather_table_stats(user,'hx_index_test_tbl',method_opt=&gt;'for all indexed columns', &lt;strong&gt;cascade=&gt;TRUE&lt;/strong&gt;);&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;Now see what happens...&lt;br /&gt;&lt;br /&gt;SQL&gt; select * from hx_index_test_tbl where name = 'A0';&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=10 Bytes=1000)&lt;br /&gt;   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'HX_INDEX_TEST_TBL' (Cost=2 Card=10 Bytes=1000)&lt;br /&gt;   2    1     INDEX (RANGE SCAN) OF 'HX_INDEX_TEST_TBL_IDX_001' (NON-UNIQUE) (Cost=1 Card=10)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So if you don’t gather stats properly with cost based optimizer you will get weird execution plans.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-3800127469984087550?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/3800127469984087550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=3800127469984087550' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/3800127469984087550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/3800127469984087550'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/06/lesson-for-day.html' title='Lesson for the day'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-8726236850878330103</id><published>2008-06-09T23:10:00.000-07:00</published><updated>2009-05-07T03:53:08.738-07:00</updated><title type='text'>String List</title><content type='html'>Being a PLSQL developer many a times I have been in a situation where I would get list of values as input in a string and have to check if they exist in a particular table. The values would be separated by a delimiter. Let’s consider the below example&lt;br /&gt;&lt;br /&gt;String Input:  ‘ORACLE, SQL SERVER, DB2, MYSQL, SYBASE’&lt;br /&gt;&lt;br /&gt;I have to use this string to see if these values exist in the table.&lt;br /&gt;&lt;br /&gt;One possible way is to build a dynamic SQL. Just pad single quotes before and after each value in the string and build a SQL with the IN clause. But I want to do it without a dynamic SQL. How is this possible?&lt;br /&gt;&lt;br /&gt;I came up with this SQL which splits this string and gives me the values in the string as rows.&lt;br /&gt;&lt;br /&gt;Here is the SQL…&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; var a varchar2(100)&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec :a := 'ORACLE, SQL SERVER, DB2, MYSQL, SYBASE'&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;  SELECT TRIM(SUBSTR(:a, INSTR(','||:a,',',1,level), INSTR(:a||',',',',1,level) - INSTR(','||:a,',',1,level))) my_list&lt;br /&gt;  2        FROM dual, (SELECT length(replace(translate(lower(:a)||',','abcdefghijklmnopqrstuvwxyz1234567890',' '),' ','')) cnt&lt;br /&gt;  3                                    FROM dual)&lt;br /&gt;  4  CONNECT BY level &amp;lt;= cnt&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;MY_LIST&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;ORACLE&lt;br /&gt;SQL SERVER&lt;br /&gt;DB2&lt;br /&gt;MYSQL&lt;br /&gt;SYBASE&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So what have I done here? Let me split it into steps for your understanding.&lt;br /&gt;&lt;br /&gt;1.       I am identifying the possible letters that would appear in the values and translating them into blank space. Following command does that for me.&lt;br /&gt;       &lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; SELECT translate(lower(:a)||',','abcdefghijklmnopqrstuvwxyz1234567890',' ') val&lt;br /&gt;   2       FROM dual;&lt;br /&gt;&lt;br /&gt;VAL&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt; ,  , , ,  ,&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you can see I don’t have anything other than comma (The delimiter).&lt;br /&gt;&lt;br /&gt;2.       Now I am going to remove all the blank space from the output that I got in step 1.&lt;br /&gt;       &lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; SELECT replace(translate(lower(:a)||',','abcdefghijklmnopqrstuvwxyz1234567890',' '),' ','') val         &lt;br /&gt;   2      FROM dual;&lt;br /&gt;&lt;br /&gt;VAL&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;,,,,,&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now the length of the output will give me the total number of values in the list. Note that I have padded a extra comma to the string as the number of delimiter is always less than the number of values by one.&lt;br /&gt;&lt;br /&gt;3.       So the third step is obviously to count the number of comma in the above input and determine total number of values in the string list.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; SELECT length(replace(translate(lower(:a)||',','abcdefghijklmnopqrstuvwxyz1234567890',' '),' ','')) cnt&lt;br /&gt;  2       FROM dual&lt;br /&gt;  3  /&lt;br /&gt;&lt;br /&gt;       CNT&lt;br /&gt;----------&lt;br /&gt;            5&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4.       Next step is to generate the string list for 5 times in rows using the CONNECT BY clause.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt; SELECT level, :a my_list&lt;br /&gt;  2       FROM dual, (SELECT length(replace(translate(lower(:a)||',','abcdefghijklmnopqrstuvwxyz1234567890',' '),' ','')) cnt&lt;br /&gt;  3                               FROM dual)&lt;br /&gt;  4  CONNECT BY level &amp;lt;= cnt&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;     LEVEL MY_LIST&lt;br /&gt;---------- ---------------------------------------------------------------------------------------------------------------&lt;br /&gt;         1 ORACLE, SQL SERVER, DB2, MYSQL, SYBASE&lt;br /&gt;         2 ORACLE, SQL SERVER, DB2, MYSQL, SYBASE&lt;br /&gt;         3 ORACLE, SQL SERVER, DB2, MYSQL, SYBASE&lt;br /&gt;         4 ORACLE, SQL SERVER, DB2, MYSQL, SYBASE&lt;br /&gt;         5 ORACLE, SQL SERVER, DB2, MYSQL, SYBASE&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5.       Now its simple with the help of SUBSTR and INSTR I can split each values as shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt;  SELECT TRIM(SUBSTR(:a, INSTR(','||:a,',',1,level), INSTR(:a||',',',',1,level) - INSTR(',':a,',',1,level))) my_list&lt;br /&gt;  2        FROM dual, (SELECT length(replace(translate(lower(:a)',','abcdefghijklmnopqrstuvwxyz1234567890',' '),' ','')) cnt&lt;br /&gt;  3                            FROM dual)&lt;br /&gt;  4  CONNECT BY level &amp;lt;= cnt&lt;br /&gt;  5  /&lt;br /&gt;&lt;br /&gt;MY_LIST&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;ORACLE&lt;br /&gt;SQL SERVER&lt;br /&gt;DB2&lt;br /&gt;MYSQL&lt;br /&gt;SYBASE&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now I can use this SQL to convert any value list into rows and use in my SQL statements.&lt;br /&gt;&lt;br /&gt;And if you can use Regular expression things can be much more easier.&lt;br /&gt;&lt;br /&gt;Check this out.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SQL&amp;gt;  SELECT trim(regexp_substr(:a,'[^,]+', 1, level)) my_list&lt;br /&gt;  2     FROM dual&lt;br /&gt;  3  CONNECT BY level &amp;lt;= NVL( LENGTH( REGEXP_REPLACE( :a, '[^,]+', NULL ) ), 0 ) + 1&lt;br /&gt;  4  /&lt;br /&gt;&lt;br /&gt;MY_LIST&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;ORACLE&lt;br /&gt;SQL SERVER&lt;br /&gt;DB2&lt;br /&gt;MYSQL&lt;br /&gt;SYBASE&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;NOTE: This might need have to be customized based on the given requirement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-8726236850878330103?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/8726236850878330103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=8726236850878330103' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8726236850878330103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8726236850878330103'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/06/string-list.html' title='String List'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-2125663657622796240</id><published>2008-06-02T22:32:00.000-07:00</published><updated>2008-06-02T22:36:16.607-07:00</updated><title type='text'>Code reusability in oracle pl/sql</title><content type='html'>Again today when checking out tom’s blog I lead me to &lt;a href="http://tylermuth.wordpress.com/2008/06/01/reusable-plsql/"&gt;this &lt;/a&gt; post in Tayler Muth’s Blog. This sounds to be an interesting topic. So I thought for a while and this is what came up to my mind…&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Code reusability in oracle pl/sql&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;First to start with pl/sql is procedural language which is not object oriented. Once said that it implies that this language is not familiar with the concept of inheritance. I have been using pl/sql for quite some time. It’s a great programming language. It would be even better if it had the class concept in it.&lt;br /&gt;&lt;br /&gt;Class concept would come handy when we want to build a framework which can be utilized over and over.&lt;br /&gt;&lt;br /&gt;Currently I am working on a masking utility. We have different masking algorithms say…&lt;br /&gt;&lt;br /&gt;Algorithm 1, Algorithm 2, Algorithm 3 etc.&lt;br /&gt;&lt;br /&gt;The general framework of this masking is something like this.&lt;br /&gt;&lt;br /&gt;1.       Get the field from user which needs to be masked.&lt;br /&gt;2.       Get the master table for that field.&lt;br /&gt;3.       Load the distinct data for the field from master table into a staging table&lt;br /&gt;4.       Apply your masking logic on the staging table.&lt;br /&gt;5.       Find all the transaction tables that have this field in it.&lt;br /&gt;6.       Using the staging table update all the transaction table.&lt;br /&gt;&lt;br /&gt;Here this is a very good candidate for class concept where I can have a parent class which will have the entire frame work of what I have given in six steps. And I can have one child class for each algorithm and in each child class I can just over write the step four where I can apply my masking algorithm. But unfortunately we don’t have it. Hence I went for package, Use some CASE statements and hooked in my algorithms and made it as optimal as possible. I basically hate writing lot of code. If Oracle can introduce OOP(Object Oriented Programming) in PL/SQL it would be of great use and even more flexible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-2125663657622796240?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/2125663657622796240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=2125663657622796240' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2125663657622796240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2125663657622796240'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/06/code-reusability-in-oracle-plsql.html' title='Code reusability in oracle pl/sql'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-9112805134036969035</id><published>2008-05-15T23:39:00.000-07:00</published><updated>2008-05-15T23:50:49.141-07:00</updated><title type='text'>Read Only Table.</title><content type='html'>I saw &lt;a href="http://richardfoote.wordpress.com/2008/05/15/read-only-table-before-11g-a-day-in-the-life/"&gt;this&lt;/a&gt; post on Richard foote's blog which pointed me to &lt;a href="http://forums.oracle.com/forums/thread.jspa?threadID=655417&amp;amp;tstart=50"&gt;this&lt;/a&gt; otn thread.&lt;br /&gt;&lt;br /&gt;So i gave it a try. This is what i did.&lt;br /&gt;&lt;br /&gt;Say I have a table as given below in production.&lt;br /&gt;&lt;br /&gt;SQL&gt; CREATE TABLE hx_my_read_only_table (no INTEGER CHECK(NO&gt;0), name VARCHAR2(100));&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO hx_my_read_only_table VALUES(1,'KARTHICK');&lt;br /&gt;&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO hx_my_read_only_table VALUES(2,'VIMAL');&lt;br /&gt;&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO hx_my_read_only_table VALUES(3,'VIJAY');&lt;br /&gt;&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;SQL&gt; COMMIT;&lt;br /&gt;&lt;br /&gt;Commit complete.&lt;br /&gt;&lt;br /&gt;SQL&gt; SELECT * FROM hx_my_read_only_table;&lt;br /&gt;&lt;br /&gt;        NO NAME&lt;br /&gt;---------- --------------------------------------------------------------------------------       &lt;br /&gt; 1 KARTHICK        &lt;br /&gt;2 VIMAL       &lt;br /&gt; 3 VIJAY&lt;br /&gt;&lt;br /&gt;And I want to make it read only. I will use ACCESS CONTROL to achieve it.&lt;br /&gt;&lt;br /&gt;SQL&gt; CREATE CONTEXT hx_my_context USING hx_my_pkg;&lt;br /&gt;&lt;br /&gt;Context created.&lt;br /&gt;&lt;br /&gt;SQL&gt; CREATE OR REPLACE PACKAGE hx_my_pkg &lt;br /&gt;2  AS &lt;br /&gt;3     PROCEDURE hx_set_context ( &lt;br /&gt;4                     hx_p_fld VARCHAR2, &lt;br /&gt;5                     hx_p_value VARCHAR2); &lt;br /&gt;6 &lt;br /&gt;7     FUNCTION hx_get_val (&lt;br /&gt;8                      hx_p_fld varchar2) RETURN NUMBER;&lt;br /&gt;9&lt;br /&gt;10     FUNCTION hx_get_key(&lt;br /&gt;11                     p_schema in varchar2,&lt;br /&gt;12                     p_object in varchar2) RETURN VARCHAR2;&lt;br /&gt;13  END hx_my_pkg;&lt;br /&gt;14  /&lt;br /&gt;Package created.&lt;br /&gt;SQL&gt; CREATE OR REPLACE PACKAGE BODY hx_my_pkg &lt;br /&gt;2  AS &lt;br /&gt;3     PROCEDURE hx_set_context ( &lt;br /&gt;4                     hx_p_fld VARCHAR2, &lt;br /&gt;5                     hx_p_value VARCHAR2) &lt;br /&gt;6     IS &lt;br /&gt;7     BEGIN &lt;br /&gt;8             DBMS_SESSION.SET_CONTEXT('HX_MY_CONTEXT', hx_p_fld, hx_p_value); &lt;br /&gt;9     END;&lt;br /&gt;10&lt;br /&gt;11     FUNCTION hx_get_val (&lt;br /&gt;12                      hx_p_fld varchar2) RETURN NUMBER&lt;br /&gt;13     IS&lt;br /&gt;14     BEGIN&lt;br /&gt;15              RETURN SYS_CONTEXT('HX_MY_CONTEXT', hx_p_fld);&lt;br /&gt;16     END;&lt;br /&gt;17&lt;br /&gt;18     FUNCTION hx_get_key(&lt;br /&gt;19                     p_schema in varchar2,&lt;br /&gt;20                     p_object in varchar2) RETURN VARCHAR2&lt;br /&gt;21     IS&lt;br /&gt;22             lPredicate VARCHAR2 (2000);&lt;br /&gt;23     BEGIN&lt;br /&gt;24             lPredicate := 'NO = SYS_CONTEXT(''HX_MY_CONTEXT'', ''NO'')';&lt;br /&gt;25&lt;br /&gt;26             RETURN lPredicate;&lt;br /&gt;27     END;&lt;br /&gt;28&lt;br /&gt;29  END hx_my_pkg;&lt;br /&gt;30  /&lt;br /&gt;&lt;br /&gt;Package body created.&lt;br /&gt;&lt;br /&gt;SQL&gt; BEGIN &lt;br /&gt;2      DBMS_RLS.ADD_POLICY (USER, 'HX_MY_READ_ONLY_TABLE', 'HX_READ_ONLY_POLICY',USER, 'hx_my_pkg.hx_get_key', 'INSERT, UPDATE, DELETE' ); &lt;br /&gt;3  END; &lt;br /&gt;4  /&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&gt; BEGIN &lt;br /&gt;2      hx_my_pkg.hx_set_context('NO',0); &lt;br /&gt;3  END; &lt;br /&gt;4  /&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&gt; UPDATE hx_my_read_only_table &lt;br /&gt;2     SET NAME = 'RICHARD' &lt;br /&gt;3   WHERE NO = 1;&lt;br /&gt;&lt;br /&gt;0 rows updated.&lt;br /&gt;&lt;br /&gt;SQL&gt; DELETE FROM hx_my_read_only_table;&lt;br /&gt;&lt;br /&gt;0 rows deleted.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO hx_my_read_only_table VALUES(4,'RICHARD');&lt;br /&gt;&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;I was expecting this one not to insert record. I have to see what the problem is.&lt;br /&gt;&lt;br /&gt;SQL&gt; ROLLBACK;&lt;br /&gt;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;br /&gt;Mean while I restricted the insert by with this trigger. I personally hate triggers but....&lt;br /&gt;&lt;br /&gt;SQL&gt; CREATE OR REPLACE TRIGGER hx_my_trigger BEFORE INSERT ON hx_my_read_only_table FOR EACH ROW &lt;br /&gt;2  BEGIN &lt;br /&gt;3      IF :NEW.NO &lt;&gt; hx_my_pkg.hx_get_val('NO') &lt;br /&gt;4      THEN &lt;br /&gt;5              RAISE_APPLICATION_ERROR(-20001, 'Insert Not possible...'); &lt;br /&gt;6      END IF; &lt;br /&gt;7  END; &lt;br /&gt;8  /&lt;br /&gt;&lt;br /&gt;Trigger created.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO hx_my_read_only_table VALUES(4,'RICHARD');&lt;br /&gt;&lt;br /&gt;INSERT INTO hx_my_read_only_table VALUES(4,'RICHARD') &lt;br /&gt; *&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-20001: Insert Not possible...&lt;br /&gt;ORA-06512: at "SYSADM.HX_MY_TRIGGER", line 4&lt;br /&gt;ORA-04088: error during execution of trigger 'SYSADM.HX_MY_TRIGGER'&lt;br /&gt;&lt;br /&gt;So i have Restricted INSERT, UPDATE, DELETE on this table.&lt;br /&gt;&lt;br /&gt;SQL&gt; SELECT * FROM HX_MY_READ_ONLY_TABLE;&lt;br /&gt;&lt;br /&gt;        NO NAME&lt;br /&gt;---------- --------------------------------------------------------------------------------        &lt;br /&gt;1 KARTHICK        &lt;br /&gt;2 VIMAL        &lt;br /&gt;3 VIJAY&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-9112805134036969035?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/9112805134036969035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=9112805134036969035' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/9112805134036969035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/9112805134036969035'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/05/read-only-table.html' title='Read Only Table.'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-2722431771128698468</id><published>2008-05-06T21:19:00.000-07:00</published><updated>2008-05-06T21:44:25.344-07:00</updated><title type='text'>The bridge is falling down.</title><content type='html'>Few days back tom wrote&lt;a href="http://tkyte.blogspot.com/2008/04/it-has-been-while.html"&gt; this &lt;/a&gt;in his blog. I felt there is lot of truth in it and was very happy to hear it from him. Today when I came into office the first mail I came across had these pictures.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://bp3.blogger.com/_jKncqkKIgbA/SCExmqqmSOI/AAAAAAAAAvg/ocsJsdGV0jk/s1600-h/ATT00073.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5197489985320012002" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp3.blogger.com/_jKncqkKIgbA/SCExmqqmSOI/AAAAAAAAAvg/ocsJsdGV0jk/s400/ATT00073.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://bp2.blogger.com/_jKncqkKIgbA/SCEx6aqmSQI/AAAAAAAAAvw/3DqvFQkqH6o/s1600-h/ATT00094.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5197490324622428418" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp2.blogger.com/_jKncqkKIgbA/SCEx6aqmSQI/AAAAAAAAAvw/3DqvFQkqH6o/s400/ATT00094.jpg" border="0" /&gt;&lt;/a&gt;&lt;a href="http://bp0.blogger.com/_jKncqkKIgbA/SCExe6qmSNI/AAAAAAAAAvY/BOo1Z0VfBxw/s1600-h/ATT00070.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5197489852176025810" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp0.blogger.com/_jKncqkKIgbA/SCExe6qmSNI/AAAAAAAAAvY/BOo1Z0VfBxw/s400/ATT00070.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_jKncqkKIgbA/SCEuzqqmSLI/AAAAAAAAAvI/WUrJ2u62nlk/s1600-h/ATT00085.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_jKncqkKIgbA/SCExt6qmSPI/AAAAAAAAAvo/lLyWvBXFNUA/s1600-h/ATT00091.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5197490109874063602" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp0.blogger.com/_jKncqkKIgbA/SCExt6qmSPI/AAAAAAAAAvo/lLyWvBXFNUA/s400/ATT00091.jpg" border="0" /&gt;&lt;/a&gt;This one is an unacceptable construction flaw. The mail said it has happened in Korea. Such thing may be very… very… rare event in construction business. But here in software we see lots of bridges falling down every day. After seeing this I have started to worry even more about what he said.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-2722431771128698468?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/2722431771128698468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=2722431771128698468' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2722431771128698468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2722431771128698468'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/05/bridge-is-falling-down.html' title='The bridge is falling down.'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_jKncqkKIgbA/SCExmqqmSOI/AAAAAAAAAvg/ocsJsdGV0jk/s72-c/ATT00073.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-8328128935972654196</id><published>2008-05-06T00:08:00.000-07:00</published><updated>2008-05-06T02:42:16.584-07:00</updated><title type='text'>DML Error Logging in 10gR2</title><content type='html'>This is a cool stuff in oracle. I just tried it few days back and I was exited so thought of sharing it here.&lt;br /&gt;&lt;br /&gt;Have you ever stuck up with a bulk insert failing on a check constraint? In such a situation we spend most of our time trying to find out the culprit rows. Oracle has come up with a great stuff by which such rows can be logged separately without disturbing the valid rows.&lt;br /&gt;&lt;br /&gt;To put it straight by using the DML Error Logging feature you can just pick up all the invalid rows and put it separately and let the valid records go into the target table.Following is a small demonstration of this feature.&lt;br /&gt;&lt;br /&gt;This is the source table from which the data is going to be selected.&lt;br /&gt;&lt;br /&gt;SQL&gt; CREATE TABLE SOURCE(NO NUMBER, NAME VARCHAR2(100))&lt;br /&gt;2 /&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO SOURCE SELECT LEVEL, 'KARTHICK' FROM DUAL CONNECT BY LEVEL &lt;=15&lt;br /&gt;2 /&lt;br /&gt;&lt;br /&gt;15 rows created.&lt;br /&gt;&lt;br /&gt;This is the target table into which the data from the source table is going to be inserted.&lt;br /&gt;&lt;br /&gt;SQL&gt; CREATE TABLE TARGET(NO NUMBER, NAME VARCHAR2(100))&lt;br /&gt;2 /&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;I am creating a check constraint as follows&lt;br /&gt;&lt;br /&gt;SQL&gt; ALTER TABLE TARGET ADD CONSTRAINT SOURCE_CHK CHECK(NO &lt;10)&lt;br /&gt;2 /&lt;br /&gt;&lt;br /&gt;Table altered.&lt;br /&gt;&lt;br /&gt;Now let’s try to insert the source table data into target table.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO TARGET SELECT * FROM SOURCE;&lt;br /&gt;INSERT INTO TARGET SELECT * FROM SOURCE&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated&lt;br /&gt;&lt;br /&gt;As we have a check constraint on column TARGET.NO which says NO should be less than 10, if we have any row which does not satisfy this condition then the entire insert fails. But I want the valid rows to be inserted into my target table and all the invalid rows to be logged separately. I am going to achieve this using the DML Error Logging technique.&lt;br /&gt;&lt;br /&gt;To achieve that first we need to create a Error Log Table. The following command helps us in doing that.&lt;br /&gt;&lt;br /&gt;SQL&gt; BEGIN&lt;br /&gt;2 DBMS_ERRLOG.create_error_log (dml_table_name =&gt; 'TARGET');&lt;br /&gt;3 END;&lt;br /&gt;4 /&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;This creates a new error log table for our TARGET table. The error log table is described below&lt;br /&gt;&lt;br /&gt;SQL&gt; desc err$_TARGET;&lt;br /&gt;&lt;br /&gt;Name Null? Type&lt;br /&gt;----------------------------------------- -------- ----------------------------&lt;br /&gt;&lt;br /&gt;ORA_ERR_NUMBER$ NUMBER&lt;br /&gt;ORA_ERR_MESG$ VARCHAR2(2000)&lt;br /&gt;ORA_ERR_ROWID$ ROWID&lt;br /&gt;ORA_ERR_OPTYP$ VARCHAR2(2)&lt;br /&gt;ORA_ERR_TAG$ VARCHAR2(2000)&lt;br /&gt;NO VARCHAR2(4000)&lt;br /&gt;NAME VARCHAR2(4000)&lt;br /&gt;&lt;br /&gt;Now we need to use LOG ERROR INTO syntax in our INSERT INTO statement to log the error.&lt;br /&gt;&lt;br /&gt;SQL&gt; INSERT INTO TARGET SELECT * FROM SOURCE LOG ERRORS INTO err$_TARGET ('INSERT') REJECT LIMIT UNLIMITED&lt;br /&gt;2 /&lt;br /&gt;&lt;br /&gt;9 rows created.&lt;br /&gt;&lt;br /&gt;Now you can observe that of the 15 rows 9 rows that satisfy the check constraints are inserted into the TARGET table.So the invalid records will be logged into the Error Log table that we have created above. Let’s have a look into the error log table.&lt;br /&gt;&lt;br /&gt;SELECT * FROM ERR$_TARGET&lt;br /&gt;&lt;br /&gt;ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$ NO NAME&lt;br /&gt;--------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;2290 ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated I INSERT 10 KARTHICK&lt;br /&gt;2290 ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated I INSERT 11 KARTHICK&lt;br /&gt;2290 ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated I INSERT 12 KARTHICK&lt;br /&gt;2290 ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated I INSERT 13 KARTHICK&lt;br /&gt;2290 ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated I INSERT 14 KARTHICK&lt;br /&gt;2290 ORA-02290: check constraint (SYSADM.SOURCE_CHK) violated I INSERT 15 KARTHICK&lt;br /&gt;&lt;br /&gt;Now which this information we can easily start our trouble shooting to figure out why the rows failed the check constraint.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-8328128935972654196?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/8328128935972654196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=8328128935972654196' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8328128935972654196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8328128935972654196'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/05/dml-error-logging-in-10gr2.html' title='DML Error Logging in 10gR2'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-9079652925409386638</id><published>2008-05-01T22:37:00.000-07:00</published><updated>2008-05-01T22:40:41.560-07:00</updated><title type='text'>Do i need to repel?</title><content type='html'>I saw &lt;a href="http://tkyte.blogspot.com/2008/04/question-of-day.html"&gt;this&lt;/a&gt; posting by tom today. I felt like commenting it. And this is what i wrote.&lt;br /&gt;&lt;br /&gt;It is not most of the time "I don't know the answer" but its "I don't know the question".&lt;br /&gt;&lt;br /&gt;What I want?&lt;br /&gt;&lt;br /&gt;Almost and always in the programming world it’s not what I want, it’s what they want me to want. Unclear requirements we see it every day don't we.&lt;br /&gt;&lt;br /&gt;Why such questions?&lt;br /&gt;&lt;br /&gt;The inability to question the authority is what leads to such questions. Some of the questions asked may not be looking for the answer but may be in the phase of trying to understand what is needed. I know it’s a wrong (very... very...) approach. But in the practical world that’s the way it is.&lt;br /&gt;&lt;br /&gt;Don’t you here it?&lt;br /&gt;&lt;br /&gt;Do what I say...&lt;br /&gt;Don't do it that way, Do it my way...&lt;br /&gt;&lt;br /&gt;Do I need to repel?&lt;br /&gt;&lt;br /&gt;Is it right to say what you ask for just does not make any sense to me. If I tell that I know the next question (if the person sitting opposite to you is a genuine person) would be "Then tell me how it should be?” Do we really have answer at that moment is what matters. If we have then we may find a way out. But most of the time we know that something is wrong but we don’t know what is right. To find the right thing we need time. And that is what most of them don’t have with them. For all this as I said earlier the person should be genuine. What if he or she is a bossy person? It’s simple..."You are screwed up".&lt;br /&gt;&lt;br /&gt;So I feel such question is born not because "I don’t know what I want" but because "I don’t know what they want me to want".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-9079652925409386638?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/9079652925409386638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=9079652925409386638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/9079652925409386638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/9079652925409386638'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/05/do-i-need-to-repel.html' title='Do i need to repel?'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-2573595301543027509</id><published>2008-03-20T04:28:00.000-07:00</published><updated>2008-03-20T05:13:11.508-07:00</updated><title type='text'>Do you prefer to end up this way?</title><content type='html'>&lt;img id="BLOGGER_PHOTO_ID_5179795436397804978" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp3.blogger.com/_jKncqkKIgbA/R-JUgXOuPbI/AAAAAAAAAs0/isnPIqMwRRc/s400/untitled.bmp" border="0" /&gt;Think about it. I don't want to end up this way. Definitely not....&lt;br /&gt;&lt;br /&gt;Few days back we had a discussion on how to build a better team, of which one of the important aspects was communication between the team members. After seeing this article I am getting a strong feeling about it.&lt;br /&gt;&lt;br /&gt;There are situations where we don’t even know who the person sitting next to us. Yes that’s true. There could be several reasons for that. He may not be working on the same project on which you are. Or he may be into different technology.&lt;br /&gt;&lt;br /&gt;So one argument that rose during our discussion was if the person sitting next to us is not in your team or your project is it necessary to communicate with him (This opinion could differ based on out personal interest). I was taking the "Not necessary side".&lt;br /&gt;&lt;br /&gt;So if the person next to you is not in the same team as that of you then the question is why he is next to you? Again there could be several reasons for that. And we may not have control over those reasons.&lt;br /&gt;&lt;br /&gt;After seeing this article I am starting to feel it may be "Extremely necessary and important". So I think it’s totally up to us to decide on what to do. The organization can only create the atmosphere for us to mingle with one another but it can make us to.&lt;br /&gt;&lt;br /&gt;So I think we are the one who need to decide how much it is important.&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_jKncqkKIgbA/R-JLxXOuPaI/AAAAAAAAAss/Qq3ctTZoCb8/s1600-h/untitled.bmp"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-2573595301543027509?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/2573595301543027509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=2573595301543027509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2573595301543027509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2573595301543027509'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/03/what-do-you-get-after-all.html' title='Do you prefer to end up this way?'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_jKncqkKIgbA/R-JUgXOuPbI/AAAAAAAAAs0/isnPIqMwRRc/s72-c/untitled.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-5976426931273671434</id><published>2008-03-14T04:16:00.000-07:00</published><updated>2008-03-14T04:19:54.352-07:00</updated><title type='text'>How does it work? Does it matter!!!</title><content type='html'>&lt;span style="font-family:arial;"&gt;Ok as my profile says I am an oracle PL/SQL developer!!!&lt;br /&gt;&lt;br /&gt;That’s what I do for my living. I write code. That is all I do most of the time. I write some SQL or PL/SQL and throw it into the database. I have never cared about what oracle does with it. Why should I its oracles headache.&lt;br /&gt;&lt;br /&gt;To write a SQL all I need to know is the correct syntax. That’s all I don’t need any thing else. Even for that I have SQL Reference to help me. May be in need the ability to think in Set’s. So I know SET... I know what is a JOIN and UNION.&lt;br /&gt;&lt;br /&gt;Why should I care what oracle does with the SQL that I submitted. Why do I have to care about how it stores my data or how it gets me what I need? Why... we have the DBA guys to worry about that.&lt;br /&gt;&lt;br /&gt;Do you feel the same way as I did? Do you? I hope the answer is not YES if it is then you are going down, down from day one. Yes that’s right!! No second thoughts you are going down... Down to hell!!&lt;br /&gt;&lt;br /&gt;Have you heard about Bind Variables? If the answer is NO then you are not going down to hell as you are already living in there.&lt;br /&gt;&lt;br /&gt;To know the importance of Bind Variable it’s essential to know how Oracle Works. What it does with the so called sophisticated code that you wrote.&lt;br /&gt;&lt;br /&gt;Not only that, we need to know lot more. How the data are organized and stored, how they are retrieved. To put it in one word know the oracle database "Architecture".&lt;br /&gt;&lt;br /&gt;A nice place to start with would be here.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.ittoolbox.com/bi/confessions/archives/post-index-how-oracle-works-10605"&gt;http://blogs.ittoolbox.com/bi/confessions/archives/post-index-how-oracle-works-10605&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;I found it easy and interesting to read. The way the author has written is like a story narration. I like stories and "How oracle works" is a great story.&lt;br /&gt;&lt;br /&gt;Once you understand all of this you will really come to know how much of your code is actually sophisticated.&lt;br /&gt;&lt;br /&gt;So happy reading…&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-5976426931273671434?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/5976426931273671434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=5976426931273671434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/5976426931273671434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/5976426931273671434'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/03/how-does-it-work-does-it-matter.html' title='How does it work? Does it matter!!!'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-97959432830697256</id><published>2008-02-22T05:56:00.000-08:00</published><updated>2008-02-22T05:57:12.502-08:00</updated><title type='text'>It's the Initiation that matters...</title><content type='html'>Taking Initiation has always been my biggest problem. Because once I get started I put lot of effort and dedication into it to get it done and to do it in a nice way. But starting it is the biggest problem. By “It” I mean any thing and every thing.&lt;br /&gt;&lt;br /&gt;Take it to read some thing may be a book or to do a presentation or getting my ideas into execution. I always find it difficult to get that initial inspiration. Once it is there it’s always like sky is the limit. It starts to flow and I love it. I guess lots of people go through that state. Not sure if they do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-97959432830697256?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/97959432830697256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=97959432830697256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/97959432830697256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/97959432830697256'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/02/its-initiation-that-matters.html' title='It&apos;s the Initiation that matters...'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-8090757484124473552</id><published>2008-02-19T05:50:00.000-08:00</published><updated>2008-02-19T06:02:47.236-08:00</updated><title type='text'>Ask Tom</title><content type='html'>Ask tom (&lt;a href="http://asktom.oracle.com/"&gt;http://asktom.oracle.com&lt;/a&gt;) is a great place for oracle developers and DBA. You have so much in there. I would say it’s a repository of Knowledge about Oracle and in general Database.&lt;br /&gt;&lt;br /&gt;Today I wanted to write a small utility to export data from a table and put into a csv file. I just searched and got this great stuff from Ask Tom.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:68212348056"&gt;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:68212348056&lt;/a&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?=100:11:0::::P11_QUESTION_ID:68212348056"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dump_CSV is what all I wanted. Got it modified little bit to support my requirements. And in no time I was ready.&lt;br /&gt;&lt;br /&gt;In ask tom you not only get answers for your questions but also lot of alternatives. What is the best way to approach the problem and lot more?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-8090757484124473552?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/8090757484124473552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=8090757484124473552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8090757484124473552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/8090757484124473552'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/02/ask-tom.html' title='Ask Tom'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-6060618752315569824</id><published>2008-02-12T06:41:00.000-08:00</published><updated>2008-02-12T06:52:24.039-08:00</updated><title type='text'>Why do we need to follow coding standerds?</title><content type='html'>&lt;span style="font-family:arial;"&gt;Why do we need to follow coding standerds? Over a period of time i have been tought to follow certain coding standards. Mainly like&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;Local variable - Starts with l&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Global variables - Starts with g&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Parameter - Starts with p &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;and so on...&lt;br /&gt;&lt;br /&gt;Are these standards just to make our code look beautiful or are thes things our life savers. lets see a small example....&lt;br /&gt;&lt;br /&gt;sql&gt; create table hx_tmp(hx_val INTEGER);&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;sql&gt; insert into hx_tmp values (1);&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;sql&gt; insert into hx_tmp values (2);&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;sql&gt; commit;&lt;br /&gt;Commit complete.&lt;br /&gt;&lt;br /&gt;sql&gt; create or replace function hx_f (hx_val in integer) return integer&lt;br /&gt;2 as&lt;br /&gt;3 hx_out INTEGER := 0;&lt;br /&gt;4 begin&lt;br /&gt;5 select hx_val into hx_out from hx_tmp where hx_val = hx_val;&lt;br /&gt;6&lt;br /&gt;7 return hx_out;&lt;br /&gt;8 end;&lt;br /&gt;9 /&lt;br /&gt;Function created.&lt;br /&gt;&lt;br /&gt;sql&gt; variable a number&lt;br /&gt;&lt;br /&gt;sql&gt; exec :a := hx_f(2);&lt;br /&gt;BEGIN :a := hx_f(2); END;&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-01422: exact fetch returns more than requested number of rows&lt;br /&gt;ORA-06512: at "SYSADM.HX_F", line 5&lt;br /&gt;ORA-06512: at line 1&lt;br /&gt;&lt;br /&gt;Oooooops.....&lt;br /&gt;&lt;br /&gt;If you where expecting to get a result think again. This is all because i dint follow the coding standard that i was supposed to follow. So i was expecting that input value 2 will be passed to the SQL. But it did the other way. Its all because of bad way of coding.&lt;br /&gt;&lt;br /&gt;So conclution....&lt;br /&gt;&lt;br /&gt;Coding standards is not just to make your code look beautiful or understandable or maintanable or.... or..... or.... but also to make your code bug free.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-6060618752315569824?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/6060618752315569824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=6060618752315569824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/6060618752315569824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/6060618752315569824'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/02/why-do-we-need-to-follow-coding.html' title='Why do we need to follow coding standerds?'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4720517759143243102.post-2854367422764502459</id><published>2008-02-11T00:38:00.000-08:00</published><updated>2008-02-12T01:27:18.466-08:00</updated><title type='text'>Dynamic data modal sucks…</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Dynamic data modal sucks…&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I have always felt this. But people keep on asking for this.&lt;br /&gt;&lt;br /&gt;Dynamic data model…&lt;br /&gt;Unknown number of columns in a table…&lt;br /&gt;Store rows as columns…&lt;br /&gt;Store column as rows…&lt;br /&gt;Take transpose…&lt;br /&gt;Do all sort of nonsense…&lt;br /&gt;&lt;br /&gt;The outcome that I have found because of this is simple.&lt;br /&gt;&lt;br /&gt;Headache wile coding…&lt;br /&gt;Big headache wile debugging…&lt;br /&gt;Bigger headache wile tuning for performance…&lt;br /&gt;&lt;br /&gt;But people still want it and people still do it… &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4720517759143243102-2854367422764502459?l=karthickarp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://karthickarp.blogspot.com/feeds/2854367422764502459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4720517759143243102&amp;postID=2854367422764502459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2854367422764502459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4720517759143243102/posts/default/2854367422764502459'/><link rel='alternate' type='text/html' href='http://karthickarp.blogspot.com/2008/02/dynamic-data-modal-sucks.html' title='Dynamic data modal sucks…'/><author><name>Karthick.</name><uri>http://www.blogger.com/profile/10328155919659476809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_jKncqkKIgbA/S-GKdSLrsII/AAAAAAAACfM/jbCnUIcKC4Q/S220/Picture+022.jpg'/></author><thr:total>0</thr:total></entry></feed>
