<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Jeff Kemp on Oracle</title>
	<atom:link href="http://jeffkemponoracle.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeffkemponoracle.com</link>
	<description>Oracle Database: Get it Right</description>
	<lastBuildDate>Mon, 21 May 2012 22:39:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='jeffkemponoracle.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/6f6a6311f6d0e3d42cfdbfe19d045bac?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Jeff Kemp on Oracle</title>
		<link>http://jeffkemponoracle.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://jeffkemponoracle.com/osd.xml" title="Jeff Kemp on Oracle" />
	<atom:link rel='hub' href='http://jeffkemponoracle.com/?pushpress=hub'/>
		<item>
		<title>Forbidden PL/SQL</title>
		<link>http://jeffkemponoracle.com/2012/04/30/forbidden-plsql/</link>
		<comments>http://jeffkemponoracle.com/2012/04/30/forbidden-plsql/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 01:13:56 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[humour]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[what-not-to-do]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1273</guid>
		<description><![CDATA[What&#8217;s the biggest clue you can give that your database is vulnerable to SQL injection? When your list of &#8220;forbidden words&#8221; looks suspiciously like a sample of SQL / PL/SQL keywords: I notice that they haven&#8217;t forbidden BEGIN, CREATE, MERGE, or TRUNCATE &#8230; Congressman Peters, your IT staff are doing it wrong. Via: http://thedailywtf.com/Articles/Out-of-Service.aspx#pic4 Filed under: Oracle [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1273&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>What&#8217;s the biggest clue you can give that your database is vulnerable to SQL injection? When your list of &#8220;forbidden words&#8221; looks suspiciously like a sample of SQL / PL/SQL keywords:</p>
<p><a href="http://thedailywtf.com/Articles/Out-of-Service.aspx#pic4"><img class="alignnone" src="http://img.thedailywtf.com/images/12/q2/err10/pic4.png" alt="" width="562" height="125" /></a></p>
<p>I notice that they haven&#8217;t forbidden <strong>BEGIN</strong>, <strong>CREATE</strong>, <strong>MERGE</strong>, or <strong>TRUNCATE</strong> &#8230;</p>
<p>Congressman Peters, your IT staff are <strong>doing it wrong</strong>.</p>
<p>Via: <a href="http://thedailywtf.com/Articles/Out-of-Service.aspx#pic4">http://thedailywtf.com/Articles/Out-of-Service.aspx#pic4</a></p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/'>Oracle</a> Tagged: <a href='http://jeffkemponoracle.com/tag/humour/'>humour</a>, <a href='http://jeffkemponoracle.com/tag/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/tag/sql/'>SQL</a>, <a href='http://jeffkemponoracle.com/tag/what-not-to-do/'>what-not-to-do</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1273/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1273&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/04/30/forbidden-plsql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://img.thedailywtf.com/images/12/q2/err10/pic4.png" medium="image" />
	</item>
		<item>
		<title>Code I Regret: Refactoring as Penance</title>
		<link>http://jeffkemponoracle.com/2012/04/19/code-i-regret-refactoring-as-penance/</link>
		<comments>http://jeffkemponoracle.com/2012/04/19/code-i-regret-refactoring-as-penance/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 13:55:54 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[code-snippet-of-the-day]]></category>
		<category><![CDATA[design-antipattern]]></category>
		<category><![CDATA[humour]]></category>
		<category><![CDATA[introspection]]></category>
		<category><![CDATA[what-not-to-do]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1258</guid>
		<description><![CDATA[Recently I refactored some PL/SQL for sending emails &#8211; code that I wrote way back in 2004. The number of &#8220;WTF&#8220;&#8216;s per minute has not been too high; however, I&#8217;ve cringed more times than I&#8217;d like&#8230; 1. Overly-generic parameter types When you send an email, it will have at least one recipient, and it may [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1258&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.osnews.com/story/19266/WTFs_m"><img class="alignright" title="&quot;Worse Than Failures&quot; per minute :)" src="http://www.osnews.com/images/comics/wtfm.jpg" alt="" width="300" height="283" /></a>Recently I refactored some PL/SQL for sending emails &#8211; code that I wrote way back in 2004. The number of &#8220;<a href="http://thedailywtf.com/Info/About.aspx" target="_blank">WTF</a>&#8220;&#8216;s <a href="http://www.osnews.com/story/19266/WTFs_m" target="_blank">per minute</a> has not been <em>too</em> high; however, I&#8217;ve cringed more times than I&#8217;d like&#8230;</p>
<h1>1. Overly-generic parameter types</h1>
<p>When you send an email, it will have at least one recipient, and it may have many recipients. However, no email will have more than one sender. Yet, I wrote the package procedure like this:</p>
<pre>TYPE address_type IS RECORD
 (name          VARCHAR2(100)
 ,email_address VARCHAR2(200)
 );
TYPE address_list_type IS TABLE OF address_type
 INDEX BY BINARY_INTEGER;
PROCEDURE send
 (i_sender     IN address_list_type
 ,i_recipients IN address_list_type
 ,i_subject    IN VARCHAR2
 ,i_message    IN VARCHAR2
 );</pre>
<p>Why I didn&#8217;t have i_sender be a simple address_type, I can&#8217;t remember. Internally, the procedure only looks at i_sender(1) &#8211; if a caller were to pass in a table of more than one sender, it raises an exception.</p>
<h1>2. Functional programming to avoid local variables</h1>
<p>Simple is best, and there&#8217;s nothing wrong with using local variables. I wish I&#8217;d realised these facts when I wrote functions like this:</p>
<pre>FUNCTION address
 (i_name          IN VARCHAR2
 ,i_email_address IN VARCHAR2
 ) RETURN address_list_type;
FUNCTION address
 (i_address       IN address_list_type
 ,i_name          IN VARCHAR2
 ,i_email_address IN VARCHAR2
 ) RETURN address_list_type;</pre>
<p>All that so that callers can avoid *one local variable*:</p>
<pre>EMAIL_PKG.send
 (i_sender     =&gt; EMAIL_PKG.address('joe','joe@company.com')
 ,i_recipients =&gt; EMAIL_PKG.address(
                  EMAIL_PKG.address(
                  'jill', 'jill@company.com')
                 ,'bob', 'bob@company.com')
 ,i_subject    =&gt; 'hello'
 ,i_message    =&gt; 'world'
 );</pre>
<p>See what I did there with the recipients? Populating an array on the fly with just function calls. Smart eh? But rather useless, as it turns out; when we need to send multiple recipients, it&#8217;s usually populated within a loop of unknown sized, so this method doesn&#8217;t work anyway.</p>
<p><em>Go ahead &#8211; face your past and dig up some code you wrote 5 years ago or more.</em> I think, if you don&#8217;t go &#8220;WTF!&#8221; every now and then, you probably haven&#8217;t learned anything or improved yourself in the intervening years. Just saying :)</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/plsql/'>PL/SQL</a> Tagged: <a href='http://jeffkemponoracle.com/tag/code-snippet-of-the-day/'>code-snippet-of-the-day</a>, <a href='http://jeffkemponoracle.com/tag/design-antipattern/'>design-antipattern</a>, <a href='http://jeffkemponoracle.com/tag/humour/'>humour</a>, <a href='http://jeffkemponoracle.com/tag/introspection/'>introspection</a>, <a href='http://jeffkemponoracle.com/tag/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/tag/what-not-to-do/'>what-not-to-do</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1258/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1258&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/04/19/code-i-regret-refactoring-as-penance/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://www.osnews.com/images/comics/wtfm.jpg" medium="image">
			<media:title type="html">&#34;Worse Than Failures&#34; per minute :)</media:title>
		</media:content>
	</item>
		<item>
		<title>Poll: your oldest Oracle version</title>
		<link>http://jeffkemponoracle.com/2012/04/12/poll-your-oldest-oracle-version/</link>
		<comments>http://jeffkemponoracle.com/2012/04/12/poll-your-oldest-oracle-version/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 00:36:58 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1259</guid>
		<description><![CDATA[I&#8217;m doing some research for an uncoming Oracle conference &#8211; to help, please answer this poll. Thank you! Update: thanks to everyone who voted &#8211; it certainly looks like there is a significant number of places still running Oracle versions older than 10g. It is likely that many of these will be getting ready to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1259&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m doing some research for an uncoming Oracle conference &#8211; to help, please answer this poll. Thank you!</p>
<a name="pd_a_6129942"></a><div class="PDS_Poll" id="PDI_container6129942" style="display:inline-block;"></div><div id="PD_superContainer"></div><noscript><a href="http://polldaddy.com/poll/6129942">Take Our Poll</a></noscript>
<p><em>Update:</em> thanks to everyone who voted &#8211; it certainly looks like there is a significant number of places still running Oracle versions older than 10g. It is likely that many of these will be getting ready to upgrade or be decommissioned, but even then our 7/8i/9i database skills will be relevant for some time to come.</p>
<p>If you haven&#8217;t voted yet, the poll is still open.</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/'>Oracle</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1259/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1259&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/04/12/poll-your-oldest-oracle-version/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>
	</item>
		<item>
		<title>Alexandria: May Cause Addiction</title>
		<link>http://jeffkemponoracle.com/2012/03/25/alexandria-may-cause-addiction/</link>
		<comments>http://jeffkemponoracle.com/2012/03/25/alexandria-may-cause-addiction/#comments</comments>
		<pubDate>Sun, 25 Mar 2012 05:00:05 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[amazon-ec2]]></category>
		<category><![CDATA[tips-&-tricks]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1246</guid>
		<description><![CDATA[Ever since I downloaded the Alexandria PL/SQL library, I haven&#8217;t been able to put it down. Just recently I decided I wanted to serve up a whole lot of media files directly from Amazon&#8217;s S3 simple storage service, instead of serving them from within my EC2 (elastic compute) instance. They were just wasting my linux [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1246&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/plsql-utils/"><img class="size-full wp-image-1248 aligncenter" src="http://jeffkemponoracle.files.wordpress.com/2012/03/alexandria-logo.png?w=497" alt=""   /></a></p>
<p>Ever since I downloaded the <a href="http://code.google.com/p/plsql-utils/" target="_blank">Alexandria PL/SQL library</a>, I haven&#8217;t been able to put it down. Just recently I decided I wanted to serve up a whole lot of media files directly from Amazon&#8217;s S3 simple storage service, instead of serving them from within my EC2 (elastic compute) instance. They were just wasting my linux server&#8217;s time responding to http requests.</p>
<p>So, I quickly wrote the following code to transfer them:</p>
<pre>DECLARE
  l_blob BLOB;
BEGIN
  /* initialise my AWS session */
  ALEX.amazon_aws_auth_pkg.init
    ( 'yyy-my-aws-id-yyy'
    , 'xxx-not-telling-xxx'
    , p_gmt_offset =&gt; -8);
  FOR rec IN (
    SELECT id, filename, mime_type, location
    FROM myfiles
    WHERE location = 'http://myserver/media/'
  ) LOOP
    /* read the file from its current location */
    l_blob := ALEX.http_util_pkg.get_blob_from_url
      (rec.location || rec.filename);
    IF DBMS_LOB.getLength(l_blob) &gt; 0 THEN
      /* upload the file to Amazon S3 */
      ALEX.amazon_aws_s3_pkg.new_object
        ( 'mybucket'
        , rec.filename
        , l_blob
        , rec.mime_type
        , ALEX.amazon_aws_s3_pkg.g_acl_public_read);
      UPDATE myfiles
      SET location = 'https://mybucket.s3-ap-southeast-1.amazonaws.com/'
      WHERE id = rec.id;
      COMMIT;
    END IF;
  END LOOP;
END;</pre>
<p>After a short while, all the files had been copied across to my bucket on S3, and my table updated so that my web site now points people&#8217;s browsers to the new location for those files.</p>
<p>Of course, I could have used UTL_FILE to read the files from disk, but then I&#8217;d have to first create a directory, and write a loop to read the file in chunks into the BLOB. Why bother with all that when I can just call <strong>http_util_pkg.get_blog_from_url</strong> and get it all in one go?</p>
<p>That&#8217;s the trouble with powerful utilities like Alexandria: they&#8217;re too easy to use, make tasks like this trivial, and you start finding all sorts of uses for them. All of a sudden, Alexandria is your hammer, and the <a href="http://en.wikipedia.org/wiki/Law_of_the_instrument" target="_blank">world is full of nails</a>.</p>
<p>See also: this quick <a href="http://ora-00001.blogspot.com.au/2011/03/amazon-s3-api-for-plsql.html" target="_blank">intro to using Alexandria&#8217;s API for Amazon S3</a>.</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/'>Oracle</a>, <a href='http://jeffkemponoracle.com/category/oracle/plsql/'>PL/SQL</a> Tagged: <a href='http://jeffkemponoracle.com/tag/amazon-ec2/'>amazon-ec2</a>, <a href='http://jeffkemponoracle.com/tag/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/tag/tips-tricks/'>tips-&amp;-tricks</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1246/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1246/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1246/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1246/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1246/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1246/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1246/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1246/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1246&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/03/25/alexandria-may-cause-addiction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://jeffkemponoracle.files.wordpress.com/2012/03/alexandria-logo.png" medium="image" />
	</item>
		<item>
		<title>Generating unique identifiers with &#8220;SELECT MAX(id) + 1&#8243;</title>
		<link>http://jeffkemponoracle.com/2012/03/22/generating-unique-identifiers-with-select-maxid-1/</link>
		<comments>http://jeffkemponoracle.com/2012/03/22/generating-unique-identifiers-with-select-maxid-1/#comments</comments>
		<pubDate>Thu, 22 Mar 2012 07:40:05 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[tips-&-tricks]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1230</guid>
		<description><![CDATA[Normally, when you see code like this in a production system, you should duck your head and run: SELECT NVL( MAX( id ), 0 ) + 1 INTO :new_id FROM mytable; What&#8217;s wrong with this code? I hope the first answer that rolls off your tongue has something to do with concurrency &#8211; i.e. two [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1230&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://knowyourmeme.com/memes/dont-do-it"><img class="aligncenter" src="http://i2.kym-cdn.com/entries/icons/original/000/008/542/Capture.GIF" alt="" width="332" height="224" /></a></p>
<p>Normally, when you see code like this in a production system, you should duck your head and run:</p>
<pre>SELECT NVL( MAX( id ), 0 ) + 1
INTO   :new_id
FROM   mytable;</pre>
<p>What&#8217;s wrong with this code?</p>
<p>I hope the first answer that rolls off your tongue has something to do with <strong><a href="http://docs.oracle.com/cd/E11882_01/server.112/e25789/consist.htm#CNCPT121" target="_blank">concurrency</a></strong> &#8211; i.e. two sessions that run this around the same time will not see uncommitted rows from each other, and so are likely to try to insert rows with conflicting identifiers.</p>
<p>I hope the second answer that you might mention has to do with performance &#8211; even considering there&#8217;s a unique index on the column, this code will still need to read at least one index block to get the latest ID (assuming the query optimiser chooses to do a <a href="http://www.orafaq.com/tuningguide/high%20vol%20index.html" target="_blank">MIN/MAX index scan</a> so that it doesn&#8217;t have to scan the entire index before returning a result). In a high load system this cost might be unacceptable.</p>
<p>Of course, the first problem (concurrency) could be solved by serializing access to the &#8220;get the next ID&#8221; function, e.g. with a <a href="http://jeffkemponoracle.com/2005/10/19/user-named-locks-with-dbms_lock/">DBMS_LOCK</a>. We all know, however, that there&#8217;s no sane reason to serialize this when Oracle <em>already provides a perfectly good mechanism</em> for generating unique IDs, with virtually no serialization &#8211; <strong><a href="http://docs.oracle.com/cd/E11882_01/server.112/e25789/schemaob.htm#CNCPT611" target="_blank">sequences</a></strong>.</p>
<pre>CREATE SEQUENCE my_id_seq;
SELECT my_id_seq.NEXTVAL INTO :new_id FROM DUAL;</pre>
<p>Sequences have the benefits of guaranteeing uniqueness, and if their &#8220;<a href="http://docs.oracle.com/cd/E11882_01/server.112/e25494/views002.htm#ADMIN11801" target="_blank">cache</a>&#8221; setting is set appropriately, will add a negligible amount of overhead for serialization.</p>
<p>Problem solved. Easy, right? I bet you&#8217;re wondering why I added the word &#8220;Normally&#8221; to my first sentence in this post&#8230;.</p>
<p>Question: When might using <strong>&#8220;SELECT MAX(id) + 1&#8243;</strong> ever be an acceptable source of unique identifiers?</p>
<p>Answer: <strong><a href="http://docs.oracle.com/cd/E11882_01/server.112/e25494/tables003.htm#ADMIN11633" target="_blank">Global Temporary tables</a></strong>.</p>
<p>If I&#8217;ve inserted any rows into a global temporary table, by definition no other session can see my data, so the first consideration, concurrency, is not an issue.</p>
<p>Also, if I&#8217;m not expecting to ever insert many rows into my global temporary table, I can be reasonably confident that performance will not be an issue either. Plus, if I put an index on the ID column, that query will be quite inexpensive.</p>
<p><em>Conclusion:</em> if you are using global temporary tables, you don&#8217;t <em>have to</em> use sequences to generate unique identifiers for them. I&#8217;m not saying you shouldn&#8217;t, of course &#8211; a sequence may be faster, and may even lead to simpler code in some cases &#8211; but in other cases you might decide to forego a sequence &#8211; one less object, with perhaps its role grants and synonyms, to deploy.</p>
<p>&#8230;</p>
<p>Now, of course, you have to ask yourself, why query the table at all? Why not store that latest ID in a private global variable in a package? In fact, we can create a simple package to replace the sequence, e.g.:</p>
<pre>CREATE OR REPLACE PACKAGE my_table_pkg IS
FUNCTION next_id RETURN my_table.id%TYPE;
END my_table_pkg;
CREATE OR REPLACE PACKAGE BODY my_table_pkg IS
  g_latest_id my_table.id%TYPE;
FUNCTION next_id RETURN my_table.id%TYPE IS
  BEGIN
    g_latest_id := NVL(g_latest_id, 0) + 1;
    RETURN g_latest_id;
  END next_id;
END my_table_pkg;</pre>
<p>Well, now you know what to do. Whenever you need to generate a unique set of identifiers for a global temporary table, you&#8217;ve got a choice of options: sequence, package variable, or a &#8220;max(id)+1&#8243; query.</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/category/oracle/sql/'>SQL</a> Tagged: <a href='http://jeffkemponoracle.com/tag/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/tag/sql/'>SQL</a>, <a href='http://jeffkemponoracle.com/tag/tips-tricks/'>tips-&amp;-tricks</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1230/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1230&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/03/22/generating-unique-identifiers-with-select-maxid-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://i2.kym-cdn.com/entries/icons/original/000/008/542/Capture.GIF" medium="image" />
	</item>
		<item>
		<title>Constrain a table to only 1 row</title>
		<link>http://jeffkemponoracle.com/2012/03/21/constrain-a-table-to-only-1-row/</link>
		<comments>http://jeffkemponoracle.com/2012/03/21/constrain-a-table-to-only-1-row/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 07:29:10 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[problem-solved]]></category>
		<category><![CDATA[tips-&-tricks]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1219</guid>
		<description><![CDATA[I needed a table that could only ever have one row &#8211; if anyone tried to insert a second row they&#8217;d get an error. CREATE UNIQUE INDEX only_one_row_allowed ON mytable (1); Testing it: INSERT INTO mytable VALUES ('x'); ORA-00001: unique constraint (SCOTT.ONLY_ONE_ROW_ALLOWED) violated Filed under: SQL Tagged: problem-solved, SQL, tips-&#38;-tricks<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1219&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I needed a table that could only ever have one row &#8211; if anyone tried to insert a second row they&#8217;d get an error.</p>
<p><code> CREATE UNIQUE INDEX only_one_row_allowed ON mytable (1);<br />
</code></p>
<p>Testing it:</p>
<p><code> INSERT INTO mytable VALUES ('x');<br />
ORA-00001: unique constraint (SCOTT.ONLY_ONE_ROW_ALLOWED) violated<br />
</code></p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/sql/'>SQL</a> Tagged: <a href='http://jeffkemponoracle.com/tag/problem-solved/'>problem-solved</a>, <a href='http://jeffkemponoracle.com/tag/sql/'>SQL</a>, <a href='http://jeffkemponoracle.com/tag/tips-tricks/'>tips-&amp;-tricks</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1219/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1219&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/03/21/constrain-a-table-to-only-1-row/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>
	</item>
		<item>
		<title>New apex web site: www.myhomecontents.com.au</title>
		<link>http://jeffkemponoracle.com/2012/03/17/new-apex-web-site-www-myhomecontents-com-au/</link>
		<comments>http://jeffkemponoracle.com/2012/03/17/new-apex-web-site-www-myhomecontents-com-au/#comments</comments>
		<pubDate>Sat, 17 Mar 2012 10:51:57 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[APEX]]></category>
		<category><![CDATA[amazon-ec2]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1224</guid>
		<description><![CDATA[I&#8217;ve just opened my new web site, built entirely in Oracle Application Express, and announced it on my other blog: &#8220;www.myhomecontents.com.au has been built with just one simple purpose – to help you keep track of your home contents. It’s in “beta” status at the moment, so I’m keen to get as many people as possible [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1224&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="www.myhomecontents.com.au"><img class="alignright size-full wp-image-1225" title="www.myhomecontents.com.au" src="http://jeffkemponoracle.files.wordpress.com/2012/03/couchcropped.png?w=497" alt=""   /></a>I&#8217;ve just opened my new web site, built entirely in Oracle Application Express, and <a href="http://jeffkemp.jk64.com/2012/03/17/new-web-site-www-myhomecontents-com-au/">announced it on my other blog</a>:</p>
<blockquote><p><em>&#8220;<strong><a href="http://www.myhomecontents.com.au" target="_blank">www.myhomecontents.com.au</a></strong> has been built with just one simple purpose – to help you keep track of your home contents. It’s in “beta” status at the moment, so I’m keen to get as many people as possible to try it out to flesh out any bugs.&#8221;</em></p></blockquote>
<p><a href="www.myhomecontents.com.au"><img class="aligncenter size-full wp-image-1226" title="www.myhomecontents.com.au" src="http://jeffkemponoracle.files.wordpress.com/2012/03/flotsam-login.png?w=497&h=363" alt="" width="497" height="363" /></a></p>
<p>Please check it out, and let me know what you think!</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/apex/'>APEX</a> Tagged: <a href='http://jeffkemponoracle.com/tag/amazon-ec2/'>amazon-ec2</a>, <a href='http://jeffkemponoracle.com/tag/apex/'>APEX</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1224/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1224&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/03/17/new-apex-web-site-www-myhomecontents-com-au/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://jeffkemponoracle.files.wordpress.com/2012/03/couchcropped.png" medium="image">
			<media:title type="html">www.myhomecontents.com.au</media:title>
		</media:content>

		<media:content url="http://jeffkemponoracle.files.wordpress.com/2012/03/flotsam-login.png" medium="image">
			<media:title type="html">www.myhomecontents.com.au</media:title>
		</media:content>
	</item>
		<item>
		<title>DEFAULT NULL NULL</title>
		<link>http://jeffkemponoracle.com/2012/02/13/default-null-null/</link>
		<comments>http://jeffkemponoracle.com/2012/02/13/default-null-null/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 03:37:14 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1217</guid>
		<description><![CDATA[Found myself running the following command today: ALTER TABLE mytable MODIFY (mycolumn DEFAULT NULL NULL); I know &#8211; I&#8217;m easily entertained :) Filed under: SQL<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1217&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Found myself running the following command today:</p>
<p>    ALTER TABLE mytable<br />
       MODIFY (mycolumn DEFAULT NULL NULL);</p>
<p>I know &#8211; I&#8217;m easily entertained :)</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/sql/'>SQL</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1217/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1217&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2012/02/13/default-null-null/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>
	</item>
		<item>
		<title>Designing a PL/SQL API &#8211; BOOLEAN or CHAR?</title>
		<link>http://jeffkemponoracle.com/2011/12/19/designing-a-plsql-api-boolean-or-char/</link>
		<comments>http://jeffkemponoracle.com/2011/12/19/designing-a-plsql-api-boolean-or-char/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 03:05:48 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[best-practice]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1203</guid>
		<description><![CDATA[A simple question: you&#8217;re designing an API to be implemented as a PL/SQL package, and you don&#8217;t (yet) know the full extent to which your API may be used, so you want to cover a reasonable variety of possible usage cases. You have a function that will return a BOOLEAN &#8211; i.e. TRUE or FALSE [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1203&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A simple question: you&#8217;re designing an API to be implemented as a PL/SQL package, and you don&#8217;t (yet) know the full extent to which your API may be used, so you want to cover a reasonable variety of possible usage cases.</p>
<p><a href="http://phy240.ahepl.org/assets/images/HydrogenAtom-11_5_3.jpg"><img class="alignright" title="Booleans - you can't get much more atomic than that :)" src="http://phy240.ahepl.org/assets/images/HydrogenAtom-11_5_3.jpg" alt="" width="240" height="240" /></a>You have a function that will return a BOOLEAN &#8211; i.e. TRUE or FALSE (or perhaps NULL). Should you implement it this way, or should you return some other kind of value &#8211; e.g. a CHAR &#8211; e.g. &#8216;Y&#8217; for TRUE or &#8216;N&#8217; for FALSE; or how about a NUMBER &#8211; e.g. 1 for TRUE or 0 for FALSE?</p>
<p>This debate has raged since 2002, and probably earlier &#8211; e.g. <a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6263249199595">http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6263249199595</a></p>
<p>Well, if I use a BOOLEAN, it makes the code simple and easy to understand &#8211; and callers can call my function in IF and WHILE statements without having to compare the return value to anything. However, I can&#8217;t call the function from a SQL statement, which can be annoyingly restrictive.</p>
<p>If I use a CHAR or NUMBER, I can now call the function from SQL, and store it in a table &#8211; but it makes the code just a little more complicated &#8211; now, the caller has to trust that I will ONLY return the values agreed on. Also, there is no way to formally restrict the values as agreed &#8211; I&#8217;d have to just document them in the package comments. I can help by adding some suitable constants in the package spec, but note that Oracle Forms cannot refer to these constants directly. Mind you, if the value is being stored in a table, a suitable CHECK constraint would be a good idea.</p>
<p>Perhaps a combination? Have a function that returns BOOLEAN, and add wrapper functions that converts a BOOLEAN into a &#8216;Y&#8217; or &#8216;N&#8217; as appropriate? That might be suitable.</p>
<p>Personally, though, I hate the NUMBER (1 or 0) idea for PL/SQL. That&#8217;s so C-from-the-1970&#8242;s. Who codes like that anymore?</p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/'>Oracle</a>, <a href='http://jeffkemponoracle.com/category/oracle/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/category/oracle/sql/'>SQL</a> Tagged: <a href='http://jeffkemponoracle.com/tag/best-practice/'>best-practice</a>, <a href='http://jeffkemponoracle.com/tag/plsql/'>PL/SQL</a>, <a href='http://jeffkemponoracle.com/tag/sql/'>SQL</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1203/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1203&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2011/12/19/designing-a-plsql-api-boolean-or-char/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://phy240.ahepl.org/assets/images/HydrogenAtom-11_5_3.jpg" medium="image">
			<media:title type="html">Booleans - you can&#039;t get much more atomic than that :)</media:title>
		</media:content>
	</item>
		<item>
		<title>3 Reasons to Hate Hibernate</title>
		<link>http://jeffkemponoracle.com/2011/11/25/3-reasons-to-hate-hibernate/</link>
		<comments>http://jeffkemponoracle.com/2011/11/25/3-reasons-to-hate-hibernate/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 06:16:39 +0000</pubDate>
		<dc:creator>Jeffrey Kemp</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[mindset]]></category>
		<category><![CDATA[what-not-to-do]]></category>

		<guid isPermaLink="false">http://jeffkemponoracle.com/?p=1013</guid>
		<description><![CDATA[Warning: this is a rant. This is just a collection of observations of Hibernate, from the perspective of an Oracle developer/&#8221;DBA&#8221;. I&#8217;m aware of some of the benefits of using Hibernate to shield Java developers from having to know anything about the database or the SQL language, but sometimes it seems to me that we [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1013&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#ff0000;"><strong><em>Warning: this is a rant.</em></strong></span></p>
<p>This is just a collection of observations of Hibernate, from the perspective of an Oracle developer/&#8221;DBA&#8221;. I&#8217;m aware of some of the benefits of using Hibernate to shield Java developers from having to know anything about the database or the SQL language, but sometimes it seems to me that we might generally be better off if they were required to learn a little about what&#8217;s going on &#8220;underneath the hood&#8221;. (Then I remind myself that it&#8217;s my job to help them get the most out of the database the client spent so much money getting.)</p>
<p>So, here are my gripes about Hibernate &#8211; just getting them off my chest so I can put them to bed.</p>
<blockquote><p><em>Disclaimer: I know every Hibernate aficionado will jump in with &#8220;but it&#8217;s easy to fix that, all you have to do is&#8230;&#8221; but these are generalizations only.</em></p></blockquote>
<h1><a href="http://farm2.static.flickr.com/1306/1041323440_a377ac2955.jpg"><img class="alignright" src="http://farm2.static.flickr.com/1306/1041323440_a377ac2955.jpg" alt="" width="300" height="225" /></a>Exhibit A: Generic Query Generators</h1>
<p>As soon as I&#8217;d loaded all the converted data into the dev and test instances, we started hitting silly performance issues. A simple search on a unique identifier would take 20-30 seconds to return at first, then settle down to 4-8 seconds a pop. Quite rightly, everyone expected these searches to be virtually instant.</p>
<p>The culprit was usually a query like this:</p>
<pre>select count(*) as y0_
from XYZ.SOME_TABLE this_
inner join XYZ.SOME_CHILD_TABLE child1_
on this_.PARENT_ID=child1_.PARENT_ID
where lower(this_.UNIQUE_IDENTIFIER) like :1
order by child1_.COLH asc, child1_.COLB asc, this_.ANOTHER_COL desc</pre>
<p>What&#8217;s wrong with this query, you might ask?</p>
<h2>Issue 1: Case-insensitive searches by default</h2>
<p>Firstly, it is calling LOWER() on the unique identifier, which will never contain any alphabetic characters, so case-insensitive searches will never be required &#8211; and so it will not use the unique index on that column. Instead of forcing the developers to <em>think about</em> whether case-insensitive searches are required or not for each column, it allows them to simply blanket the whole system with these &#8211; and quite often no-one will notice until the system goes into UAT or even Prod and someone actually decides to test searching on that particular column, and decides that waiting for half a minute is unacceptable. It&#8217;s quite likely that for some cases even this won&#8217;t occur, and these poorly performing queries (along with their associated load on the database server) will be used all the time, and people will complain about the general poor performance of the database.</p>
<h2>Issue 2: Count first, then re-query for the data</h2>
<p>Secondly, it is doing a COUNT(*) on a query which will immediately after be re-issued in order to get the actual data.  I&#8217;d much prefer that the developers were writing the SQL by hand. That way, it&#8217;d be a trivial matter to ask them to get rid of the needless COUNT(*) query; and if they simply <em>must</em> show a total record count on the page, add a COUNT(*) OVER () to the main query &#8211; thus killing two birds with one efficient stone.</p>
<h1><a href="http://fc07.deviantart.net/fs40/f/2009/027/f/d/Magic_Wand_by_mciguu.png"><img class="alignright" src="http://fc07.deviantart.net/fs40/f/2009/027/f/d/Magic_Wand_by_mciguu.png" alt="" width="307" height="307" /></a>Exhibit B: Magical Class Generators (tables only)</h1>
<h2>Issue 3: No views, no procedures, no functions</h2>
<p>When someone buys Hibernate, they might very well ask: is it possible to call an Oracle procedure or function with this product? And the answer is, of course, &#8220;yes&#8221;. Sure, you can do anything you want!</p>
<p>The day the Java developers peel off the shrinkwrap, the first thing they try is creating a Java class based on a single table. With glee they see it automagically create all the member attributes and getter/setter methods, and with no manual intervention required they can start coding the creation, modification and deletion of records using this class, which takes care of all the dirty SQL for them.</p>
<p>Then, the crusty old Oracle developer/&#8221;DBA&#8221; comes along and says: &#8220;It&#8217;d be better if you could use this API I&#8217;ve lovingly crafted in a PL/SQL package &#8211; everything you need is in there, and you&#8217;ll be shielded from any complicated stuff we might need to put in the database now or later. All you have to do is call these simple procedures and functions.&#8221; And the Java developer goes &#8220;sure, no problem&#8221; &#8211; until they discover that Hibernate cannot automatically create the same kind of class they&#8217;ve already gotten accustomed to.</p>
<p><em>&#8220;What, we actually need to read the function/procedure definition and hand-code all the calls to them? No sir, not happening.&#8221;</em> After all, they bought Hibernate to save them all that kind of work, and who&#8217;s going to blame them?</p>
<p>So, you say, &#8220;Ok, no problem, we&#8217;ll wrap the API calls with some simple views, backed by instead-of triggers.&#8221; But then they hit another wall &#8211; Hibernate can&#8217;t tell from a view definition how that view relates to other views or tables.</p>
<p>The end result is that all the Java code does is access tables directly. And you get the kind of queries (and worse) that you saw in Exhibit &#8220;A&#8221; above.</p>
<p>There. I feel so much better already.</p>
<p><span style="color:#ff0000;"><strong>/rant</strong></span></p>
<br />Filed under: <a href='http://jeffkemponoracle.com/category/oracle/sql/'>SQL</a> Tagged: <a href='http://jeffkemponoracle.com/tag/development/'>development</a>, <a href='http://jeffkemponoracle.com/tag/hibernate/'>Hibernate</a>, <a href='http://jeffkemponoracle.com/tag/mindset/'>mindset</a>, <a href='http://jeffkemponoracle.com/tag/sql/'>SQL</a>, <a href='http://jeffkemponoracle.com/tag/what-not-to-do/'>what-not-to-do</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeffkemponoracle.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeffkemponoracle.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeffkemponoracle.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeffkemponoracle.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeffkemponoracle.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeffkemponoracle.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeffkemponoracle.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeffkemponoracle.wordpress.com/1013/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeffkemponoracle.com&#038;blog=12972578&#038;post=1013&#038;subd=jeffkemponoracle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeffkemponoracle.com/2011/11/25/3-reasons-to-hate-hibernate/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1bab0ace9c953cc500a28fea281a5c55?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">jeffreykemp</media:title>
		</media:content>

		<media:content url="http://farm2.static.flickr.com/1306/1041323440_a377ac2955.jpg" medium="image" />

		<media:content url="http://fc07.deviantart.net/fs40/f/2009/027/f/d/Magic_Wand_by_mciguu.png" medium="image" />
	</item>
	</channel>
</rss>
