<?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:blogger='http://schemas.google.com/blogger/2008' 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-15861274</id><updated>2025-09-02T07:22:53.888+01:00</updated><title type='text'>Oracle WTF</title><subtitle type='html'>Every three years or so, I like to post something mildly amusing for no real reason.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default?alt=atom'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default?alt=atom&amp;start-index=26&amp;max-results=25'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>96</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15861274.post-2289701399949481477</id><published>2017-10-14T12:31:00.002+01:00</published><updated>2022-08-27T08:38:26.073+01:00</updated><title type='text'>Mmm, π</title><content type='html'>&lt;p&gt;Young &lt;b&gt;rz.He&lt;/b&gt; over on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/plsql+or+sql+oracle&quot;&gt;Stack Overflow&lt;/a&gt; has a question about why SQL*Plus doesn&#39;t parse every line of a PL/SQL block in case it&#39;s a comment in order to avoid unnecessary prompts for substitution variables. Here&#39;s his &lt;a href=&quot;http://idownvotedbecau.se/nomcve/&quot;&gt;mcve&lt;/a&gt;:

&lt;pre&gt;SQL&gt; begin
  2      null; -- &amp;commented_out
  3  end;
  4  /
Enter value for commented_out: wtf

PL/SQL procedure successfully completed.&lt;/pre&gt;
&lt;p&gt;Oh, wait - it&#39;s not that. It&#39;s actually this:&lt;/p&gt;

&lt;pre&gt;CREATE OR REPLACE PROCEDURE cal_circle AS
-- DECLARE

  pi              CONSTANT NUMBER := 3.1415926;
  radius          NUMBER := 3;

  -- to make it more dynamic I can set 
  -- radius NUMBER := &amp;enter_value;

  circumference   DECIMAL(4,2) := radius * pi * 2;
  area            DECIMAL(4,2) := pi * radius ** 2;

BEGIN

  -- DBMS_OUTPUT.PUT_LINE(&#39;Enter a valur of radius: &#39;|| radius);
  dbms_output.put_line(&#39;For a circle with radius &#39;
   || radius
   || &#39;,the circumference is &#39;
   || circumference
   || &#39; and the area is &#39;
   || area
   || &#39;.&#39;);
END;
/
&lt;/pre&gt;

&lt;p&gt;But anyway.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/46514518/230471&quot;&gt;An excellent answer&lt;/a&gt; explains all about clients and servers and procedure parameters and why it&#39;s really not SQL*Plus&#39;s job to pre-parse everything before sending it to the database and it wouldn&#39;t be such a great idea if it did. I voted up. But what really baked my noodle was the opening comment (my emphasis):
&lt;/p&gt;
&lt;blockquote&gt;You can use a parameter instead of a substitution variable to allow different users to call the procedure &lt;b&gt;with different values of pi&lt;/b&gt;.&lt;/blockquote&gt;
&lt;p&gt;...with a fixed version of the code posted as an example...&lt;/p&gt;
&lt;pre&gt;CREATE OR REPLACE PROCEDURE CAL_CIRCLE
  ( P_RADIUS IN NUMBER, P_PI IN NUMBER )
AS
  CIRCUMFERENCE DECIMAL(4, 2) := P_RADIUS * P_PI * 2;
  AREA          DECIMAL(4, 2) := P_PI * P_RADIUS ** 2;

BEGIN
  DBMS_OUTPUT.put_line(&#39;For a circle with radius &#39;
                       || P_RADIUS
                       || &#39;, the circumference is &#39;
                       || CIRCUMFERENCE
                       || &#39; and the area is &#39;
                       || AREA
                       || &#39;. &#39; || &#39;Calculated with Pi = &#39; || P_PI);
END;&lt;/pre&gt;

&lt;p&gt;You will agree that is much more flexible. Now we can call it for a conventional &lt;i&gt;&amp;pi;&lt;/i&gt;, like this:&lt;/p&gt;

&lt;pre&gt;SQL&gt; call cal_circle(3, 3.1416);
For a circle with radius 3, the circumference is 18.85 and the area is 28.27. Calculated with Pi = 3.1416&lt;/pre&gt;

&lt;p&gt;Or like this:&lt;/p&gt;

&lt;pre&gt;SQL&gt; call cal_circle(3, acos(-1));
For a circle with radius 3, the circumference is 18.85 and the area is 28.27. Calculated with Pi = 3.1415926535897932384626433832795028842&lt;/pre&gt;

&lt;p&gt;But what if we need to switch back to the imperial &lt;i&gt;&amp;pi;&lt;/i&gt; following our exit from the EU, or the chancellor reduces the UK&#39;s &lt;i&gt;&amp;pi;&lt;/i&gt; in order to stimulate economic growth, or we want to use the &lt;a href=&quot;http://www.abarim-publications.com/Bible_Commentary/Pi_In_The_Bible.html&quot;&gt;biblical &lt;i&gt;&amp;pi;&lt;/i&gt;&lt;/a&gt; for religious reasons, or if we simply want to use the same procedure in an alternative universe with a fundamentally different geometry than our own? No problem:&lt;/p&gt;

&lt;pre&gt;SQL&gt; call cal_circle(3, 2.71828);
For a circle with radius 3, the circumference is 16.31 and the area is 24.46. Calculated with Pi = 2.71828&lt;/pre&gt;

&lt;p&gt;Now that is reusability. (The radius can&#39;t be more than 9.99, but come on, you can&#39;t have everything.)&lt;/p&gt;

&lt;p&gt;As usual, of course, the easy way is no fun:&lt;/p&gt;

&lt;pre&gt;create or replace function circumference
    ( p_radius in number )
    return number
    deterministic
as
begin
    return p_radius * 6.2831853071795864769252867666;
end circumference;
&lt;/pre&gt;
&lt;p&gt;(with something similar for area - at which point you might consider putting them both into a &lt;code&gt;circle&lt;/code&gt; package). Or, slightly more fun:&lt;/p&gt;

&lt;pre&gt;create or replace type circle as object
( radius         number
, diameter       number
, circumference  number
, area           number
, constructor function circle(p_radius number) return self as result );
/

create or replace type body circle
as
    constructor function circle
        ( p_radius number )
        return self as result
    is
    begin
        self.radius := p_radius;
        self.diameter := self.radius * 2;
        self.circumference := self.radius * 6.2831853071795864769252867666;
        self.area := 3.1415926535897932384626433833 * radius ** 2;

        return;
    end;
end;
/

SQL&gt; select circle(3) as mycircle from dual;

MYCIRCLE(RADIUS, DIAMETER, CIRCUMFERENCE, AREA)
----------------------------------------------------
CIRCLE(3, 6, 18.8495559, 28.2743339)

1 row selected.&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/2289701399949481477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/2289701399949481477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2289701399949481477'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2289701399949481477'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2017/10/mmm.html' title='Mmm, π'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/15587739711173542698</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-1817490237094022151</id><published>2017-10-07T09:15:00.000+01:00</published><updated>2017-10-14T12:53:01.401+01:00</updated><title type='text'>The power of scripting</title><content type='html'>&lt;p&gt;So your system has a neat automated archive and purge function for your rolling partitions, driven by the &lt;code&gt;PART_RETENTION&lt;/code&gt; table which holds the table name, partition type (&#39;DAILY&#39;, &#39;MONTHLY&#39;, &#39;QUARTERLY&#39; or &#39;YEARLY&#39;) and how many of each to keep. As a general rule, you want 35 dailies, 13 month-ends, 5 quarter-ends and 2 year-ends for each table. Let&#39;s say you have ten tables. All you need is a handy script to set that up. This is what someone actually came up with. (This is just an example. There were a lot more tables).&lt;/p&gt;

&lt;pre&gt;insert into part_retention (table_name, partition_type, retention ) values &#39;COUNTRIES&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;DEPARTMENTS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;EMPLOYEES&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOBS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOB_HISTORY&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;LOCATIONS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;REGIONS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;SALES&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDERS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDER_ITEMS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;CUSTOMERS&#39;, &#39;DAILY&#39;, 35);
insert into part_retention (table_name, partition_type, retention ) values &#39;COUNTRIES&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;DEPARTMENTS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;EMPLOYEES&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOBS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOB_HISTORY&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;LOCATIONS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;REGIONS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;SALES&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDERS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDER_ITEMS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;CUSTOMERS&#39;, &#39;MONTHLY&#39;, 13);
insert into part_retention (table_name, partition_type, retention ) values &#39;COUNTRIES&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;DEPARTMENTS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;EMPLOYEES&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOBS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOB_HISTORY&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;LOCATIONS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;REGIONS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;SALES&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDERS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDER_ITEMS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;CUSTOMERS&#39;, &#39;QUARTERLY&#39;, 5);
insert into part_retention (table_name, partition_type, retention ) values &#39;COUNTRIES&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;DEPARTMENTS&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;EMPLOYEES&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOBS&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;JOB_HISTORY&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;LOCATIONS&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;REGIONS&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;SALES&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDERS&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;ORDER_ITEMS&#39;, &#39;YEARLY&#39;, 2);
insert into part_retention (table_name, partition_type, retention ) values &#39;CUSTOMERS&#39;, &#39;YEARLY&#39;, 2);&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/1817490237094022151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/1817490237094022151' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/1817490237094022151'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/1817490237094022151'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2017/10/the-power-of-scripting.html' title='The power of scripting'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/15587739711173542698</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-4723988011575374114</id><published>2014-01-05T11:46:00.000+00:00</published><updated>2014-01-05T11:46:49.041+00:00</updated><title type='text'>Looping the hard way</title><content type='html'>&lt;p&gt;The task was to construct partition names from &#39;P001&#39; to (for some reason) &#39;P336&#39;, as part of a larger maintenance script. Here&#39;s what they came up with:&lt;/p&gt;
&lt;pre&gt;declare
   p varchar2(4);
   i number := 1;
begin
   loop
      if i &lt; 10 then
         p := &#39;P00&#39; || to_char(i);
      elsif i &lt; 100 then
         p := &#39;P0&#39; || to_char(i);
      else
         p := &#39;P&#39; || to_char(i);
      end if;
      
      i := i + 1;
      
      exit when i &gt; 336;

      dbms_output.put_line(p);
   end loop;
end;&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/4723988011575374114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/4723988011575374114' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/4723988011575374114'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/4723988011575374114'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2014/01/looping-hard-way.html' title='Looping the hard way'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/15587739711173542698</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-9138961244582996606</id><published>2013-06-01T08:51:00.000+01:00</published><updated>2013-06-02T01:08:55.376+01:00</updated><title type='text'>e_howdidIdeservethis</title><content type='html'>&lt;p&gt;A friend has found himself supporting a stack of code written in this style:&lt;/p&gt;
&lt;pre&gt;DECLARE
   e_dupe_flag EXCEPTION;
   PRAGMA EXCEPTION_INIT(e_dupe_flag, -1);

BEGIN
   ...

EXCEPTION
   WHEN e_dupe_flag THEN
      RAISE e_duplicate_err;

  etc...&lt;/pre&gt;
&lt;p&gt;Because, as he says, coding is &lt;b&gt;&lt;i&gt;not hard enough&lt;/i&gt;&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;This reminded me of one that was sent in a while ago:&lt;/p&gt;
&lt;pre&gt;others EXCEPTION;&lt;/pre&gt;
&lt;p&gt;&lt;i&gt;&quot;I didn&#39;t know you could do that&quot;&lt;/i&gt; adds our correspondent.</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/9138961244582996606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/9138961244582996606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/9138961244582996606'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/9138961244582996606'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2013/06/ehowdidideservethis.html' title='e_howdidIdeservethis'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-2755519406369175133</id><published>2012-05-23T07:35:00.001+01:00</published><updated>2014-02-09T18:42:51.109+00:00</updated><title type='text'>The Girl With The ANSI Tattoo</title><content type='html'>&lt;p&gt;I enjoyed the &lt;a href=&quot;http://www.rottentomatoes.com/m/the_girl_with_the_dragon_tattoo/&quot;&gt;David Fincher remake&lt;/a&gt; of &lt;a href=&quot;http://www.rottentomatoes.com/m/the_girl_with_the_dragon_tattoo_2009/&quot;&gt;The Girl With The Dragon Tattoo&lt;/a&gt; more than I thought I would. Rather than a shallow and cynical Hollywood cash-in, it&#39;s actually a tense, atmospheric, only slightly voyeuristic crime thriller. My favourite part, though, was when Lisbeth Salander begins to solve a 40 year old murder cold case using SQL.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;img border=&quot;0&quot; width=&quot;645px&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5ZMEaI4gt9HDxaMA5uKTeWQDjT_FCaiX83xG_h8wL36Mr3GLe_0AgORXug7d43GXjWxbTOOczgCgRF9eZM9ImO3EmDG31mehuoHvq7p0t31UMwsxJR90qHRaASDAdRNVIIjg2ug/s1600/IMG_7862.JPG&quot; alt=&quot;[girl_tattoo_overshoulder.jpg]&quot;/&gt;
&lt;/div&gt;

&lt;p&gt;We see her tapping at her laptop as she hacks effortlessly into the Swedish police database, interspersed with green-tinted tracking shots of scrolling text as she types in keywords like &#39;unsolved&#39; and &#39;decapitation&#39;, though never quite the whole query:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJJDtrXxcYAzFIC-YYVmSSkoSrUhyphenhyphenZGymg1v17wTOP0mIfr4Y14IzvZ5C4lMElB3HEUxQhzYLr0yPSVyjL6AxyuASPdlaLq7W-ln0CEYi1v1vmI9vsbe-pnibv1NJKym0Xwjv67w/s1600/girl_tattoo1.jpg&quot; alt=&quot;[girl_tattoo1.jpg]&quot;/&gt;
&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUA2aL61QMhpz9-tQcyp0VkEfbrJM2UgVi9Qv4QeorXxJFOoaoOTVO416ZkDdAQ-0DWSD5BORjNhJPHThGxY-i6Ur0J7h44CApLwuJ8Qn-kNRpc5huACHBfXVNdvhhNiCEZ_tjxQ/s1600/girl_tattoo2.jpg&quot; alt=&quot;[girl_tattoo2.jpg]&quot;/&gt;
&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP24gvwtYNz-8viWltIWWWs803PifL_FN-jmnGBMZyaWqwqu_NOxAGkJ1FTrDGD6DCnACZ7LEpG9WTWtEZFuSaAFPMSWQE0V4yFWcHN8sdYDfpwbAA_P6Wak2VRJUh5Gm3JUg76w/s1600/girl_tattoo3-mari-magda.jpg&quot; alt=&quot;[girl_tattoo3-mari-magda.jpg]&quot;/&gt;
&lt;/div&gt;

&lt;p&gt;Naturally I couldn&#39;t help stitching a few screenshots together in Photoshop, and this is what I got:&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;img border=&quot;0&quot; width=&quot;800px&quot;
src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnQ_7X1xQhsQCLKFhl8CNYKyEM1c3beSEdbti6j7ODEMUbzHgt6j3m26Dd7gXKwuCrxjYybG0ZJ9JK1lRfilVSDvf3gXMAf9DD2B-kD_KDOdpNj7dhfObl6TMlUohO4g3YnF0O7A/s1600/Girl-with-the-ANSI-Tattoo-SQL.jpg&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;Immediately moviegoers will notice that this can&#39;t be Oracle SQL - obviously the &lt;tt&gt;AS&lt;/tt&gt; keyword is not valid for table aliases. In fact as we pull back for a thrilling query results listing we see the &lt;tt&gt;mysql&lt;/tt&gt; prompt and giveaway &lt;tt&gt;use [dbname]&lt;/tt&gt; connect syntax and over-elaborate box drawing.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;img border=&quot;0&quot; width=&quot;640px&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnJQTqndrO02tKKU4EvyrtFDj8D5P6WTiTV50oIbZHALdKou1zDpUM4rn8fvl6uW66Q3wlCVAUo-SxsjWXklreD8aWfIznXDh8Y8mOivjuzog5sfaBq422jF8tRfjg-EqC-js_3A/w1100-h733-no/girl_tattoo_results1.jpg&quot; alt=&quot;[girl_tattoo_results1.jpg]&quot;/&gt;
&lt;/div&gt;

&lt;p&gt;Notice we can just make out the &#39;FT&#39; of an ANSI left join to the Keyword table.&lt;/p&gt;&lt;p&gt;Finally we get a full-screen shot of the results listing for Västra Götaland:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSoyHR9nmjzdgD9Fov3gz3budJBE8TbgQJjcFbZlsjbdthOJmUF7hiEMYg8ZkIrNiA94GY5HrBSoSqdqZ9-kuZjTagAbVqQjCOmFVyH_2_z6WJHR4qpygkMKCtUMIauRIcAuuQcQ/s1600/girl_tattoo_results2.jpg&quot; alt=&quot;[girl_tattoo_results2.jpg]&quot;/&gt;
&lt;/div&gt;

&lt;p&gt;Here&#39;s what we were able to reconstruct in the Oracle WTF Forensics department:&lt;/p&gt;
&lt;pre&gt;SELECT DISTINCT v.fname, v.lname, i.year, i.location, i.report_file
FROM   Incident AS i
       LEFT JOIN Victim AS v on v.incident_id = i.id
       LEFT JOIN Keyword AS k ON k.incident_id = i.id
WHERE  i.year BETWEEN 1947 AND 1966
AND    i.type = &#39;HOMICIDE&#39;
AND    v.sex = &#39;F&#39;
AND    i.status = &#39;UNSOLVED&#39;
AND    (  k.keyword IN
          (&#39;rape&#39;, &#39;decapitation&#39;, &#39;dismemberment&#39;, &#39;fire&#39;, &#39;altar&#39;, &#39;priest&#39;, &#39;prostitute&#39;)
        OR v.fname IN (&#39;Mari&#39;, &#39;Magda&#39;)
        OR SUBSTR(v.fname, 1, 1) = &#39;R&#39; AND SUBSTR(v.lname, 1, 1) = &#39;L&#39; );

+--------+---------+------+-----------+----------------------------------+
| fname  | lname   | year | location  | report_file                      |
+--------+---------+------+-----------+----------------------------------+
| Anna   | Wedin   | 1956 | Mark      | FULL POLICE REPORT NOT DIGITIZED |
| Linda  | Janson  | 1955 | Mariestad | FULL POLICE REPORT NOT DIGITIZED |
| Simone | Grau    | 1958 | Goteborg  | FULL POLICE REPORT NOT DIGITIZED |
| Lea    | Persson | 1962 | Uddevalla | FULL POLICE REPORT NOT DIGITIZED |
| Kajsa  | Severin | 1962 | Dals-Ed   | FULL POLICE REPORT NOT DIGITIZED |
+--------+---------+------+-----------+----------------------------------+&lt;/pre&gt;
&lt;p&gt;Shocked moviegoers will have been left wondering why a genius-level hacker would outer-join to the Victims and Keywords tables only to use literal-text filter predicates that defeat the outer joins, and whether MySQL has a &lt;tt&gt;LIKE&lt;/tt&gt; operator&lt;!--, and why none of the victims&#39; initials are &#39;R L&#39;--&gt;.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/2755519406369175133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/2755519406369175133' title='75 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2755519406369175133'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2755519406369175133'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2012/05/girl-with-ansi-tattoo.html' title='The Girl With The ANSI Tattoo'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/15587739711173542698</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5ZMEaI4gt9HDxaMA5uKTeWQDjT_FCaiX83xG_h8wL36Mr3GLe_0AgORXug7d43GXjWxbTOOczgCgRF9eZM9ImO3EmDG31mehuoHvq7p0t31UMwsxJR90qHRaASDAdRNVIIjg2ug/s72-c/IMG_7862.JPG" height="72" width="72"/><thr:total>75</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-2323823706808960548</id><published>2012-05-19T14:20:00.001+01:00</published><updated>2012-05-20T09:33:07.529+01:00</updated><title type='text'>How to Merge a Row</title><content type='html'>&lt;p&gt;The tough challenge that seems to have been faced by this developer was that the ID, name and value passed into the procedure needed to be either applied as an update if the name existed, or else inserted as a new row. You might think you could just use &lt;a href=&quot;http://docs.oracle.com/cd/E11882_01/server.112/e17118/statements_9016.htm&quot;&gt;MERGE&lt;/a&gt;, or maybe attempt the update, capturing the ID value with a RETURNING clause, then if that found no rows insert a new row using &lt;tt&gt;seq_somethings.NEXTVAL&lt;/tt&gt; for the ID. But wait, that wouldn&#39;t be complicated enough, would it?&lt;/p&gt;&lt;p&gt;Here&#39;s the table:&lt;/p&gt;&lt;pre&gt;create table something
( id               integer  not null constraint pk_something primary key
, name             varchar2(100)
, publicsomething  number   default 0  not null );&lt;/pre&gt;Here&#39;s what they came up with:&lt;br /&gt;
&lt;pre&gt;PROCEDURE SaveSomething(pId              IN OUT something.id%TYPE,
                        pName            IN something.name%TYPE,
                        pPublicSomething IN something.publicsomething%TYPE) IS
     counter NUMBER;
BEGIN
     SELECT COUNT(rowid)
     INTO   counter
     FROM   something c
     WHERE  LOWER(c.name) = LOWER(pName);

     IF counter &amp;gt; 0 THEN
          SELECT id
          INTO   pId
          FROM   something c
          WHERE  LOWER(c.name) = LOWER(pName);
     END IF;

     IF (pId IS NOT NULL AND pId &amp;gt; 0) THEN
          UPDATE something
          SET    id              = pId,
                 name            = pName,
                 publicsomething = pPublicsomething
          WHERE  id = pId;

     ELSE
          SELECT seq_somethings.NEXTVAL
          INTO   pId
          FROM   dual;

          INSERT INTO something
               (id, name, publicsomething)
          VALUES
               (pid, pname, ppublicsomething);
     END IF;

EXCEPTION
     WHEN OTHERS THEN
          -- log the details then throw the exception so the calling code can perform its own logging if required.
          log_error(&#39;PK_ADMIN.SaveSomething&#39;,
                    USER,
                    SQLCODE || &#39;: &#39; || SQLERRM);
          RAISE;
END SaveSomething;&lt;/pre&gt;&lt;p&gt;Thanks Boneist for this. By the way she mentioned she counted 6 WTFs, &quot;some more subtle than others&quot;. I&#39;m not sure whether we&#39;re counting the stupid redundant brackets around the IF condition (drives me crazy), the novel 5-character indent or the design WTF in which the &quot;name&quot; column is expected to be unique but has no constraint or indeed index. I&#39;m definitely counting &lt;tt&gt;SQLCODE&amp;nbsp;||&amp;nbsp;&#39;:&amp;nbsp;&#39;&amp;nbsp;||&amp;nbsp;SQLERRM&lt;/tt&gt; though.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/2323823706808960548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/2323823706808960548' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2323823706808960548'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2323823706808960548'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2012/05/how-to-merge-row.html' title='How to Merge a Row'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/15587739711173542698</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-452067979669871331</id><published>2011-03-26T09:08:00.000+00:00</published><updated>2011-03-26T09:08:41.360+00:00</updated><title type='text'>Concatenation, Concatenation, Concatenation</title><content type='html'>&lt;p&gt;I&#39;m still not sure what this one does, but you have to be impressed by 11 nested CONCATs.&lt;/p&gt;&lt;p&gt;(And by the way, you also have to be impressed by the inventor of the &lt;tt&gt;CONCAT&lt;/tt&gt; function who evidently considered two arguments sufficient, unlike, say &lt;tt&gt;LEAST&lt;/tt&gt;, &lt;tt&gt;GREATEST&lt;/tt&gt;, &lt;tt&gt;DECODE&lt;/tt&gt;, &lt;tt&gt;COALESCE&lt;/tt&gt; and &lt;tt&gt;BIN_TO_NUM&lt;/tt&gt;. But not &lt;tt&gt;NVL&lt;/tt&gt;. Who knows what goes through these people&#39;s heads.)&lt;/p&gt;
&lt;pre&gt;PROCEDURE ins_xyz
   ( p_xyz_id_out OUT NUMBER,
     p_input_array IN myarrayrectype )
IS
BEGIN
   p_xyz_id_out := NULL;

   BEGIN
      INSERT INTO xyztab
         (
            xyz_id,
            xyz_11,
            xyz_12,
            xyz_13,
            xyz_21,
            xyz_22,
            xyz_23,
            xyz_31,
            xyz_32,
            xyz_33,
            xyz_41,
            xyz_42,
            xyz_43,
            xyz_43_concatenated
         )
      VALUES
         (
            xyz_seq.NEXTVAL,
            p_input_array.xyz_11,
            p_input_array.xyz_12,
            p_input_array.xyz_13,
            p_input_array.xyz_21,
            p_input_array.xyz_22,
            p_input_array.xyz_23,
            p_input_array.xyz_31,
            p_input_array.xyz_32,
            p_input_array.xyz_33,
            p_input_array.xyz_41,
            p_input_array.xyz_42,
            p_input_array.xyz_43,
            SUBSTR(
              CONCAT(
                CONCAT(
                  CONCAT(
                    CONCAT(
                      CONCAT(
                        CONCAT(
                          CONCAT(
                            CONCAT(
                              CONCAT(
                                CONCAT(
                                  CONCAT(
                                    p_input_array.xyz_11 || &#39; &#39;,
                                    p_input_array.xyz_12 || &#39; &#39;),
                                  p_input_array.xyz_13 || &#39; &#39; ),
                                p_input_array.xyz_21 || &#39; &#39; ),
                              p_input_array.xyz_22 || &#39; &#39; ),
                            p_input_array.xyz_23 || &#39; &#39; ),
                          p_input_array.xyz_31 || &#39; &#39; ),
                        p_input_array.xyz_32 || &#39; &#39; ),
                      p_input_array.xyz_33 || &#39; &#39; ),
                    p_input_array.xyz_41 || &#39; &#39; ),
                  p_input_array.xyz_42 || &#39; &#39; ),
                p_input_array.xyz_43 ),
            1, 512 )
         )
      RETURNING xyz_id INTO p_xyz_id_out;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;
END ins_xyz;
&lt;/pre&gt;
&lt;p&gt;Thanks BB for this one, which she or he (I can&#39;t say more for witness protection reasons) sent me a while ago and I almost forgot about.&lt;/p&gt;&lt;p&gt;I didn&#39;t post it at the time because I couldn&#39;t understand what it did. Looking at it again though, that&#39;s all part of the fun. Here&#39;s part of the conversation we had about it:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;Me:&lt;/b&gt; Thanks BB - love it. I&#39;m  slightly puzzled by p_input_array though. Is it an  array?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;BB:&lt;/b&gt; An array of records.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Me:&lt;/b&gt; Yikes. So what does the target table look like? I suppose each &lt;i&gt;&#39;xyz_nn_&#39;&lt;/i&gt; column must be a nested table.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;BB:&lt;/b&gt; In the actual system they&#39;re parts of node tuples. &lt;i&gt;xyz_11, xyz_12, xyz_13&lt;/i&gt;, all indicate &quot;scores&quot; for pairings of the first node with 1, 2, 3, respectively. Hard to explain without giving away too much about the system. However, they&#39;re scalars.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Me:&lt;/b&gt; Glad we got that cleared up. Can I say &lt;i&gt;parts of node tuples&lt;/i&gt; without endangering your job at NASA?&lt;/p&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/452067979669871331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/452067979669871331' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/452067979669871331'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/452067979669871331'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2011/03/concatenation-concatenation.html' title='Concatenation, Concatenation, Concatenation'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-8932879139201997970</id><published>2011-03-12T15:04:00.000+00:00</published><updated>2011-03-12T15:04:44.315+00:00</updated><title type='text'>Explain this</title><content type='html'>&lt;p&gt;On the subject of &lt;a href=&quot;http://oracle-wtf.blogspot.com/2011/03/make-me-one-with-everything.html&quot;&gt;cryptic OTN posts&lt;/a&gt;, &lt;a href=&quot;http://forums.oracle.com/forums/thread.jspa?threadID=1955511&quot;&gt;this one&lt;/a&gt; has to get an honorary mention as well:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;h3&gt;explain this&lt;/h3&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;hi,&lt;/p&gt;&lt;p&gt;write query to find out order detail of oder_date 2 year before (sorry i forget exact question)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;No solutions so far.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/8932879139201997970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/8932879139201997970' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8932879139201997970'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8932879139201997970'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2011/03/explain-this.html' title='Explain this'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-4925612722564686264</id><published>2011-03-12T14:52:00.000+00:00</published><updated>2012-05-20T09:33:40.316+01:00</updated><title type='text'>Make Me One With Everything</title><content type='html'>&lt;p&gt;Seen on &lt;a href=&quot;http://forums.oracle.com/forums/thread.jspa?threadID=2188330&amp;amp;tstart=0&quot;&gt;OTN Forums&lt;/a&gt; recently (part of a question entitled &lt;i&gt;&quot;HTML not working in PL/SQL block&quot;&lt;/i&gt;, so I suppose we were warned):&lt;/p&gt;&lt;pre&gt;l_col VARCHAR2(30) := to_number(to_char(to_date(&#39;01-feb-2011&#39;,&#39;dd-mon-yyyy&#39;),&#39;dd&#39;));&lt;/pre&gt;&lt;p&gt;So the string &lt;tt&gt;&#39;01-feb-2011&#39;&lt;/tt&gt; becomes first a date, then a string again, then a number, before being assigned to a string variable. Much more interesting than boring old&lt;p&gt;&lt;pre&gt;l_col VARCHAR2(30) := extract (day from date &#39;2011-02-01&#39;);&lt;/pre&gt;&lt;p&gt;Or even,&lt;/p&gt;&lt;pre&gt;l_col VARCHAR2(30) := &#39;1&#39;;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/4925612722564686264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/4925612722564686264' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/4925612722564686264'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/4925612722564686264'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2011/03/make-me-one-with-everything.html' title='Make Me One With Everything'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-4849165561594579990</id><published>2010-01-21T07:26:00.003+00:00</published><updated>2010-01-21T07:28:46.772+00:00</updated><title type='text'>Interview questions</title><content type='html'>&lt;p&gt;A friend recently had a telephone interview for an Oracle technical contract role. Here are the questions he was asked:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What is the command to edit a crontab?&lt;/li&gt;
&lt;li&gt;What are the first and fourth parameters on the crontab?&lt;/li&gt;
&lt;li&gt;What is the command to email the list of files that are too big and need to be deleted to prevent a tablespace getting too big?&lt;/li&gt;
&lt;li&gt;Have you used the OLAP command? and who invented it?&lt;/li&gt;
&lt;li&gt;When do you set PCTFREE?&lt;/li&gt;
&lt;li&gt;When is the PGA in the SGA?&lt;/li&gt;
&lt;li&gt;Where is the Java pool?&lt;/li&gt;
&lt;li&gt;How do I stop a checkpoint when I commit?&lt;/li&gt;
&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/4849165561594579990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/4849165561594579990' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/4849165561594579990'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/4849165561594579990'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2010/01/interview-questions.html' title='Interview questions'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-8582046489776760636</id><published>2009-11-29T13:44:00.000+00:00</published><updated>2009-11-29T13:44:13.179+00:00</updated><title type='text'>The £10 UKOUG Weak Joke Challenge</title><content type='html'>&lt;p&gt;Oracle-WTF will pay the sum of £10 to the first person who makes the following weak Brummie joke to a conference audience at UKOUG:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are there any Brummies here today?&lt;/p&gt;
&lt;p&gt;Is it true that Ozzy Osbourne thought the Spice Girls were astronauts?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;(Note for visitors to England: it&#39;s about the accent. And The Spice Girls used to be a pop group. And Ozzy Osbourne, oh never mind.)&lt;/i&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/8582046489776760636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/8582046489776760636' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8582046489776760636'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8582046489776760636'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/11/10-ukoug-weak-joke-challenge.html' title='The £10 UKOUG Weak Joke Challenge'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-8893380144201761490</id><published>2009-10-31T15:21:00.003+00:00</published><updated>2009-10-31T15:32:49.462+00:00</updated><title type='text'>Now where are those user accounts?</title><content type='html'>&lt;p&gt;The IM conversation below is part of a much longer one (notice the date stamps) between a friend who we&#39;ll just call &#39;TR&#39; and a developer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;i&gt;&lt;b&gt;Developer (11 Oct 2009 14:39:51):&lt;/b&gt; I created some users and now they are gone?&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (11 Oct 2009 14:40:01):&lt;/b&gt; We have implemented a daily flashback to the data baseline so that repeatable tests can run every day in that database.&lt;br /&gt;
&lt;b&gt;TR (11 Oct 2009 14:40:03):&lt;/b&gt; You need to notify us (as per the mail I sent out) when you make data changes that you want to keep from day to day.&lt;br /&gt;
&lt;b&gt;TR (11 Oct 2009 14:40:06):&lt;/b&gt; Ok, so could you please create those users again and let me know? I&#39;ll create a new baseline for the refresh....&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (11 Oct 2009 14:45:51):&lt;/b&gt; i wonder if i ll be able this afternoon&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (11 Oct 2009 14:46:12):&lt;/b&gt; so i can do it tomorrow and send you the list&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (11 Oct 2009 14:46:25):&lt;/b&gt; You can go ahead wit the refreh of today without my users&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (11 Oct 2009 14:48:29):&lt;/b&gt; Ok, I don&#39;t need the list, just to know once you have created them.&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (11 Oct 2009 14:50:18):&lt;/b&gt; ok &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 16:57:53):&lt;/b&gt; hi TR&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (20 Oct 2009 16:57:59):&lt;/b&gt; Hi&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 16:58:06):&lt;/b&gt; Are you still doing the DB refresh on daily basis?&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (20 Oct 2009 16:58:20):&lt;/b&gt; Yes. It&#39;s automatic, I don&#39;t actually *do* anything.&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 16:58:24):&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 16:58:27):&lt;/b&gt; ok&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 16:58:33):&lt;/b&gt; then&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 16:59:22):&lt;/b&gt; i see&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 17:01:42):&lt;/b&gt; actually i m looking for this user on alpha qa2_PN3D8J20aa&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 17:01:52):&lt;/b&gt; i can&#39;t find it in the db&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 17:02:04):&lt;/b&gt; and when i m logged in with it, I added it yesterday and now it&#39;s gone&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (20 Oct 2009 17:03:02):&lt;/b&gt; i ll try using other users&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (20 Oct 2009 17:16:21):&lt;/b&gt; You didn&#39;t tell me that you had created these users. The database is refreshed every night back to the baseline...as we discussed&lt;br /&gt;
&lt;b&gt;TR (20 Oct 2009 17:16:21):&lt;/b&gt; If you add data you have to let me know and I will create a new baseline.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TR (21 Oct 2009 16:08:49):&lt;/b&gt; These users that you need. Are they in the database now?&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (21 Oct 2009 16:09:02):&lt;/b&gt; not yet&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (21 Oct 2009 16:09:07):&lt;/b&gt; but i can ping them to you&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (21 Oct 2009 16:09:12):&lt;/b&gt; at least the login&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (21 Oct 2009 16:09:19):&lt;/b&gt; You don&#39;t need to ping them to me. Just tell me when they&#39;re created&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (21 Oct 2009 16:09:25):&lt;/b&gt; ok&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (21 Oct 2009 16:09:52):&lt;/b&gt; but got too much to do today probably will have them ready monday morning&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (21 Oct 2009 16:10:20):&lt;/b&gt; Ok, so as per last time....when they are created please let me know.&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (21 Oct 2009 16:10:30):&lt;/b&gt; ok&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:18:21):&lt;/b&gt; hi TR&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 13:18:27):&lt;/b&gt; Hi&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:18:31):&lt;/b&gt; what&#39;s time is the DB refresh taking time ?&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 13:18:41):&lt;/b&gt; 00:00GMT&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:18:44):&lt;/b&gt; ok&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:18:52):&lt;/b&gt; i ll ping you by the end of the day my new users&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 13:18:57):&lt;/b&gt; Ok, you don&#39;t need to ping me the users, just create them and tell me when you have done it&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:19:01):&lt;/b&gt; in the mean time&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:19:25):&lt;/b&gt; I&#39;m working on a script to insert our users in the Db before each time&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 13:19:39):&lt;/b&gt; Ok, you don&#39;t need to do that, just create them and tell me when you&#39;ve done it.&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 13:19:48):&lt;/b&gt; so this will help us lot and you will be free to do your updates as you want and delete our users if you need to&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 13:20:02):&lt;/b&gt; Ok great. But the process is already working, you just have to tell me once you&#39;ve created them and they will always be there&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:00:26):&lt;/b&gt; hi TR&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:00:34):&lt;/b&gt; what do i have to give you about the created users? only login&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 15:00:43):&lt;/b&gt; nothing, just tell me when you&#39;ve create them.&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:00:48):&lt;/b&gt; or Zid, Xid...&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:00:54):&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 15:00:54):&lt;/b&gt; just tell me WHEN they are created...so I can add them to the baseline.&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:01:04):&lt;/b&gt; today&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;TR (25 Oct 2009 15:01:17):&lt;/b&gt; they are there now?&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:01:21):&lt;/b&gt; not yet, but I will create these users&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:02:07):&lt;/b&gt; ppm_alpha_4 ppm_alpha_5&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:02:21):&lt;/b&gt; ppm_alpha_2 ppm_alpha_3 ppm_alpha_4 ppm_alpha_5&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Developer (25 Oct 2009 15:02:21):&lt;/b&gt; please don&#39;t delete them this time&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/8893380144201761490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/8893380144201761490' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8893380144201761490'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8893380144201761490'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/10/now-where-are-those-user-accounts.html' title='Now where are those user accounts?'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-9046417030658760478</id><published>2009-09-02T11:57:00.002+01:00</published><updated>2009-09-02T12:02:21.674+01:00</updated><title type='text'>If at first you don&#39;t succeed...</title><content type='html'>&lt;p&gt;...then try again. Then try again more 125 times. Then quit.&lt;/p&gt;
&lt;pre&gt;PROCEDURE get_id
    ( p_id_out         OUT NUMBER
    , p_name_in        IN VARCHAR2
    , p_create_user_in IN VARCHAR2 )
IS
    v_new_id      NUMBER := 0;
    v_max_tries   PLS_INTEGER := 127;
    v_default_id  NUMBER := 0;
BEGIN
    v_new_id := lookup_id(p_name_in); -- will be 0 if not found

    WHILE v_new_id = 0 AND v_max_tries &gt; 0
    LOOP
        BEGIN
            INSERT INTO entry
            ( entry_id
            , entry_name
            , create_date
            , create_user
            , create_app
            , mod_date
            , mod_user
            , mod_app)
            VALUES
            ( entry_seq.NEXTVAL
            , p_name_in
            , SYSDATE
            , p_create_user_in
            , &#39;get_id&#39;
            , SYSDATE
            , p_create_user_in
            , &#39;get_id&#39; )
            RETURNING entry_id INTO v_new_id;

        EXCEPTION
            WHEN OTHERS THEN NULL;
        END;
    
        v_max_tries := v_max_tries - 1;
    END LOOP;

    p_id_out := v_new_id;
END get_id;&lt;/pre&gt;
&lt;p&gt;Thanks BB for sending this.&lt;/tt&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/9046417030658760478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/9046417030658760478' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/9046417030658760478'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/9046417030658760478'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/09/if-at-first-you-dont-succeed.html' title='If at first you don&#39;t succeed...'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-6684392869768607105</id><published>2009-05-03T12:32:00.001+01:00</published><updated>2009-05-03T12:32:55.870+01:00</updated><title type='text'>The Undocumented &quot;/1000&quot; currency formatting function</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://forums.oracle.com/forums/thread.jspa?threadID=890147&quot;&gt;Forum question&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Hi,&lt;/p&gt;&lt;p&gt;How can I format currency values to shorthand?&lt;/p&gt;&lt;p&gt;i.e. how can I display 12500 as 12.5, 2700 as 2.7, 700 as 0.7 etc?&lt;/p&gt;&lt;p&gt;I have tried using various masks but can&#39;t achieve the results I&#39;m looking for.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;That&#39;s a tough one. How to make 700 into 0.7? Could there be some Oracle feature to help with this?&lt;/p&gt;&lt;p&gt;Two quick replies later:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Thanks for the replies guys&lt;/p&gt;&lt;p&gt;I wasnt aware of the &quot;/1000&quot; feature, but it has done exactly what I need.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Oracle needs to do more to promote these display format features. What else are they hiding? That&#39;s what we want to know.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/6684392869768607105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/6684392869768607105' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/6684392869768607105'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/6684392869768607105'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/05/undocumented-1000-currency-formatting.html' title='The Undocumented &quot;/1000&quot; currency formatting function'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-7526221537717579389</id><published>2009-04-10T08:31:00.001+01:00</published><updated>2009-04-10T08:32:34.418+01:00</updated><title type='text'>How to talk your way out of a hole</title><content type='html'>&lt;p&gt;One last shot from our favourite &lt;a href=&quot;http://oracle-wtf.blogspot.com/2009/03/consultant-on-backups.html&quot;&gt;consultant&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Be careful what you expect from this proof of concept. We can’t prove the performance will match the requirements, and I would argue that performance isn’t a function of this architecture, it’s a function of technology.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;The issue is not the architecture, it’s that [this company] doesn’t have the technology. I would even argue that the technology required might not exist yet.&lt;p&gt;&lt;/p&gt;&lt;p&gt;We can say that indicatively if the technology did exist, then this architecture would hit that performance requirement.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Let&#39;s hear it for &lt;a href=&quot;http://www.joelonsoftware.com/items/2008/05/01.html&quot;&gt;architecture astronauts&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/7526221537717579389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/7526221537717579389' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/7526221537717579389'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/7526221537717579389'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/04/how-to-talk-your-way-out-of-hole.html' title='How to talk your way out of a hole'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-7945167208236007944</id><published>2009-03-20T07:57:00.004+00:00</published><updated>2009-03-20T08:03:11.732+00:00</updated><title type='text'>Rollback segments explained</title><content type='html'>&lt;p&gt;I recently read this in a book about data warehousing:&lt;/p&gt;&lt;blockquote&gt;&lt;h3 style=&quot;margin-top: 0.5em;margin-bottom: 1em;&quot;&gt;Source System Rollback Segments&lt;/h3&gt;When extracting from a relational source, extracts that take a long time can be problematic. If an extract asks for all records updated in the last 24 hours, the system must locate the appropriate set of records. This means that no user can change the updated_date field while your query is being processed. As transactions flow in during your query, they are queued up in a separate place called a rollback segment, to be applied once your request is finished. If your query takes too long, this queue gets too large and runs out of space. The system then kills your job and processes the transactions that have been queued up. In general, the folks responsible for the transaction system don&#39;t like this kind of behavior.&lt;/blockquote&gt;&lt;p&gt;Now to be fair, the book was published in 1998 and is not specifically about Oracle. Does anyone know whether there has ever been a commercial DBMS that worked anything like this, or did they just make it up?&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/7945167208236007944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/7945167208236007944' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/7945167208236007944'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/7945167208236007944'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/03/rollback-segments-explained.html' title='Rollback segments explained'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-8876133168218652012</id><published>2009-03-14T17:30:00.001+00:00</published><updated>2009-03-14T17:32:26.872+00:00</updated><title type='text'>The Consultant on Backups</title><content type='html'>&lt;p&gt;Our correspondent overheard &lt;a href=&quot;http://oracle-wtf.blogspot.com/2009/02/consultant.html&quot;&gt;The Consultant&lt;/a&gt; sorting out the backup requirements for the new system:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;Consultant:&lt;/b&gt; You have a 6 hour window overnight, now as the queues get longer under heavy loading the end of day queue clearing will run into that 6 hours. Your backup window will start to get squeezed, so we need to know the minimum time to back-up this amount of data, including the time to shut down and start up the databases.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Technical guy:&lt;/b&gt; Why?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Consultant:&lt;/b&gt; Because it has to take place in that 6 hour window.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Technical guy:&lt;/b&gt; Why is that?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Consultant:&lt;/b&gt; Because then the users will come back on line and want to use the system.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Technical guy:&lt;/b&gt; So?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Consultant: &lt;/b&gt;They can&#39;t use the system if it&#39;s down to be backed up.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Technical guy: &lt;/b&gt;We&#39;ll use an online backup and they can do whatever they like.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Consultant:&lt;/b&gt; Well, if I was in auditing I&#39;d fire you right now. You simply have to shut a database down to back it up. It&#39;s the only way you can get a consistent backup.&lt;/p&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/8876133168218652012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/8876133168218652012' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8876133168218652012'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8876133168218652012'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/03/consultant-on-backups.html' title='The Consultant on Backups'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-8844457069260996002</id><published>2009-02-17T07:22:00.003+00:00</published><updated>2009-05-03T19:02:22.510+01:00</updated><title type='text'>The Consultant</title><content type='html'>&lt;p&gt;The Consultant has a Ph. D, vast experience of high-performance systems architecture, a black belt in karate and a reputation as a genius. He&#39;s been brought in by senior management at vast but necessary expense for a strategic rethink of the way data is shared between systems, while implementing SOA, improving performance and finding the Higgs Boson. Needless to say, he tends towards the view that database development is overrated. He&#39;s already sorted out the data warehouse. Overheard by our correspondent:
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I’ve finished the design for the data warehouse. Although I say design, it’s pretty simple. That’s why it was so quick. All data warehouses are essentially the same in that they are a dimensional model. That means that you essentially have everything that is a fact, an immutable fact [waves arms expressively], in the fact table. Just the one, big, table. That’s why they’re so attractive as reporting solutions - everything is in the same place so it’s easy to understand and the reporting is easy to automate. So in that fact table you’ve got all trades, the cashflows, positions, accounting information, accounts, exceptions, counterparties. Anything that’s a fact goes in that table [does wide googly eyes expression with dramatic pause]. Then anything derived is called a dimension, like for instance P&amp;amp;L calculations, whether the account is on balance sheet, or off... they go in the dimension table.  Basically all we have to do is just pump messages into that fact table from the bus and then recalculate the dimensions in the dimension table periodically, and that’s the technical job. Getting the facts in there and getting the calculations done.&lt;/p&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/8844457069260996002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/8844457069260996002' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8844457069260996002'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/8844457069260996002'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2009/02/consultant.html' title='The Consultant'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-7219476775729158465</id><published>2008-11-01T07:43:00.008+00:00</published><updated>2008-11-03T08:33:06.049+00:00</updated><title type='text'>More Fake Performance Tips</title><content type='html'>&lt;p&gt;We&#39;re not sure if this is a joke or just (more likely) the work of an idiot. Here are &lt;a href=&quot;http://latest360.blogspot.com/2008/04/tips-for-better-performance-and-tuning.html&quot; ref=&quot;nofollow&quot;&gt;15 Tips for better performance and tuning in Oracle SQL and PL/SQL&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;ol&gt;
&lt;li&gt;FTS (Full Table Scans) are always bad and Index usage is always good.&lt;/li&gt;
&lt;li&gt;Usage of dynamic SQL within the stored procedure code is always bad even for search procedures.&lt;/li&gt;
&lt;li&gt;Empty Space in an index that gets created due to the DML operations do not get used.&lt;/li&gt;
&lt;li&gt;Indexes should be rebuilt at regular intervals.&lt;/li&gt;
&lt;li&gt;Indexes and statistics are the same thing. Also, histograms are needed only on indexed columns.&lt;/li&gt;
&lt;li&gt;Usage of cursors is always bad so avoid them like the plague.&lt;/li&gt;
&lt;li&gt;Truncate command cannot be rolled back because it is a non-logged operation.&lt;/li&gt;
&lt;li&gt;Table variables in SQL Server are always only memory resident.&lt;/li&gt;
&lt;li&gt;Column order in a covered index does not matter.&lt;/li&gt;
&lt;li&gt;In the case of SQL Server, one can separate the clustered index from the table.&lt;/li&gt;
&lt;li&gt;Only committed data gets written to the disk.&lt;/li&gt;
&lt;li&gt;Logical I/Os (LIO) are not a cause of concern, only Physical IO (PIO) are.&lt;/li&gt;
&lt;li&gt;Count(1) is better performing than count(*).&lt;/li&gt;
&lt;li&gt;Issue frequent commits in the application to make the transaction faster and also improve concurrency.&lt;/li&gt;
&lt;li&gt;Views are evil evil DB Objects that always slow down performance. &lt;/li&gt;&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;We like the fact that 8, 9 and 10 appear to be about SQL Server, despite the heading. Probably Nawal could only think of 12 fake Oracle tips but thought nobody would notice. Can you help him out with some more misleading tips for Oracle? (Or SQL Server. Nobody will notice.) For example,&lt;/p&gt;&lt;ol start=&quot;16&quot;&gt;
&lt;li&gt;The buffer cache hit ratio is a reliable indicator of system performance.&lt;/li&gt;
&lt;li&gt;Bitmap indexes are perfect for columns with a small number of distinct values, like &#39;Y&#39; and &#39;N&#39;.&lt;/li&gt;
&lt;li&gt;The Inuit have fifty words for snow.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Spotted by Michel Cadot on Oracle-L.&lt;/p&gt;
&lt;p style=&quot;font-style: italic;&quot;&gt;&lt;b&gt;Update:&lt;/b&gt; Yong Huang pointed out that the source of the article appears to be a list of common myths posted on a SQL Server blog, which makes it slightly less funny than it first seemed. Oh well.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/7219476775729158465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/7219476775729158465' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/7219476775729158465'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/7219476775729158465'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2008/11/more-fake-performance-tips.html' title='More Fake Performance Tips'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-732908617249311457</id><published>2008-08-01T11:57:00.003+01:00</published><updated>2012-05-20T09:34:36.738+01:00</updated><title type='text'>TGI g_friday</title><content type='html'>&lt;p&gt;Found in a package body:&lt;/p&gt;&lt;pre&gt;g_friday CONSTANT VARCHAR2(6) := &#39;Friday&#39;;&lt;/pre&gt;&lt;p&gt;...then a couple of hundred lines later:&lt;/p&gt;&lt;pre&gt;if to_char(business_date,&#39;fmDay&#39;) = g_friday then
    &lt;i&gt;...end-of-week processing...&lt;/i&gt;
else
    &lt;i&gt;...regular processing...&lt;/i&gt;
end if;&lt;/pre&gt;&lt;p&gt;Now that&#39;s flexible. If end-of-week processing is ever moved to the weekend, all you have to do is set &lt;tt&gt;g_friday := &#39;Saturday&#39;&lt;/tt&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/732908617249311457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/732908617249311457' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/732908617249311457'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/732908617249311457'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2008/08/tgi-gfriday.html' title='TGI g_friday'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-5907826070431757676</id><published>2008-06-21T23:24:00.005+01:00</published><updated>2009-05-03T19:12:54.144+01:00</updated><title type='text'>Auxiliary Constructs Appeal</title><content type='html'>&lt;p&gt;Will somebody give &lt;a href=&quot;http://forums.oracle.com/forums/thread.jspa?messageID=2597237&quot;&gt;this guy&lt;/a&gt; some auxiliary constructs? He just needs to know what&#39;s the auxiliary constructs, and examples in the auxiliary constructs. So if you have any auxiliary constructs you don&#39;t need, now&#39;s the time to dig deep. The appeal starts here.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/5907826070431757676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/5907826070431757676' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/5907826070431757676'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/5907826070431757676'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2008/06/auxiliary-constructs-appeal.html' title='Auxiliary Constructs Appeal'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-3669780349250863678</id><published>2008-04-27T20:15:00.002+01:00</published><updated>2012-05-20T09:35:20.917+01:00</updated><title type='text'>Fine tuning</title><content type='html'>&lt;p&gt;Mike is doing some work on an application that started life as SQL Server. Now that it has been converted to Oracle, there are one or two bits that could still do with a little fine tuning.&lt;/p&gt;&lt;p&gt;One particular procedure seemed to take rather a lot of time, and several developers had tried to get better performance out of it without much success. Here it is:&lt;/p&gt;&lt;pre&gt;CREATE OR REPLACE PROCEDURE getupdatedrunids
    ( p_customer_id  IN VARCHAR2 DEFAULT NULL
    , pc_results_out IN OUT SYS_REFCURSOR )
AS
    v_fetch_status     INTEGER := 0;
    v_sql_status       INTEGER;
    v_fetch_status1    INTEGER := 0;
    v_sql_status1      INTEGER;
    v_event_id         VARCHAR2(50);
    v_runid            NUMBER(10, 0);
    v_count_run_conns  INTEGER := 0;
    v_temp_runs        INTEGER;

BEGIN
    DELETE FROM temp_runs;

    DELETE FROM temp_run_connections;

    INSERT INTO temp_runs
         ( run_id )
    SELECT DISTINCT i.run_id
    FROM   event_status i
         , run_status    b
    WHERE  i.run_id = b.run_id
    AND    i.event_id IN
           ( SELECT DISTINCT i.event_id
             FROM   event_status i
                  , run_status   b
             WHERE  i.run_id = b.run_id
             AND    b.customer_id = p_customer_id
             GROUP  BY i.event_id
             HAVING COUNT(i.run_id) &gt; 1)
             AND    b.customer_id = p_customer_id;

    BEGIN
        v_temp_runs := 0;
        SELECT COUNT(*)
        INTO   v_temp_runs
        FROM   dual
        WHERE  EXISTS
               ( SELECT *
                 FROM   temp_runs );
    END;

    IF v_temp_runs &gt; 0 THEN
    
        DECLARE
            CURSOR c_runs IS
                SELECT DISTINCT run_id
                FROM   temp_runs;
        BEGIN
            OPEN c_runs;
            FETCH c_runs INTO v_runid;

            IF c_runs%NOTFOUND
            THEN
                v_sql_status1   := 2;
                v_fetch_status1 := -1;
            ELSE
                v_sql_status1   := 0;
                v_fetch_status1 := 0;
            END IF;
        
            WHILE v_fetch_status1 = 0
            LOOP
                BEGIN
                    DECLARE
                        CURSOR cust_incidents_cs IS
                        
                            SELECT DISTINCT i.event_id
                            FROM   event_status i
                            WHERE  i.run_id = v_runid
                            AND    i.rejected = 0;
                    BEGIN
                        OPEN cust_incidents_cs;
                    
                        FETCH cust_incidents_cs INTO v_event_id;

                        IF cust_incidents_cs%NOTFOUND
                        THEN
                            v_sql_status   := 2;
                            v_fetch_status := -1;
                        ELSE
                            v_sql_status   := 0;
                            v_fetch_status := 0;
                        END IF;

                        &amp;lt;&amp;lt;i_loop1&gt;&gt;
                        WHILE v_fetch_status = 0
                        LOOP
                            BEGIN
                                INSERT INTO temp_run_connections
                                     ( run_id
                                     , connectedids)
                                SELECT DISTINCT v_runid
                                     , i.run_id AS connectedids
                                FROM   event_status i
                                WHERE  i.run_id &amp;lt; v_runid
                                AND    i.event_id = v_event_id
                                AND    i.rejected = 0
                                AND    i.run_id IN
                                       ( SELECT DISTINCT run_id
                                         FROM   temp_runs );

                                &amp;lt;&amp;lt;fetchnext&gt;&gt;
                                FETCH cust_incidents_cs INTO v_event_id;

                                IF cust_incidents_cs%NOTFOUND
                                THEN
                                    v_sql_status   := 2;
                                    v_fetch_status := -1;
                                ELSE
                                    v_sql_status   := 0;
                                    v_fetch_status := 0;
                                END IF;
                            END;
                        END LOOP;

                        CLOSE cust_incidents_cs;
                    END;
                
                    FETCH c_runs INTO v_runid;

                    IF c_runs%NOTFOUND
                    THEN
                        v_sql_status1   := 2;
                        v_fetch_status1 := -1;
                    ELSE
                        v_sql_status1   := 0;
                        v_fetch_status1 := 0;
                    END IF;
                END;
            END LOOP;
            CLOSE c_runs;
        END;
    END IF;

    SELECT COUNT(*)
    INTO   v_count_run_conns
    FROM   temp_run_connections;

    IF v_count_run_conns &gt; 0
    THEN
        OPEN pc_results_out FOR
            SELECT DISTINCT run_id, connectedids
            FROM   temp_run_connections;
    END IF;

END getupdatedrunids;&lt;/pre&gt;&lt;p&gt;His final version was much faster. See if you can spot the difference:&lt;/p&gt;&lt;pre&gt;CREATE OR REPLACE PROCEDURE getupdatedrunids
    ( p_customer_id  IN VARCHAR2 DEFAULT NULL
    , pc_results_out IN OUT SYS_REFCURSOR )
AS
BEGIN
    OPEN pc_results_out FOR
        SELECT DISTINCT e2.run_id, ic.run_id AS connectedids
        FROM   run_status r1
             , run_status r2
             , event_status e1
             , event_status e2
        WHERE  r1.customer_id = p_customer_id
        AND    r2.customer_id = r1.customer_id
        AND    e1.run_id = r2.run_id
        AND    e1.rejected = 0
        AND    e2.run_id = r1.run_id
        AND    e2.event_id = e1.event_id
        AND    e2.run_id &gt; e1.run_id
        AND    e2.rejected = 0
        ORDER BY 1, 2;

END getupdatedrunids;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/3669780349250863678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/3669780349250863678' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/3669780349250863678'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/3669780349250863678'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2008/04/fine-tuning.html' title='Fine tuning'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-118925958724705034</id><published>2008-02-10T12:35:00.000+00:00</published><updated>2008-02-10T19:36:24.669+00:00</updated><title type='text'>WREAK_APPLICATION_HAVOC</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://tkyte.blogspot.com/2008/01/why-do-people-do-this.html&quot;&gt;Tom Kyte recently blogged&lt;/a&gt; about the senseless and yet strangely common practice of coding something like this:&lt;/p&gt;&lt;pre&gt;WHEN OTHERS THEN
   RAISE_APPLICATION_ERROR(-20001,&#39;Following Error Occured:&#39; || SQLERRM);&lt;/pre&gt;
&lt;p&gt;which fairly obviously achieves nothing except take a standard message like this:&lt;/p&gt;&lt;pre&gt;ORA-06501: PL/SQL: program error
ORA-06512: at line 6&lt;/pre&gt;&lt;p&gt;and pointlessly scramble it into this:&lt;/p&gt;&lt;pre&gt;ORA-20001:&amp;nbsp;Following&amp;nbsp;Error&amp;nbsp;Occured:ORA-06501:&amp;nbsp;PL/SQL:&amp;nbsp;program&amp;nbsp;error
ORA-06512:&amp;nbsp;at&amp;nbsp;line&amp;nbsp;11&lt;/pre&gt;&lt;p&gt;which adds some meaningless text, hides the original line number, and miss-spells &quot;occurred&quot;. Not bad for a day&#39;s work.&lt;/p&gt;&lt;p&gt;It turned out that some people had been doing this for years because they were simply too stupid to realise that they didn&#39;t have to.&lt;/p&gt;&lt;p&gt;Anyway you know all this because you read Tom Kyte&#39;s blog. But have a look at &lt;a href=&quot;http://www.techonthenet.com/oracle/exceptions/sqlerrm.php&quot; rel=&quot;nofollow&quot;&gt;this helpful page of advice&lt;/a&gt; from Tech On The Net, under &lt;i&gt;&quot;Oracle/PLSQL: SQLERRM Function&quot;&lt;/i&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;You could use the SQLERRM function to raise an error as follows:&lt;/p&gt;&lt;pre&gt;EXCEPTION
   WHEN OTHERS THEN
      raise_application_error
      (-20001,&#39;An error was encountered - &#39;||SQLCODE||&#39; -ERROR- &#39;||SQLERRM);
END;&lt;/pre&gt;&lt;p&gt;Or you could log the error to a table as follows:&lt;/p&gt;&lt;pre&gt;EXCEPTION
   WHEN OTHERS THEN
      err_code := SQLCODE;
      err_msg := substr(SQLERRM, 1, 200);

      INSERT INTO audit_table (error_number, error_message)
      VALUES (err_code, err_msg);
END;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Now that is even better. The first example adds some meaningless text, hides the original line number, and duplicates the error code (unless it&#39;s a NO_DATA_FOUND exception, but let&#39;s not go there), to produce something like this:&lt;/p&gt;
&lt;pre&gt;ORA-20001:&amp;nbsp;An&amp;nbsp;error&amp;nbsp;was&amp;nbsp;encountered&amp;nbsp;-&amp;nbsp;-6501&amp;nbsp;-ERROR-&amp;nbsp;ORA-06501:&amp;nbsp;PL/SQL:&amp;nbsp;program&amp;nbsp;error&lt;br&gt;ORA-06512: at line 11&lt;/pre&gt;&lt;p&gt;The error logging example pointlessly captures &lt;tt&gt;SQLCODE&lt;/tt&gt; (nobody will ever use it), throws away all but the first 200 characters of the error stack, logs nothing about what happened, and fails to re-raise the exception so if you don&#39;t check the log you won&#39;t know anything went wrong until your customers start asking where their stuff is.&lt;/p&gt;
&lt;p&gt;Wouldn&#39;t it be great if there were, say, a Boolean third parameter to &lt;a href=&quot;http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/errors.htm#sthref2006&quot;&gt;RAISE_APPLICATION_ERROR&lt;/a&gt; that would make it retain the existing error stack, freeing up the message line for you to put something intelligent and helpful, like, I don&#39;t know,&lt;/p&gt;
&lt;pre&gt;BEGIN
    RAISE program_error;
EXCEPTION
    WHEN OTHERS THEN
        RAISE_APPLICATION_ERROR
        ( -20001
        , &#39;Biscuits cannot be ordered on a &#39; || TO_CHAR(SYSDATE,&#39;fmDay&#39;) ||
          &#39; without a hot beverage&#39;
        , &lt;b&gt;TRUE&lt;/b&gt;);
END;&lt;/pre&gt;&lt;p&gt;to produce something like this:&lt;/p&gt;&lt;pre&gt;ORA-20001: Biscuits cannot be ordered on a Sunday without a hot beverage
ORA-06512: at line 5
ORA-06501: PL/SQL: program error&lt;/pre&gt;&lt;p&gt;We can but dream.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/118925958724705034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/118925958724705034' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/118925958724705034'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/118925958724705034'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2008/02/wreakapplicationhavoc.html' title='WREAK_APPLICATION_HAVOC'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-2499204318775308735</id><published>2007-10-26T08:33:00.000+01:00</published><updated>2007-10-26T08:36:04.200+01:00</updated><title type='text'>Frameworkia</title><content type='html'>&lt;p&gt;We thought long and hard about possible titles for &lt;a href=&quot;http://forums.oracle.com/forums/thread.jspa?threadID=575556&amp;tstart=0&quot;&gt;this new PL/SQL development standard&lt;/a&gt; proposed on OTN, but we couldn&#39;t improve on the one it came with.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I want share a new IDEA to create a new standard PL/SQL developing:&lt;/p&gt;
&lt;pre&gt;&lt;br&gt;
Function &lt;name&gt;( Standard Buffer) return number
    variable Number;
    variable1 Varchar2;
begin
    variable := get from Standard Buffer;
    variable1 := get from Standard Buffer;

    { make your business }

    put in standard buffer your results
end;&lt;/br&gt;
&lt;/pre&gt;
&lt;p&gt;Give me feedback if you are interested at the new STANDARD called &lt;b&gt;&quot;FRAMEWORKIA&quot;&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;A lot possibilities are ready.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Do you see the genius of it?&lt;/p&gt;
&lt;p&gt;Er, no.&lt;/p&gt;
&lt;p&gt;Sensing that there were people who still needed convincing, user601181 posted some sample code developed using the new Frameworkia:&lt;/p&gt;
&lt;pre&gt;CREATE OR REPLACE FUNCTION iacore
    ( eobufferia IN OUT typeeodata )
    RETURN NUMBER
IS
    CURSOR cur_getroutingcondition
        ( idc_workflow IN VARCHAR2
        , idc_operation_node IN VARCHAR2 ) IS
        SELECT *
        FROM   wf_condition
        WHERE  id_workflow = idc_workflow
        AND    id_operation_node = idc_operation_node;

    rec_getroutingcondition cur_getroutingcondition%ROWTYPE;

    CURSOR cur_dobufferiaassign
        ( idc_workflow IN VARCHAR2
        , idc_operation_node IN VARCHAR2 ) IS
        SELECT *
        FROM   wf_assignement
        WHERE  id_workflow = idc_workflow
        AND    id_operation_node = idc_operation_node;

    rec_dobufferiaassign cur_dobufferiaassign%ROWTYPE;

    next_node         NUMBER;
    next_node_ck      NUMBER;
    stop_node         NUMBER;
    operation         VARCHAR2(256);
    operation_call    VARCHAR2(256);
    type_node         VARCHAR2(32);
    workflow          VARCHAR2(32);
    line              VARCHAR2(256);
    status_wf_v       VARCHAR2(3);
    pid_chain_node    NUMBER;
    ia_tid            VARCHAR2(64);
    ia_tid_micro      VARCHAR2(64);
    ret_code_default  NUMBER;
    ret_code          NUMBER;
    retval1           NUMBER;
    statementexc      VARCHAR2(256);
    schema_function   VARCHAR2(32);
    package_function  VARCHAR2(32);
    dblink_function   VARCHAR2(32);
    first_node_flag   VARCHAR2(2) := &#39;NO&#39;;
    id_debug_source   NUMBER;
    mapin_keyp        VARCHAR2(1024);

    headerbufferia typebufferia;
    assignbufferia typebufferia;
    checkbufferia  typebufferia;

    rec_wfnode               wf_node%ROWTYPE;
    rec_wffunctionsourcecode wf_function_source_code%ROWTYPE;
    rec_wflogger             wf_logger%ROWTYPE;
    rec_wfbusiness           wf_business%ROWTYPE;
    rec_wffieldmapping       wf_fieldmapping%ROWTYPE;
BEGIN
    headerbufferia := eobufferia(1);

    workflow := frameworkia.getvalue(headerbufferia,&#39;ID_WORKFLOW&#39;);

    ---- DETERMINO QUALE NODO INVOCARE
    pid_chain_node := frameworkia.getvalue(headerbufferia,&#39;WF_NODE_ID&#39;);

    ----- SE IL NODO E&#39; NULL ALLORA E&#39; IL PRIMO NODO
    IF pid_chain_node IS NULL
    THEN
        -------DETERMINO HANDLER E FILENAME PER IL LOGGER
        SELECT *
        INTO   rec_wflogger
        FROM   wf_logger
        WHERE  id_workflow = workflow;
        -- rec_WfLogger.ID_WORKFLOW
        -- rec_WfLogger.ID_DEBUG_LEVEL
        -- rec_WfLogger.ID_DIRHANDLER
        -- rec_WfLogger.ID_FILENAME

        --------INSERISCO NELL&#39;HEADER
        frameworkia.setvalue
        ( headerbufferia
        , &#39;ID_DEBUG_WF&#39;
        , rec_wflogger.id_debug_level );

        frameworkia.setvalue
        ( headerbufferia
        , &#39;ID_DIRHANDLER&#39;
        , rec_wflogger.id_dirhandler );

        frameworkia.setvalue
        ( headerbufferia
        , &#39;ID_FILENAME&#39;
        , rec_wflogger.id_filename );

        frameworkia.setvalue
        ( headerbufferia
        , &#39;CHARACTER_EVIDENCE&#39;
        , &#39;§§§§§§§§§§§§§§§§§§§§&#39; );

        -------DETERMINO L&#39;ID NODE
        SELECT wf_node_id
        INTO   pid_chain_node
        FROM   wf_node
        WHERE  id_workflow = workflow
        AND    wf_first_node = &#39;YES&#39;;

        SELECT *
        INTO   rec_wfnode
        FROM   wf_node
        WHERE  id_workflow = workflow
        AND    wf_first_node = &#39;YES&#39;;

        frameworkia.setvalue
        ( headerbufferia
        , &#39;WF_NODE_ID&#39;
        , rec_wfnode.wf_node_id );

        SELECT b.status
        INTO   status_wf_v
        FROM   wf_node a
             , wf_name b
        WHERE  a.id_workflow = workflow
        AND    a.wf_node_id = rec_wfnode.wf_node_id
        AND    a.id_workflow = b.id_workflow;

        IF status_wf_v = &#39;OFF&#39;
        THEN
            RETURN -1;
        END IF;

        ia_tid := frameworkia.getvalue(headerbufferia,&#39;IA_TID&#39;);
        ret_code_default := 0;
        ret_code         := 0;

        frameworkia.setvalue
        ( headerbufferia
        , &#39;RET_CODE_DEFAULT&#39;
        , ret_code_default );

        frameworkia.setvalue
        ( headerbufferia
        , &#39;RET_CODE&#39;
        , ret_code);

        IF ia_tid IS NULL
        THEN
            ia_tid := &#39;TIA&#39; || dbms_random.STRING(&#39;U&#39;,1 * 1 + 6) ||
                      TO_CHAR(SYSTIMESTAMP,&#39;YYYYMMDDHH24MISSFF6&#39;);

            frameworkia.setvalue
            ( headerbufferia
            , &#39;IA_TID&#39;
            , ia_tid );
        END IF;&lt;/pre&gt;
&lt;p&gt;That&#39;s just the first hundred lines, and I&#39;ve formatted it. The complete &lt;tt&gt;iacore&lt;/tt&gt; function was well over 600 lines long.&lt;/p&gt;
&lt;p&gt;I for one welcome the new standard.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/2499204318775308735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/2499204318775308735' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2499204318775308735'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/2499204318775308735'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2007/10/frameworkia.html' title='Frameworkia'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15861274.post-1091133067457129331</id><published>2007-08-10T11:16:00.000+01:00</published><updated>2007-08-10T13:47:25.561+01:00</updated><title type='text'>Welcome back</title><content type='html'>&lt;p&gt;Our guest administrator &quot;Splogger&quot; has now left the building, along with his page of helpful links to items on Amazon.com and a range of gentlemen&#39;s health products.&lt;/p&gt;&lt;p&gt;Suspiciously, a couple of days before he arrived we were taken off air by Blogger&#39;s spambots, presumably alerted by the amount of &lt;a href=&quot;http://radiofreetooting.blogspot.com/2007/07/roy-batty-writes.html&quot;&gt;irrelevant, repetitive, and nonsensical text&lt;/a&gt; and links to Viagra sites they found here. &lt;a href=&quot;http://bloggerstatusforreal.blogspot.com/2006/07/stolen-computers.html&quot;&gt;From what I read&lt;/a&gt;, it seems possible that the Blogger automated suspension to prevent blog spam might have actually left the account vulnerable to blog spammers. As ironies go, that is up there with rain on your wedding day and good advice that you just didn&#39;t take.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://oracle-wtf.blogspot.com/feeds/1091133067457129331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment/fullpage/post/15861274/1091133067457129331' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/1091133067457129331'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/15861274/posts/default/1091133067457129331'/><link rel='alternate' type='text/html' href='https://oracle-wtf.blogspot.com/2007/08/welcome-back.html' title='Welcome back'/><author><name>William Robertson</name><uri>http://www.blogger.com/profile/06976436975493102341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://www.williamrobertson.pwp.blueyonder.co.uk/gifs/starfield.gif'/></author><thr:total>9</thr:total></entry></feed>