SunQuest
 
       Database Articles
  Home arrow Database Articles arrow Page 4 - Best Practices for PL/SQL Variables
IBM developerWorks
Try It Free
Codewalker Forums 
  Tutorials  
Database Articles  
Miscellaneous  
Navigation Usability  
PEAR Articles  
Programming Basics  
Server Administration  
XML Tutorials  
  Reviews  
Database Book Reviews  
Linux Book Reviews  
Miscellaneous Reviews  
PHP Book Reviews  
PHP Software Reviews  
Server Admin Reviews  
SQL Tool Reviews  
  Code Gallery  
Content Management Code  
Contest Code  
Counters Code  
Database Code  
Date Time Code  
Discussion Board Code  
Email Code  
File Manipulation Code  
GUI Code  
Link Farm Code  
Miscellaneous Code  
Search Code  
Site Navigation Code  
User Management Code  
Forums Sitemap 
Dedicated Servers  
Download TestComplete 
IBM® developerWorks
Weekly Newsletter 
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
DATABASE ARTICLES

Best Practices for PL/SQL Variables
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 2
    2007-12-20

    Table of Contents:
  • Best Practices for PL/SQL Variables
  • Didn’t your parents teach you to clean up after yourself?
  • Programmers are (or should be) control freaks
  • Best Practices for Declaring and Using Package Variables
  • Packages should have a strong sense of personal space

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
    Try It Free
     
    ADVERTISEMENT

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    Best Practices for PL/SQL Variables - Best Practices for Declaring and Using Package Variables


    (Page 4 of 5 )

    Use the best practices described in this section when you are declaring variables for use in packages.

    Danger, Will Robinson! Globals in use!

    Use package globals sparingly and only in package bodies.

    Problem: Jasper needs Lizbeth’s program data. Delaware needs Jasper’s program data.

    Everyone is working very hard in the final week or two of the coding cycle. Packages are constructed quickly, and everyone needs to reference “stuff” in everyone else’s packages. Here’s one example:

    Lizbeth creates a package named mfe_reports to consolidate all reporting-related functionality, including a function that returns the standard header for a report. This header is composed of a top line, a bottom line, and a report-specific string sandwiched in between. Here is Lizbeth’s package specification:

      PACKAGE mfe_reports
      IS
        
    topline VARCHAR2(100) := 'My Flimsy Excuse – We Report for You!!!!!!';
        
    bottomline VARCHAR2(100) := '== Report Generation Engine Version 4.3 ==';
        
    ...
     
    END mfe_reports;

    Jasper builds a report in his mfe_acceptability package. He doesn’t like the exclamation marks at the end of the top line, but he can’t get Lizbeth to change it (“Sorry, Jasper, that’s the standard.”). He also thinks putting “=” at the beginning and end of the bottom line is dumb. So he writes the following code:

      PACKAGE BODY mfe_acceptability
      IS
         PROCEDURE acceptance_report IS
            c_carriage_return CONSTANT VARCHAR2(1) := CHR(10);
        
    BEGIN
           
    mfe_reports.topline := replace (mfe_reports.topline, '!', '');
           
    mfe_reports.topline := replace (mfe_reports.bottomline, '=', '');
           
    DBMS_OUTPUT.PUT_LINE (
               
    mfe_reports.topline || c_carriage_return ||
               
    'Acceptance Report' || c_carriage_return ||
               
    mfe_reports.bottomline);

            ... rest of report logic ...
         END acceptance_report;

    And now Jasper can create the report just the way he likes it.

    Unfortunately for Jasper, the users are dismayed. They like the exclamation marks and the equals signs. They asked for those characters. And so they complain to Sunita, and Jasper gets in trouble. Jasper’s response? “If you didn’t want me to change it, why didn’t you stop me from changing it?”

    A very good question.

    Solution: Don’t expose program data in package specifications, letting everyone see and change it.

    Lizbeth realizes now that she should have ensured that neither Jasper nor any other developer could change the elements of the header. At first, she thinks to herself: “Well, fine. I will make the variables constants and then Jasper will not be able to change the values.”

      PACKAGE mfe_reports
      IS
         topline CONSTANT VARCHAR2(100) :=
             'My Flimsy Excuse – We Report for You!!!!!!';
         bottomline CONSTANT VARCHAR2(100) :=
             '== Report Generation Engine Version 4.3 ==';
      END mfe_reports;

    This is true. Now Jasper has no choice: he will have to accept the top and bottom lines and use them as is. Otherwise, he will get this error:

      PLS-00363: expression 'MFE_REPORTS.TOPLINE' cannot be used as an assignment
      target

    Looking at Jasper’s code, though, Lizbeth realizes that she needs to do more. If she is truly supposed to help people produce standard headers, it doesn’t make any sense for them to be concatenating the various pieces together with line breaks.

    So she decides to take things a step further and build a function that does all the work for the user of the mfe_reports package:

      PACKAGE mfe_reports
      IS
        
    FUNCTION standard_header (text_in in VARCHAR2) RETURN VARCHAR2;
      END mfe_reports;

      PACKAGE BODY mfe_reports
     
    IS
        
    FUNCTION standard_header (text_in in VARCHAR2) RETURN VARCHAR2
        
    IS
           
    c_carriage_return CONSTANT VARCHAR2(1) := CHR(10);
            c_topline CONSTANT VARCHAR2(100) :=
               'My Flimsy Excuse – We Report for You!!!!!!';
            c_bottomline CONSTANT VARCHAR2(100) :=
               '== Report Generation Engine Version 4.3 ==';
         BEGIN
            RETURN c_topline
               
    || c_carriage_return
               
    || text_in
               
    || c_carriage_return
                || c_bottomline;
         END standard_header;
      END mfe_report

    With this function in place, Jasper can add the header to his report with nothing more than this:

      PACKAGE BODY mfe_acceptability
     
    IS
         PROCEDURE acceptance_report IS
         BEGIN
            DBMS_OUTPUT.PUT_LINE (
               mfe_reports.standard_header ('Acceptance Report'));

            ... rest of report logic ...
         END acceptance_report;

    Sure, he might still gripe a bit about the lack of control over the report header, but at least now he doesn’t have to write nearly as much code. Instead, the central report package does most of the work for him.

    Jasper’s direct references (and changes) to the package variables in mfe_reports demonstrated some of the problems associated with global variables. A global variable is a data structure that can be referenced outside the scope or block in which it is declared. A variable declared at the package level (outside any
    individual procedure or function in that package) is global at one of two levels:

    1. If the variable is declared in the package body, then it is globally accessible to all programs defined within that package.
    2. If the variable is declared in the package specified, then it is accessible to (and directly referenceable by) any program executed from a schema that has EXECUTE authority on that package.

    Globals can also be defined in any PL/SQL block. In the following block, for example, the l_publish_date is global to the local display_book_info procedure:

      DECLARE
         l_publish_date DATE;
         ...
         PROCEDURE display_book_info IS
         BEGIN
           
    DBMS_OUTPUT.PUT_LINE (l_publish_date);
      END;

    Globals are dangerous and should be avoided, because they create hidden “dependencies” or side effects. A global doesn’t have to be passed through the parameter list, so it’s hard for you to even know that a global is referenced in a program without looking at the implementation.

    Furthermore, if that global is a variable (not a constant) and is declared in the package specification, then you have in effect lost control of your data. You cannot guarantee the integrity of its value, since any program run from a schema that has EXECUTE authority on the package can change the package however the developer of that program desires.

    You can avoid using globals, and uncontrolled modifications to globals, in a number of ways:

    Pass the global as a parameter in your procedures and functions
      
    Don’t reference it directly within the program
       (circumventing the structure and visibility of the
       parameter list).

    Declare variables, cursors, functions, and other objects as “deeply” as possible
      
    That would be in the block nearest to where, or
       within which, that object will be used). Doing this will
       reduce the chance of unintended use by other
       sections of the code.

    Hide your package data behind “gets and sets”
      
    These are subprograms that control access to the
       data. This approach is covered in the next best
       practice.

    Scope declarations as locally as possible
      
    If your variable is used only in a single subprogram,
       declare it there. If it needs to be shared among
       multiple programs in a package body, declare it at the
       package level (but never put the declaration in the
       package specification).

     


     

    More Database Articles Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "Oracle PL/SQL Best Practices, Second...
     

    Buy this book now. This article is excerpted from chapter four of the book Oracle PL/SQL Best Practices, Second Edition, written by Steven Feuerstein (O'Reilly, 2007; ISBN: 0596514107). Check it out today at your favorite bookstore. Buy this book now.

    DATABASE ARTICLES ARTICLES

    - More on Query Optimization for Oracle Databa...
    - Query Optimization in Oracle
    - Clusters and Other Data Structures for Oracle
    - Using Indexes with an Oracle Database
    - The Basics of Data Structures in Oracle
    - Oracle Data Structures
    - Best Practices for PL/SQL Variables
    - What`s Code Without Variables?
    - Clauses, Sorting, and SQL Queries
    - The From Clause and SQL Queries
    - Query Primer
    - Full Text Searches and Strings
    - Searching with Strings
    - Pattern Matching with Strings
    - Working with Cases of Strings





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway