﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Steven Feuerstein's Blog</title>
    <description>Steven Feuerstein is considered one of the world's leading experts on the Oracle PL/SQL language, having written ten books on PL/SQL (all published by O'Reilly Media, including Oracle PL/SQL Programming. Steven has been developing software since 1980, spent five years with Oracle (1987-1992) and has served as PL/SQL Evangelist for Quest Software since January 2001. He is also an Oracle ACE Director. He writes regularly for Oracle Magazine, which named him the PL/SQL Developer of the Year in both 2002 and 2006.
&lt;p /&gt;
Steven's blog provides advice and code that you can put to immediate use in your world of programming.
&lt;p /&gt;
&lt;font color="#003366" size="3"&gt;&lt;strong&gt;Recent postings on PL/SQL: &lt;/font&gt;&lt;/strong&gt;</description>
    <link>http://www.toadworld.com/BLOGS/tabid/67/BlogId/13/Default.aspx</link>
    <language>en-US</language>
    <managingEditor>Steven Feuerstein</managingEditor>
    <webMaster>webmaster@toadworld.com</webMaster>
    <pubDate>Sat, 04 Jul 2009 09:31:03 GMT</pubDate>
    <lastBuildDate>Sat, 04 Jul 2009 09:31:03 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>Blog RSS Generator Version 3.2.0.15477</generator>
    <item>
      <title>Oracle PL/SQL Programming 5th Edition - "Early Warning"</title>
      <description>&lt;div&gt;I was on the phone with a &lt;a href="http://www.quest.com/code-tester-for-oracle"&gt;Quest Code Tester&lt;/a&gt; user the other day and he asked me if I was working on the next edition of my original "magnum opus", Oracle PL/SQL Programming, which would include Oracle11g features.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I cannot describe to you how good it felt to say: "No, I'm not working on it. I'm &lt;em&gt;finished&lt;/em&gt; working on it."&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In fact, just last week, my editor (Debby Russell) sent all the chapters to the production department, so that they could begin the long process of converting Word docs into an actual, publishable book.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;This fifth edition will cover all features of Oracle11g, through Release 2 - which means it will not be published until the fall, probably at the same time as Oracle Open World (week of October 12), or whenever Oracle formally announces availability of Release 2.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;We have also added a single, very extensive chapter on optimizing performance of PL/SQL code.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;You can see more information about the book and even pre-order the book at:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://oreilly.com/catalog/9780596514464/%23top"&gt;http://oreilly.com/catalog/9780596514464/#top&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;But you may want to hold off a little bit on that pre-order. I am considering offering the ability to order the book directly from me, and have it signed whatever personalized message you request. So....you will hopefully see an update about that soon!&lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/390/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/390/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=390</guid>
      <pubDate>Wed, 10 Jun 2009 18:19:00 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=390</trackback:ping>
    </item>
    <item>
      <title>Naming Conventions and Coding Standards, the Feuerstein Way</title>
      <description>&lt;div&gt;I am often asked about the naming conventions and coding standards that I use. My answer is usually a combination of muttering and vague statements and hand-waving.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;That's because I have a confession: I don't have a single naming conventions and coding standards document that I use. Why not? Because I am a software developer! That is, I feel (well, I &lt;em&gt;am&lt;/em&gt;) very busy, overwhelmed by deadlines. I don't feel like I have the time to stop and write down the few rules that I might actually follow more of less consistently. And it seems that a part of me is somewhat resistant to being accountable to a standard. Sound familiar?&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Sigh...unfortunately (no, make that &lt;em&gt;very&lt;/em&gt; fortunately), lots of other PL/SQL developers look to me for advice about how to "do things right." Ah, the pressure, the pressure!&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Ah, the hypocrisy. That's what it really comes down to: I am a big hypocrite. I routinely violate just about every best practice I push on others. I sound high and mighty, but when I write code, I feel the same pull to do the quick and dirty.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So I've decided to take a few moments out of my various plane rides (I am now - when I started this document, anyway - flying from Manchester, UK, to Sweden to do a presentation to the Stockholm OUG, then a couple of days of customer visits in Stockholm and Milan, then two days of training for Oracle in Helsinki) to jot down what have become my &lt;em&gt;de facto&lt;/em&gt; coding standards.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;You see, I &lt;em&gt;do&lt;/em&gt; have standards, and I even follow them, more or less. I just don't like to bother writing them down.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So that's what (finally) you'll find &lt;u&gt;&lt;a href="http://www.toadworld.com/LinkClick.aspx?link=580&amp;tabid=67"&gt;here&lt;/a&gt;&lt;/u&gt;. It's a combination of the naming conventions I follow, certain naming conventions with which I disagree, and a variety of other suggestions. I hope you find it useful. I'm not going to make much of an effort to justify my approach or explain away the inconsistencies. I'll just show you what I do and you can decide for yourself if you'd like to use my path as a model for your own journey.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I also hereby declare this to be a &lt;em&gt;work in progress&lt;/em&gt;. So...&lt;/div&gt;
&lt;ul&gt;
    &lt;li&gt;If you have disagreements with my approach, &lt;u&gt;&lt;a href="http://www.toadworld.comhttp://www.toadworld.commailto:steven.feuerstein@quest.com?subject=PL%2FSQL%20Standards"&gt;let me know&lt;/a&gt;&lt;/u&gt;. Perhaps I will agree with &lt;em&gt;you&lt;/em&gt;, and change my document (you will get the credit).&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;If you have a suggestion for something to add to the document, &lt;u&gt;&lt;a href="http://www.toadworld.comhttp://www.toadworld.commailto:steven.feuerstein@quest.com?subject=PL%2FSQL%20Standards"&gt;send it to me&lt;/a&gt;&lt;/u&gt;. If I like it, I will put it into the document (and give you credit).&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;If you would like to offer your own set of naming conventions and coding standards to the world of PL/SQL developers, I will add it to the webpage.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt; The URL for my standards document is:  &lt;a href="http://www.ToadWorld.com/SF/standards"&gt;&lt;strong&gt;www.ToadWorld.com/SF/standards&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/381/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/381/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=381</guid>
      <pubDate>Thu, 28 May 2009 17:32:00 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=381</trackback:ping>
    </item>
    <item>
      <title>A Classic Error in My Monthly Puzzle!</title>
      <description>&lt;div&gt;
&lt;p&gt;Every month, a Toad World newsletter goes out to thousands of Toad users and it includes a monthly puzzle that I write. Last month's puzzle went like this:&lt;/p&gt;
&lt;blockquote&gt;Which of the following blocks &lt;strong&gt;does not&lt;/strong&gt; contain an infinite loop?
&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;&lt;font face="Arial"&gt;A.&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
   l_line VARCHAR2(32767);&lt;br /&gt;
   l_file UTL_FILE.file_type :=&lt;br /&gt;
      UTL_FILE.fopen ('C:\temp', 'my_file.txt', 'R');&lt;br /&gt;
BEGIN&lt;br /&gt;
   LOOP&lt;br /&gt;
      UTL_FILE.get_line (l_file, l_line);&lt;br /&gt;
   END LOOP;&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Arial"&gt;B.&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
BEGIN&lt;br /&gt;
   LOOP&lt;br /&gt;
      DBMS_OUTPUT.PUT_LINE ('abc');&lt;br /&gt;
   END LOOP;&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Arial"&gt;C.&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
DECLARE&lt;br /&gt;
   l_keep_going BOOLEAN;&lt;br /&gt;
BEGIN&lt;br /&gt;
   WHILE (l_keep_going)&lt;br /&gt;
   LOOP&lt;br /&gt;
      DBMS_OUTPUT.PUT_LINE ('abc');&lt;br /&gt;
      l_keep_going := SYSDATE IS NOT NULL;&lt;br /&gt;
   END LOOP;&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Arial"&gt;D.&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
BEGIN&lt;br /&gt;
   &lt;&lt;start_of_block&gt;&gt;&lt;br /&gt;
   DBMS_OUTPUT.PUT_LINE ('abc');&lt;br /&gt;
   GOTO start_of_block;&lt;br /&gt;
END;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I told my friends at Toad World that the answer was (A), because  UTL_FILE.GET_LINE raises the NO_DATA_FOUND exception when you read past the end of the file. Since files cannot be of infinite size, you will eventually read to the end of the file and then the loop will terminate.&lt;/p&gt;
&lt;p&gt;And I wiped my hands of that puzzle. Unfortunately, it came back to haunt me in the form of a message from the Toad World editor-in-chief:&lt;/p&gt;
&lt;blockquote&gt;"Steven, normally I don't worry when I get just a few responses to the puzzler with answers different from what you’ve told us is the correct one, but this month I’m wondering if we missed something because we’ve had close to 50% of the respondents picking the wrong answer (C), and explaining their choice as follows: The value of l_keep_going is not initialized to TRUE and is therefore unknown. It will not enter the loop and therefore the loop is not infinite."&lt;/blockquote&gt;
&lt;p&gt;Oh my, oh my. They are so right. And I was so sloppy. And I was so over-confident, that I did not ask anyone with PL/SQL experience to proof my Q&amp;A.&lt;/p&gt;
&lt;p&gt;Let's take a closer look at choice C:&lt;/p&gt;
&lt;blockquote&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;DECLARE&lt;br /&gt;
   l_keep_going BOOLEAN;&lt;br /&gt;
BEGIN&lt;br /&gt;
   WHILE (l_keep_going)&lt;br /&gt;
   LOOP&lt;br /&gt;
      DBMS_OUTPUT.PUT_LINE ('abc');&lt;br /&gt;
      l_keep_going := SYSDATE IS NOT NULL;&lt;br /&gt;
   END LOOP;&lt;br /&gt;
END;&lt;/font&gt;&lt;/font&gt;&lt;/blockquote&gt;
&lt;p&gt;I declare a variable that I will use to determine termination of the loop, but I neglected to provide a non-null default value. As a result, the WHILE condition fails immediately, the loop body never executes even once – and certainly not an infinite number of times!&lt;/p&gt;
&lt;p&gt;This kind of bug often manifests in this form as well:&lt;/p&gt;
&lt;blockquote&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;DECLARE&lt;br /&gt;
   l_counter PLS_INTEGER;&lt;br /&gt;
BEGIN&lt;br /&gt;
   LOOP&lt;br /&gt;
      do_something;&lt;br /&gt;
      l_counter := l_counter + 1;&lt;br /&gt;
      EXIT WHEN l_counter = 100;&lt;br /&gt;
   END LOOP;&lt;br /&gt;
END;&lt;/font&gt;&lt;/font&gt;&lt;/blockquote&gt;
&lt;p&gt;Again, I have failed to initialize my counter (likely it would be set to 1) and in this case the result is an infinite loop.&lt;/p&gt;
&lt;p&gt;Hey, that must have been what I meant to use as choice C! Yeah, right.&lt;/p&gt;
&lt;p&gt;So the lessons to be learned are:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Anyone can and everyone does make mistakes. Including the self-named PL/SQL Evangelist. &lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;Code review is a critical component of high quality development. All critical code (and what isn't?) should be looked at by another human being before it goes "live."&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/365/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/365/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=365</guid>
      <pubDate>Mon, 27 Apr 2009 15:47:00 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=365</trackback:ping>
    </item>
    <item>
      <title>An interview with Steven Feuerstein</title>
      <description>&lt;div&gt;In case you simply can't get enough of Steven Feuerstein (no, I don't generally talk about my self in the third person or in the royal "we"), I invite you to check out this &lt;a href="http://www.databasedesign-resource.com/interview-with-steven-feuerstein.html"&gt;interview&lt;/a&gt;. I had an awful lot of fun answering the questions, and you might be entertained reading them.&lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/364/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/364/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=364</guid>
      <pubDate>Thu, 23 Apr 2009 01:06:00 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=364</trackback:ping>
    </item>
    <item>
      <title>A handy string parsing utility - extended</title>
      <description>&lt;div&gt;It's truly one of the oddities of the PL/SQL language that it does not offer a delimited string parsing program. The closest we can get is DBMS_UTILITY.COMMA_TO_TABLE, and that is sadly deficient (it only parses comma-delimited strings and each item between the commas must be a valid PL/SQL identifier).&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So I built one myself (the parse package) and put it in the &lt;u&gt;&lt;a href="http://www.toadworld.com/Portals/0/stevenf/demo.zip"&gt;demo.zip file&lt;/a&gt;&lt;/u&gt; that accompanies my training materials. You will find it in the parse.pkg file. For the past few years it has consisted of a single function that accepts a delimited list and returns a collection of the items in the list.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;On a flight from London Heathrow to Istanbul in April 2009, though, I decided to make this package a bit more useful. I added two overloadings of the string_to_list function so that you can now easily parse (1) a string that contains multiple lists and (2) a string that contains multiple lists, each of which has a name.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So I have updated the demo.zip download to include this new version, and I thought I would bring it to your attention. The demo.zip contains about 2000 files and there is no index. So it's just a tad bit difficult to find the useful programs within it.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I have also created a &lt;u&gt;&lt;a href="http://www.toadworld.com/LinkClick.aspx?link=430&amp;tabid=67"&gt;Quest Code Tester for Oracle&lt;/a&gt;&lt;/u&gt; test definition to verify the behavior of these functions. If you would like to check that out, install Quest Code Tester 1.8.3 or higher (available as a beta &lt;u&gt;&lt;a href="http://unittest.inside.quest.com/beta.jspa"&gt;here&lt;/a&gt;&lt;/u&gt; until mid-May 2009), and then import the Q#PARSE.qut file (also in demo.zip).&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Here are examples of using the three different overloadings of parse.string_to_list:&lt;/div&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px"&gt;
&lt;pre&gt;DECLARE&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;l_list&lt;span&gt;   &lt;/span&gt;parse.items_tt;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;l_list:=parse.string_to_list('a,b,c,d',',');&lt;br /&gt;END;&lt;br /&gt;/&lt;/pre&gt;
&lt;pre&gt;DECLARE&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;l_list&lt;span&gt;   &lt;/span&gt;parse.nested_items_tt;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;l_list:=parse.string_to_list('a,b,c,d|1,2,3,4','|',',');&lt;br /&gt;END;&lt;br /&gt;/&lt;/pre&gt;
&lt;pre&gt;DECLARE&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;l_list&lt;span&gt;   &lt;/span&gt;parse.named_nested_items_tt;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;l_list:=parse.string_to_list('a,b,c,d|1,2,3,4','|',',');&lt;br /&gt;END;&lt;br /&gt;/&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;div&gt;The third overloading, which returns a collection of type parse.named_nested_items_tt, also offers a demonstration of the elegance and usefulness of multi-level and string-indexed collections.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I hope you find the parse package useful.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;And I hope that someday we can happily deprecate it, for the very good reason that PL/SQL finally offers one of its own.&lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/362/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/362/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=362</guid>
      <pubDate>Mon, 13 Apr 2009 16:57:00 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=362</trackback:ping>
    </item>
    <item>
      <title>Run an OS command from within PL/SQL</title>
      <description>&lt;div&gt;
&lt;p&gt;Developers are hard people to satisfy. Oracle gives us this incredibly robust, powerful and easy to use database programming language – and all we can do is complain about what it &lt;em&gt;doesn't &lt;/em&gt;do for us.&lt;/p&gt;
&lt;p&gt;Well, that's reality for you: PL/SQL is powerful and robust and easy to use, but also very narrowly focused. So if you want it to do something outside of its area of expertise, sometimes you have to jump through a few more hoops than you'd like.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;A good example of this is figuring out how to run an OS command from a PL/SQL block. There is not, unfortunately, a native "execute host command" statement within PL/SQL . Instead, Oracle offers (at least) three ways to do this:&lt;/div&gt;
&lt;ul type="disc"&gt;
    &lt;li&gt;Use the DBMS_SCHEDULER package&lt;/li&gt;
    &lt;li&gt;Run a Java method to execute your command.&lt;/li&gt;
    &lt;li&gt;Run a C program to execute your command.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DBMS_SCHEDULER offers the simplest and most intuitive solution, especially from the standpoint of DBA and system administration tasks. I talk about this solution on the OTN Best Practice page:&lt;/p&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px"&gt;
&lt;p&gt;&lt;a href="http://apex.oracle.com/pls/otn/f?p=2853:4:1544539351000407::NO::P4_QA_ID:16282"&gt;http://apex.oracle.com/pls/otn/f?p=2853:4:1544539351000407::NO::P4_QA_ID:16282&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I will, in this Toad World blog, offer brief guidance on the other two options. It is very unlikely that you will be able to rely solely on the content below to implement either approach. Instead, I suggest you use this as a starting point and then from there visit the detailed &lt;a href="http://tahiti.oracle.com"&gt;&lt;strong&gt;Oracle documentation&lt;/strong&gt;&lt;/a&gt; and/or the full chapter coverage of both these techniques in my &lt;a href="http://www.oreillynet.com/cs/catalog/view/au/344"&gt;&lt;strong&gt;Oracle PL/SQL Programming&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;font size="3"&gt;Executing an OS command with Java&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With the Java approach, you will take these steps:&lt;/p&gt;
&lt;/div&gt;
&lt;ol&gt;
    &lt;li&gt;Find the Java class that implements host command execution.&lt;/li&gt;
    &lt;li&gt;Build a class that invokes that host command method. Let's call it HostCommand.&lt;/li&gt;
    &lt;li&gt;Build a PL/SQL program that calls a method in HostCommand to run your command.&lt;/li&gt;
    &lt;li&gt;Acquire the privileges needed to execute host commands via Java in the database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let's go through each of these steps.&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Find the Java class that implements host command execution.&lt;/strong&gt;&lt;br /&gt;
    &lt;br /&gt;
    Objects of the java&lt;strong&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lang&lt;strong&gt;.&lt;/strong&gt;Runtime&lt;/span&gt; class include an &lt;em&gt;exec&lt;/em&gt; method that will execute a host command.&lt;br /&gt;
     &lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Build a class that invokes that host command method. Let's call it HostCommand.&lt;/strong&gt;&lt;br /&gt;
    &lt;br /&gt;
    Here's code to create a new Java class in the database to invoke this command for the Windows XP operating system:&lt;br /&gt;
    &lt;br /&gt;
    &lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED&lt;/font&gt; &lt;font color="#ff0000"&gt;"UTLcmd"&lt;/font&gt;&lt;br /&gt;
    &lt;font color="#0000ff"&gt;AS&lt;/font&gt; import java.lang.Runtime;&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;br /&gt;
    public class execHostCommand&lt;br /&gt;
    { &lt;br /&gt;
      public static void execute (String command) &lt;br /&gt;
        throws java.io.IOException&lt;br /&gt;
      {&lt;br /&gt;
       String osName = System.getProperty("&lt;font color="#0000ff"&gt;os.name&lt;/font&gt;");&lt;br /&gt;
       if(osName.equals("&lt;font color="#0000ff"&gt;Windows XP&lt;/font&gt;"))&lt;br /&gt;
           command = "&lt;font color="#0000ff"&gt;cmd /c&lt;/font&gt; " + command;&lt;br /&gt;
       Runtime rt = java.lang.Runtime.getRuntime();&lt;br /&gt;
       rt.exec(command);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    /&lt;br /&gt;
    &lt;/font&gt;&lt;br /&gt;
    You can easily modify the execute method to support other operating systems based on the value of osName.&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Build a PL/SQL program that calls a method in HostCommand to run your command.&lt;br /&gt;
    &lt;/strong&gt;&lt;font face="Courier New" size="2"&gt;&lt;br /&gt;
    CREATE OR REPLACE PACKAGE host_command IS&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;  PROCEDURE execute (cmd IN VARCHAR2) AS LANGUAGE JAVA NAME&lt;br /&gt;
    &lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;           &lt;/span&gt;'execHostCommand.execute(java.lang.String)';&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;END;&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;/&lt;br /&gt;
    &lt;/font&gt; &lt;br /&gt;
    Notice that I "map" the VARCHAR2 datatype to the java.lang.String class in my call to the new Java method.&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Acquire the privileges needed to execute host commands via Java in the database.&lt;br /&gt;
    &lt;/strong&gt; &lt;br /&gt;
    You need special privileges to execute host commands from within the database through Java. Otherwise when you try to execute your command you will see an error like this (the error message will vary depending on what you are trying to do):&lt;br /&gt;
     &lt;br /&gt;
    &lt;img height="183" alt="" width="456" src="http://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog032709-1.gif" /&gt;&lt;br /&gt;
     &lt;br /&gt;
    One way to obtain these privileges to have the JAVASYSPRIV role granted to your schema. This role contains all the privileges you need (and more).&lt;br /&gt;
     &lt;br /&gt;
    For a more nuanced approach to granting the required privileges, you can also use the Java security API available in the Oracle database. For example, if I want to delete a file using a host command (perhaps it is not accessible through UTL_FILE), I will need to grant the following privileges to the schema in which the command is executed, such as HR:&lt;br /&gt;
    &lt;font size="2"&gt;&lt;br /&gt;
    &lt;font face="Courier New"&gt;BEGIN&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;   &lt;/span&gt;DBMS_JAVA.grant_permission ('HR'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, 'SYS:java.io.FilePermission'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, '&lt;&lt;all files=""&gt;&lt;/all&gt;&gt;'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, 'execute'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                              &lt;/span&gt;);&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;   &lt;/span&gt;DBMS_JAVA.grant_permission ('HR'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, 'SYS:java.lang.RuntimePermission'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, 'writeFileDescriptor'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, ''&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                              &lt;/span&gt;);&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;   &lt;/span&gt;DBMS_JAVA.grant_permission ('HR'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, 'SYS:java.lang.RuntimePermission'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, 'readFileDescriptor'&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                             &lt;/span&gt;, ''&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;                              &lt;/span&gt;);&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;END;&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;/&lt;/font&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;font size="3"&gt;Executing an OS command with C&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To use C, you must define an &lt;em&gt;external procedure&lt;/em&gt; and then invoke it within your PL/SQL block. It is not possible within this article to cover completely all the steps and issues involved in setting up such an external procedure. I will, instead, cover the highlights. For the full details, check out Oracle documentation at:&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;blockquote dir="ltr" style="margin-right: 0px"&gt;
&lt;div&gt;&lt;a href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_extern_proc.htm#ADFNS010"&gt;http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_extern_proc.htm#ADFNS010&lt;/a&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;and also read Chapter 27 of Oracle PL/SQL Programming, 4&lt;sup&gt;th&lt;/sup&gt; edition, in which my co-author Bill Pribyl thoroughly explains external procedures.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;As with Java, you will need help your database administrator to supply the privileges needed to execute your host command in C.&lt;/p&gt;
&lt;p&gt;Here are the steps to follow with C:&lt;/p&gt;
&lt;/div&gt;
&lt;ol&gt;
    &lt;li&gt;Find (or build) the C program that implements host command execution.&lt;/li&gt;
    &lt;li&gt;Save the C source to a file and generate a shared library for it.&lt;/li&gt;
    &lt;li&gt;Save the library file where Oracle can find it.&lt;/li&gt;
    &lt;li&gt;Define a library inside Oracle that is associated with the shared library on disk.&lt;/li&gt;
    &lt;li&gt;Create a PL/SQL wrapper for the C function.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let's go through each of these steps.&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Find (or build) the C program that implements host command execution.&lt;/strong&gt;&lt;br /&gt;
     &lt;br /&gt;
    The C system function executes an operating system command. So I build a simple C function, extprocsh(), that accepts a string and passes it to the &lt;span&gt;&lt;font color="#ff0000"&gt;system&lt;/font&gt;&lt;/span&gt; function for execution:&lt;br /&gt;
    &lt;font size="2"&gt; &lt;br /&gt;
    &lt;font face="Courier New"&gt;int extprocsh(char *cmd)&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;{&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;   return system(cmd);&lt;br /&gt;
    &lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt; &lt;br /&gt;
    The function returns the result code as provided by &lt;span&gt;&lt;font color="#ff0000"&gt;system&lt;/font&gt;&lt;/span&gt;, a function normally found in the C runtime library (&lt;span&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;libc&lt;/font&gt;&lt;/em&gt;&lt;/span&gt;) on Unix, or in &lt;span&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;msvcrt.dll&lt;/font&gt;&lt;/em&gt;&lt;/span&gt; on Microsoft platforms.&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Save the C source to a file and generate a shared library for it.&lt;br /&gt;
    &lt;/strong&gt; &lt;br /&gt;
    I save the source code in a file named &lt;span&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;extprocsh.c&lt;/font&gt;&lt;/em&gt;&lt;/span&gt;. I then use the GNU C compiler to generate a shared library. On a 64-bit Solaris machine running GCC 3.4.2 and Oracle Database 10g Release 2, the following compiler command worked to create a shared library:&lt;br /&gt;
    &lt;font size="2"&gt; &lt;br /&gt;
    &lt;font face="Courier New"&gt;gcc -m64 extprocsh.c -fPIC -G -o extprocsh.so&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt; &lt;br /&gt;
    Similarly, on Microsoft Windows XP Pro running GCC 3.2.3 from Minimal GNU for Windows (MinGW), also with Oracle Database 10g Release 2, this works:&lt;br /&gt;
    &lt;font size="2"&gt; &lt;br /&gt;
    &lt;font face="Courier New"&gt;c:\MinGW\bin\gcc extprocsh.c -shared -o extprocsh.dll&lt;br /&gt;
     &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Save the library file where Oracle can find it.&lt;br /&gt;
    &lt;/strong&gt; &lt;br /&gt;
    These commands generate a shared library file, &lt;span&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;extprocsh.so&lt;/font&gt;&lt;/em&gt;&lt;/span&gt; or &lt;span&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;extprocsh.dll&lt;/font&gt;&lt;/em&gt;&lt;/span&gt;. Now I need to put the library file somewhere that Oracle can find it. The default locations for Windows and Unix respectively are:&lt;br /&gt;
    &lt;span&gt;&lt;font size="2"&gt;&lt;font color="#ff6600"&gt;&lt;em&gt; &lt;br /&gt;
    &lt;font face="Courier New" color="#ff0000"&gt;$ORACLE_HOME/bin&lt;br /&gt;
    &lt;/font&gt;&lt;/em&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;em&gt;&lt;font size="2"&gt;&lt;font face="Courier New" color="#ff0000"&gt;$ORACLE_HOME/lib&lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;/em&gt;&lt;/span&gt; &lt;br /&gt;
    If you want to use a non-default location, you will need to edit the listener configuration file and supply path value(s) for the ENVS="EXTPROC_DLLS...".&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Define a library inside Oracle that is associated with the shared library on disk.&lt;br /&gt;
    &lt;/strong&gt; &lt;br /&gt;
    After copying the file and/or making adjustments to the listener, you will then define a "library" inside Oracle to point to the DLL. For example:&lt;br /&gt;
    &lt;font face="Courier New" size="2"&gt; &lt;br /&gt;
    CREATE OR REPLACE LIBRARY extprocshell_lib &lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;   AS '/u01/app/oracle/local/lib/extprocsh.so';   &lt;font color="#009933"&gt;&lt;strong&gt;-- Unix&lt;br /&gt;
    &lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;     &lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;CREATE OR REPLACE LIBRARY extprocshell_lib&lt;br /&gt;
    &lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;   AS 'c:\oracle\local\lib\extprocsh.dll';      &lt;font color="#009933"&gt;&lt;strong&gt;-- Microsoft&lt;br /&gt;
    &lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt; &lt;br /&gt;
    &lt;strong&gt;Note:&lt;/strong&gt; performing this step requires Oracle’s CREATE LIBRARY privilege.&lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Create a PL/SQL wrapper for the C function.&lt;br /&gt;
    &lt;/strong&gt; &lt;br /&gt;
    Now I can create a PL/SQL call specification which uses the newly created library:&lt;br /&gt;
    &lt;font face="Courier New" size="2"&gt; &lt;br /&gt;
    CREATE OR REPLACE FUNCTION exec_host_command (cmd IN VARCHAR2)&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;   RETURN PLS_INTEGER&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;AS&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;   LANGUAGE C&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;   LIBRARY extprocshell_lib&lt;br /&gt;
    &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;   NAME "extprocsh"&lt;br /&gt;
    &lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;   PARAMETERS (cmd STRING, RETURN INT);&lt;/font&gt;&lt;/font&gt;
    &lt;p&gt;Then, assuming that your DBA has set up the system environment to support external procedures, the exec_host_command function can now be called anywhere you can invoke a PL/SQL function. &lt;/p&gt;
    &lt;p&gt;Note that these operating system commands will execute with the same privileges as the Oracle Net listener that spawns the &lt;span&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;extproc&lt;/font&gt;&lt;/em&gt;&lt;/span&gt; process. &lt;br /&gt;
     &lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt; &lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/356/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/356/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=356</guid>
      <pubDate>Fri, 27 Mar 2009 13:14:00 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=356</trackback:ping>
    </item>
    <item>
      <title>Automatic refactoring in PL/SQL tools – Part 3</title>
      <description>&lt;div&gt;In &lt;a href="http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=321"&gt;part 1&lt;/a&gt; of this series, I reviewed the automated refactoring features in SQL Developer. In &lt;a href="http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=328"&gt;part 2&lt;/a&gt;, I checked out PL/SQL Developer's refactoring features. Now, it's time for Toad.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Differently from both PL/SQL Developer and SQL Developer, Toad does not have a separate Refactoring right click menu. Instead, the main (and most important) refactoring is explicitly visible from the right click menu in the editor: Extract Procedure.&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;img height="660" alt="" width="713" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-1.gif" /&gt;&lt;/p&gt;
&lt;p&gt;Let's dive right in and explore this feature. When I select Extract procedure...., I see the following window:&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-2.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;When I choose the default (and check the "With replace option" – which I would argue should be checked by default), Toad then opens another tab in my editor and fills it with this:&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-3.gif" /&gt;&lt;/p&gt;
&lt;p&gt;It did not automatically compile the procedure for me, which I actually like. I'd rather be responsible for the act of compiling - and perhaps over-writing an existing procedure of the same name, which in fact would have occurred here, as you can see from my list of existing procedures:&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-4.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The extraction was smart; I ended up with a procedure that has two formal parameters, ensuring that it is completely independent of the original context (the use_cursor procedure). That original procedure is also changed appropriately:&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-5.gif" /&gt;&lt;/p&gt;
&lt;p&gt;If I choose the "local procedure" option, then Toad correctly creates a local subprogram for me:&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-6.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  a very handy and competent refactoring. It performs correctly under all tested circumstances (PL/SQL Developer had a number of bugs, which I have been told is fixed in a later release than I used). My suggestions for improvement? Let me specify that I want the stored program to be not schema-level, but inside a package. And if I could choose an existing package to put it &lt;em&gt;into&lt;/em&gt;, well, that would be fantastic! I could cut down on the number of independent stored program units (I try to avoid schema-level functions and procedures whenever possible), and increase the likelihood of code re-use.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;That is the only truly automatic refactoring feature in Toad, at least from my perspective. But for the sake of performing a true apples-to-apples comparison, you may recall that SQL Developer offers these options on its refactoring menu:&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-7.gif" /&gt;&lt;/p&gt;
&lt;p&gt;I don't really consider case conversion to be refactoring, but in case you do, you can certainly do that in Toad, either under the Edit menu in Toad or  on Editor toolbar (or you can simply use the keyboard shortcuts):&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog030909-8.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Toad doesn't offer any kind of rename feature, as does SQL Developer and PL/SQL Developer, but both of those implementations were a bit hobbled in how they worked. I doubt they are used much on a day to day basis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Overall Conclusion&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;All three tools examined (Toad, SQL Developer and PL/SQL Developer) offer competent Extract Procedure functionality, though at least in the versions I used, Toad had the fewest drawbacks in its implementation. Beyond that, Toad has fewer explicit refactoring features than PL/SQL Developer. My feeling, however, is that outside of Extract Procedure, the refactorings are minor and of limited importance.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I hope that with the introduction of PL/Scope and ALL_IDENTIFIERS in Oracle11g, we will see a major step forward by all IDE vendors as regards refactoring and code analysis.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/346/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/346/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=346</guid>
      <pubDate>Mon, 09 Mar 2009 15:18:00 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=346</trackback:ping>
    </item>
    <item>
      <title>Automatic refactoring in PL/SQL tools – Part 2</title>
      <description>&lt;div&gt;In &lt;a href="http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=321"&gt;part 1 of this series&lt;/a&gt;, I reviewed the automated refactoring features in SQL Developer. Now I will check out PL/SQL Developer (version 7.1.5)'s refactoring features.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;To access these features, I highlight some code in a procedure edit window and then choose Refactoring from the right click menu. I see these options:&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;img height="134" alt="" width="432" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I explore each of these below.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Rename item&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;If I highlight the name of identifier in its declaration section, the Rename item option is enabled:&lt;/div&gt;
&lt;div&gt; &lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I specified "abc" as the new name for this variable and PL/SQL Developer correctly substituted all instances of that identifier:&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-3.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;br /&gt;
What if I have another variable with the same name in a different scope? PL/SQL Developer does a nice job of recognizing that it should not change it:&lt;/div&gt;
&lt;div&gt; &lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Sadly, it's not yet working at genius level. If I include in the subprogram a reference to the outer l_cursor variable, it does not change that name:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  Works quite well, though it would be nice if I could highlight an identifier name anywhere in the program and have it do a rename (not only in the declaration statement for that variable). Could be a bit smarter, but for most "normal" scenarios, it should be fine.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Extract procedure&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;This is one of the most important refactorings: take logic out of your executable section and "hide" it inside a local procedure – or in a schema-level procedure. So I highlighted a line of code and choose this option. I was then asked to provide the new procedure name:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;After providing that name and pressing OK, I see the following:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-7.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Well...that didn't go very well. Notice that it grabbed a part of the next line (DBMS_SQL.PARSE), even though I didn't highlight it. Ugh. OK, I will do it again, with just the code from that single open_cursor line. The result looks much better; notice that the tool correctly extracted all local variables and arguments referenced in the code and now passes them in as arguments:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-8.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;There is one big problem, however: the code will not compile, because the subprogram was inserted &lt;em&gt;before&lt;/em&gt; the l_cursor declaration and that is invalid:&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-9.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Here's a nice touch, though: if your highlighted code references local variable that are used &lt;em&gt;only&lt;/em&gt; in that highlighted code, PL/SQL Developer will move the declaration for that variable out of the main program and into the local module. In other words, from this:&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-10.gif" /&gt; &lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;to:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-11.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  Disappointing overall. It's got the right idea and has been pretty-well thought through, but has at least two fairly serious flaws. Also, SQL Developer offers the option to define locally or store as a separate subprogram, which PL/SQL Dev does not.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Extract local constant&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;Here's what the help doc says about this one:&lt;br /&gt;
&lt;br /&gt;
"If a certain expression should be converted to a local constant, you can select it and provide the constant name. A local constant will be created within the current subprogram, of a type that is determined from the expression. All occurrences of the expression in the current subprogram will be replaced by the constant name."&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;All righty – let's try it out. I will create a constant for the call to the open_cursor function:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-12.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;And the result:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-13.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;PL/SQL Dev did a good job of &lt;em&gt;not&lt;/em&gt; including the ; from the highlighted text in the value assigned to the constant. It correctly replaced the call to the function with the named constant. It did &lt;em&gt;not&lt;/em&gt;, however, come up with the right datatype for the constant. Instead, it seems to have simply added up the number of characters in the selected text. That's just weird!&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Next I will highlight the local variable and change it to a constant:&lt;/div&gt;
&lt;div&gt; &lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-14.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The result is not great:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-15.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;It seems to me that it should have left the original declaration of l_cursor alone. The result is code that will not compile.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  marginally useful refactoring.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Extract global constant&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;PL/SQL Dev help tells us the following about this feature:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;"If a certain expression should be converted to a global constant, you can select it and provide the constant name. A global constant will be created within the current package, of a type that is determined from the expression. All occurrences of the expression in the current package will be replaced by the constant name."&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So what does this do? Well, if I use it inside my procedure, it acts the same as with a local constant extraction. I would have thought it should prompt me for the package name and either move the variable to that package or create a new package with that name.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Next I tried in a package:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-16.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;and it did the right thing, sort of:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-17.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;It still does not work properly with datatypes, though. It just defines them as VARCHAR2 all the time.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  same as for local constant....minimally useful.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Swap assignment&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;A very minor "refactoring". Use it to change an assignment of this form:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;a := b;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;to&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;b := a;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;It's fairly smart. You don't have to highlight the entire assignment statement, just a part of it, and PL/SQL Dev will move everything on the right to the left.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  not really a refactoring, but it could be a useful accelerator on occasion.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Replace assignment with initialization&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;The help doc says:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;"If a local variable assignment is purely for initialization, you can move it to the declaration of the variable. You can right-click on a statement or select multiple statements."&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So I started with this code:&lt;/div&gt;
&lt;div&gt; &lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-18.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;When I clicked on the variable name, the identifiers lit up:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-19.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I then chose my refactoring option&lt;/div&gt;
&lt;div&gt; &lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-20.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;and ended up with this:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven Feuerstein/SF-Blog010509-21.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;That's nice...though I have one concern and one desire:&lt;/div&gt;
&lt;ul type="disc"&gt;
    &lt;li&gt;Concern: the change is valid, but it could cause problems. When an exception raised in the declaration section, it cannot be handled within that block's exception section. The exception &lt;em&gt;always &lt;/em&gt;propagates unhandled to the outer block. So making this change could affect program behavior. &lt;br /&gt;
     &lt;/li&gt;
    &lt;li&gt;Desire: This would be even nicer if it was combined with the option to move the assignment to an initialization &lt;em&gt;procedure&lt;/em&gt; not simply to the declaration statement.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;  mildly useful, but sometimes &lt;em&gt;not desireable&lt;/em&gt; due to the way exception propagation works in PL/SQL.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;Overall Conclusion&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;Refactoring in PL/SQL Developer is minimal, but useful. It's done in a fairly smart way. Now if they would only give me a key stroke to pop up the refactoring menu, rather than having to make my way down through two levels of right click menu options.&lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/328/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/328/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=328</guid>
      <pubDate>Tue, 06 Jan 2009 16:30:00 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=328</trackback:ping>
    </item>
    <item>
      <title>Automatic refactoring in PL/SQL tools – Part 1  </title>
      <description>&lt;p&gt;&lt;span class="Normal" id="dnn_ctr389_MainView_ViewEntry_lblEntry"&gt;
&lt;div&gt;I have long been attracted to the idea and process of refactoring (explained below). It is now very exciting to see that automated refactoring features are working their way into tools for PL/SQL development. I will analyze these features over the next few entries in my ToadWorld blog, starting with SQL Developer and then moving on to PL/SQL Developer, and finishing up with SQL Navigator and Toad.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Oracle recently released Version 1.5.1 of SQL Developer, its free development tool for PL/SQL developers. I have been watching SQL Developer since Oracle first brought it into the world, seeing as (a) I am obsessed with PL/SQL; and (b) Oracle has had a checkered history when it comes to producing decent development tools for us PL/SQL developers; and (c) I work for Quest Software and of course we are keen to see how SQL Developer stacks up with Toad and SQL Navigator.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;My overall assessment of SQL Developer has been: it's a fine, clean, light development environment – with lots of room for growth and catching up. That is, for a free product that is relatively new, it is a nice effort. Not too surprising, since it leverages the JDeveloper framework, into which Oracle has invested lots and lots of resources.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Would I use it instead of Toad or SQL Navigator or a number of the other tools that have been out there for awhile? Not unless my budget consisted of $0 for PL/SQL development tools. As with any piece of software, it will take time for SQL Developer to mature and fill out its feature set.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The SQL Developer team is certainly not standing still, however, and with Version 1.5, they have added several new features. One feature that caught my eye in particular was support for automated refactoring.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;" Refactoring? What's that?" some of you may be wondering. You can see lots of information at &lt;a href="http://www.refactoring.com/"&gt;&lt;font color="#000000"&gt;http://www.refactoring.com/&lt;/font&gt;&lt;/a&gt;, but briefly (and from that site):&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;" Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Its heart is a series of small behavior preserving transformations. Each transformation (called a 'refactoring') does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring."&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The bottom line is that it is a highly structured methodology for going through clearly defined steps (each ideally verified by a pre-defined regression test) to make your code more maintainable.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;em&gt;Automated&lt;/em&gt; refactoring is a process that applies well-established and accepted refactorings automatically to your code. IDEs for object oriented languages have offered automated refactorings, albeit very simple ones, for a while. Now, SQL Developer offers this capability.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Exciting! So I decided to take a look. After installing SQL Developer 1.5, I opened up a program definition in an editor window, highlighted some code and checked out the right click menu. There it is!&lt;/div&gt;
&lt;p align="center"&gt;&lt;img height="103" alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-1.gif" width="498" /&gt; &lt;/p&gt;
&lt;div&gt;Interesting....but what are they? I dipped into Help just to see what I could find about these and found....very little. Just a window on Extract Procedure. So let's start with that first. SQL Developer tells me:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;"This dialog box is displayed if you are editing a procedure, select one or more PL/SQL statements, right-click, and select Refactoring, then Extract Procedure. The selected statements are encapsulated into the procedure to be created.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;"Defined Locally: For a standalone procedure, defines the newly refactored code in the definition section of the original procedure.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;"Stored: For a standalone procedure, defines the newly refactored code in a new standalone procedure.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;"Name: Name of the procedure to encapsulate the selected statements. For a packaged procedure, the newly extracted procedure text is placed immediately after the current procedure."&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now, I &lt;em&gt;really&lt;/em&gt; like this. I do. I believe that encapsulation or information hiding is one of the most important factors in writing maintainable code. And I believe in particular that we should make extensive use of locally-declared modules to do this.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So I highlight the line of code I want to encapsulate (the open cursor statement). I then, for starters, ask to create it as a schema-level procedure: &lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-2.gif" /&gt; &lt;/p&gt;
&lt;div&gt;Type in the name, press OK, and I see this:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-3.gif" /&gt; &lt;/p&gt;
&lt;div&gt;So far...OK, but just OK. Notice that it does not recognize that my line of code references a parameter from the main program. It would seem to me that the refactoring process should automatically create an argument for this procedure. This code isn't even valid. But I press Yes, and the box goes away, fine, but then I see that the original code is still present in my procedure:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-4.gif" /&gt; &lt;/p&gt;
&lt;div&gt;That's no good – I wanted to replace it with the new stored procedure. I check the browser and find that this procedure has not been created in my schema:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-5.gif" /&gt; &lt;/p&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now maybe that's because there was an error in the code (un-declared referenced to security_level_in), but I didn't get any notification. OK, I will try it again with code that &lt;em&gt;will&lt;/em&gt; compile, but still I see nothing. Well, I have no idea what is going on here, but really what I want to do is create a local module, so let's try that.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I highlight the code, choose my refactoring option, choose Local:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-6.gif" /&gt; &lt;/p&gt;
&lt;div&gt;I type in the name of my new local module and press OK. I then see this:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-7.gif" /&gt;&lt;/p&gt;
&lt;div&gt;Ugh. That's no good. It's supposed to be a &lt;em&gt;local&lt;/em&gt; module. SQL Developer has placed this code &lt;em&gt;above and outside&lt;/em&gt; of the use_cursor procedure. I then have to move it inside to make it work.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Bottom line, SQL Developer developers: nice idea, but your implementation leaves much to be desired. I don't see how I can use this to help me develop more modular, maintainable code any more easily than if I cut and paste myself.&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Let's check out the other refactoring options. "Rename Local Variable..."&lt;/p&gt;
&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-8.gif" /&gt;&lt;/p&gt;
&lt;div&gt;Hey, I like the sound of that! All too often we come up initially (in the heat of development) with bad variable names like "d" or "l_integer." Yuch! So the ability to be able to provide a new name and have the product sweep through my code and replace all instances...well, that would be pretty darned cool. Let's give it a try; in the program below I reference l_cursor four times:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-9.gif" /&gt;&lt;/p&gt;
&lt;div&gt;There's no help for this feature, so I figure I will highlight the variable name and then specify a new one that indicates that this is a dynamic cursor:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-10.gif" /&gt;&lt;/p&gt;
&lt;div&gt;Press OK, and it worked very nicely:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-11.gif" /&gt;&lt;/p&gt;
&lt;div&gt;Excellent! Now I will add a reference to a package variable with the same name:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-12.gif" /&gt;&lt;/p&gt;
&lt;div&gt;and try to do another renaming. This last addition should &lt;em&gt;not &lt;/em&gt; be changed, as it is &lt;em&gt;not &lt;/em&gt;the local variable. OK, I highlight the variable inside the code and try to change it, but I get this message:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-13.gif" /&gt;&lt;/p&gt;
&lt;div&gt;Hmmm. I guess I need to highlight the declaration itself, though that shouldn't be necessary. OK, I do that, ask to rename variables to abc and sadly I see this:&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-14.gif" /&gt;&lt;/p&gt;
&lt;div&gt;So the rename feature is nice enough, but if it is not &lt;em&gt;scope-aware&lt;/em&gt; (that is, if it cannot distinguish between locals, globals and even program names – yes, in another test, it even replaced the name of a &lt;em&gt;packaged&lt;/em&gt; &lt;em&gt;program&lt;/em&gt; that happened to have the same name as the local variable), then it really isn't doing anything better than a search and replace.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;It also lets me change the variable name to something that is &lt;em&gt;not&lt;/em&gt; a valid identifier, such as 123. If this feature is really directed at changing variable names, it should be aware of the rules and at a minimum put invalid names inside double quotes.&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Finally, I tried to change a local variable's name from abc to something with about 100 characters in it and got this message:&lt;/p&gt;
&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-15.gif" /&gt;&lt;/p&gt;
&lt;div&gt;Not sure what this means, but it certainly isn't helpful.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So I have to rate this feature a marketing-inflated misnomer. Sorry, SQL Developer developers!&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;And the third refactoring:&lt;/p&gt;
&lt;/div&gt;
&lt;p align="center"&gt;&lt;img alt="" src="http://www.toadworld.comhttp://www.toadworld.com/Portals/0/blogimages/Steven%20Feuerstein/SF-Blog120908-16.gif" /&gt;&lt;/p&gt;
&lt;p align="left"&gt;This lets you toggle between different case formats. It seems to work well enough. Honestly, however, I believe that it is not appropriate to include something like this under the Refactoring banner. It is a simple key driven formatting feature.&lt;/p&gt;
&lt;div&gt;In conclusion, I am very pleased that the SQL Developer has introduced automated refactoring to the PL/SQL community. This is a concept and capability which is badly needed. The implementation in Version 1.5, however, leaves much to be desired.&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Next/soon, I will take a look at PL/SQL Developer's refactoring capabilities.&lt;/p&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;/p&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/321/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/321/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=321</guid>
      <pubDate>Tue, 09 Dec 2008 19:23:00 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=321</trackback:ping>
    </item>
    <item>
      <title>Congratulations to the newest Oracle Magazine PL/SQL Developer of the Year!</title>
      <description>&lt;div&gt;As I travel certain parts of the globe doing presentations on PL/SQL, I meet many extremely talented PL/SQL programmers – people who meet the most complex challenges you can imagine with a deft combination of intense creativity, hard work, and of course Oracle PL/SQL.&lt;/div&gt;
&lt;p&gt;Oracle Magazine names only one as the PL/SQL Developer of the Year at each Oracle Open World, and this year the award was given to Alex De Vergori of Betfair.  Oracle Magazine &lt;a href="http://www.oracle.com/technology/oramag/oracle/08-nov/o68awards.html#devergori"&gt;writes&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px"&gt;
&lt;p&gt;&lt;strong&gt;Developer works with 250,000 lines of PL/SQL code that deliver success.&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;Successful PL/SQL developers require more than just good technical knowledge, according to Alex De Vergori, Oracle Magazine’s PL/SQL Developer of the Year. &lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;“They also need fine attention to detail, a passion about what they’re doing, and a high degree of pride in the software that they’re producing,” says De Vergori, a database architect who channels those skills at Betfair, an online gaming company that pioneered the concept of betting exchanges in 2000. &lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;To manage customers’ bets, De Vergori and the Betfair team have created a core betting engine and business logic that encompass more than 250,000 lines of PL/SQL code. The Betfair solution runs on Oracle Database using distributed databases around the world and an Oracle data warehouse running Oracle Real Application Clusters. Betfair also uses Oracle Coherence for its in-memory distributed data caching requirements, Java for its middle tier, and Ajax for its front-end applications. &lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;“We take in excess of five million transactions a day, and they all go straight through to the database, where those bets match with other transactions in real time,” says De Vergori. “At peak, we can easily see something like 1,000 bet transactions per second. With Oracle, our growth has been exponential, so that has enabled us to succeed in our market.”&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;Click &lt;a href="http://www.oracle.com/technology/oramag/oracle/08-may/o38developer.html"&gt;here&lt;/a&gt; if you would like to read more details about how Betfair is using PL/SQL.&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;Alex, welcome to the "select circle" of PL/SQL Developer of the Year awardees. Now, finally, you understand why you were spending all those long days, nights and weekends writing PL/SQL code!&lt;br /&gt;
 &lt;/div&gt;</description>
      <link>http://www.toadworld.com/BLOGS/tabid/67/EntryID/305/Default.aspx</link>
      <author>Steven Feuerstein</author>
      <comments>http://www.toadworld.com/BLOGS/tabid/67/EntryID/305/Default.aspx#Comments</comments>
      <guid isPermaLink="true">http://www.toadworld.com/Default.aspx?tabid=67&amp;EntryID=305</guid>
      <pubDate>Mon, 03 Nov 2008 15:03:00 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.toadworld.com/DesktopModules/Blog/Trackback.aspx?id=305</trackback:ping>
    </item>
  </channel>
</rss>