You are previewing Oracle PL/SQL Best Practices.
O'Reilly logo
Oracle PL/SQL Best Practices

Book Description

In this book, Steven Feuerstein, widely recognized as one of the world's experts on the Oracle PL/SQL language, distills his many years of programming, writing, and teaching about PL/SQL into a set of PL/SQL language "best practices"--rules for writing code that is readable, maintainable, and efficient. Too often, developers focus on simply writing programs that run without errors--and ignore the impact of poorly written code upon both system performance and their ability (and their colleagues' ability) to maintain that code over time. Oracle PL/SQL Best Practices is a concise, easy-to-use reference to Feuerstein's recommendations for excellent PL/SQL coding. It answers the kinds of questions PL/SQL developers most frequently ask about their code:

  • How should I format my code?

  • What naming conventions, if any, should I use?

  • How can I write my packages so they can be more easily maintained?

  • What is the most efficient way to query information from the database?

  • How can I get all the developers on my team to handle errors the same way?

The book contains 120 best practices, divided by topic area. It's full of advice on the program development process, coding style, writing SQL in PL/SQL, data structures, control structures, exception handling, program and package construction, and built-in packages. It also contains a handy, pull-out quick reference card. As a helpful supplement to the text, code examples demonstrating each of the best practices are available on the O'Reilly web site. Oracle PL/SQL Best Practices is intended as a companion to O'Reilly's larger Oracle PL/SQL books. It's a compact, readable reference that you'll turn to again and again--a book that no serious developer can afford to be without.

Table of Contents

  1. Oracle PL/SQL Best Practices
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. A Note Regarding Supplemental Files
    3. Dedication
    4. Preface
      1. Structure of This Book
      2. How to Use This Book
      3. Not All Best Practices Are Created Equal
      4. About the Code
      5. Other Resources
      6. Conventions Used in This Book
      7. Comments and Questions
      8. Acknowledgments
    5. 1. The Development Process
      1. DEV-01: Set standards and guidelines before writing any code.
      2. DEV-02: Ask for help after 30 minutes on a problem.
      3. DEV-03: Walk through each other's code.
      4. DEV-04: Validate standards against source code in the database.
      5. DEV-05: Generate code whenever possible and appropriate.
      6. DEV-06: Set up and use formal unit testing procedures.
      7. DEV-07: Get independent testers for functional sign-off.
    6. 2. Coding Style and Conventions
      1. STYL-01: Adopt a consistent, readable format that is easy to maintain.
      2. STYL-02: Adopt logical, consistent naming conventions for modules and data structures.
      3. STYL-03: Standardize module and program headers.
      4. STYL-04: Tag module END statements with module names.
      5. STYL-05: Name procedures with verb phrases and functions with noun phrases.
      6. STYL-06: Self-document using block and loop labels.
      7. STYL-07: Express complex expressions unambiguously using parentheses.
      8. STYL-08: Use vertical code alignment to emphasize vertical relationships.
      9. STYL-09: Comment tersely with value-added information.
      10. STYL-10: Adopt meaningful naming conventions for source files.
    7. 3. Variables and Data Structures
      1. 3.1. Declaring Variables and Data Structures
        1. DAT-01: Match datatypes to computational usage.
        2. DAT-02: Anchor variables to database datatypes using %TYPE and %ROWTYPE.
        3. DAT-03: Use SUBTYPE to standardize application-specific datatypes.
        4. DAT-04: Do not hard-code VARCHAR2 lengths.
        5. DAT-05: Use CONSTANT declarations for variables whose values do not change.
        6. DAT-06: Perform complex variable initialization in the executable section.
      2. 3.2. Using Variables and Data Structures
        1. DAT-07: Replace complex expressions with Boolean variables and functions.
        2. DAT-08: Do not overload data structure usage.
        3. DAT-09: Remove unused variables and code.
        4. DAT-10: Clean up data structures when your program terminates (successfully or with an error).
        5. DAT-11: Beware of and avoid implicit datatype conversions.
      3. 3.3. Declaring and Using Package Variables
        1. DAT-12: Package application-named literal constants together.
        2. DAT-13: Centralize TYPE definitions in package specifications.
        3. DAT-14: Use package globals judiciously and only in package bodies.
        4. DAT-15: Expose package globals using "get and set" modules.
    8. 4. Control Structures
      1. 4.1. Conditional and Boolean Logic
        1. CTL-01: Use ELSIF with mutually exclusive clauses.
        2. CTL-02: Use IF...ELSIF only to test a single, simple condition.
        3. CTL-03: Replace and simplify IF statements with Boolean expressions.
      2. 4.2. Loop Processing
        1. CTL-04: Never EXIT or RETURN from WHILE and FOR loops.
        2. CTL-05: Use a single EXIT in simple loops.
        3. CTL-06: Use a simple loop to avoid redundant code required by a WHILE loop.
        4. CTL-07: Never declare the FOR loop index.
        5. CTL-08: Scan collections using FIRST, LAST, and NEXT in loops.
        6. CTL-09: Move static expressions outside of loops and SQL statements.
      3. 4.3. Miscellaneous
        1. CTL-10: Use anonymous blocks within IF statements to conserve resources.
        2. CTL-11: Label and highlight GOTOs if using this normally unnecessary construct.
    9. 5. Exception Handling
      1. EXC-00: Set guidelines for application-wide error handling before you start coding.
        1. EXC-00: Set guidelines for application-wide error handling before you start coding.
      2. 5.1. Raising Exceptions
        1. EXC-01: Verify preconditions using standardized assertion routines that raise violation exceptions.
        2. EXC-02: Use the default exception-handling model to communicate module status back to calling PL/SQL programs.
        3. EXC-03: Catch all exceptions and convert to meaningful return codes before returning to non-PL/SQL host programs.
        4. EXC-04: Use your own raise procedure in place of explicit calls to RAISE_APPLICATION_ERROR.
        5. EXC-05: Only RAISE exceptions for errors, not to branch execution control.
        6. EXC-06: Do not overload an exception with multiple errors unless the loss of information is intentional.
      3. 5.2. Handling Exceptions
        1. EXC-07: Handle exceptions that cannot be avoided but can be anticipated.
        2. EXC-08: Avoid hard-coded exposure of error handling by using standard, declarative procedures.
        3. EXC-09: Use named constants to soft-code application-specific error numbers and messages.
        4. EXC-10: Include standardized modules in packages to dump package state when errors occur.
        5. EXC-11: Use WHEN OTHERS only for unknown exceptions that need to be trapped.
      4. 5.3. Declaring Exceptions
        1. EXC-12: Standardize named application exceptions in package specifications.
        2. EXC-13: Document all package exceptions by module in package specifications.
        3. EXC-14: Use the EXCEPTION_INIT pragma to name system exceptions that might be raised by your program.
    10. 6. Writing SQL in PL/SQL
      1. SQL-00: Establish and follow clear rules for how to write SQL in your application.
        1. SQL-00: Establish and follow clear rules for how to write SQL in your application.
      2. 6.1. General SQL and Transaction Management
        1. SQL-01: Qualify PL/SQL variables with their scope names when referenced inside SQL statements.
        2. SQL-02: Use incremental COMMITs to avoid rollback segment errors when changing large numbers of rows.
        3. SQL-03: Use autonomous transactions to isolate the effect of COMMITs and ROLLBACKs (Oracle8i).
      3. 6.2. Querying Data from PL/SQL
        1. SQL-04: Put single-row fetches inside functions; never hard-code a query in your block.
        2. SQL-05: Hide reliance on the dual table.
        3. SQL-06: Define multi-row cursors in packages so they can be used from multiple programs.
        4. SQL-07: Fetch into cursor records, never into a hard-coded list of variables.
        5. SQL-08: Use COUNT only when the actual number of occurrences is needed.
        6. SQL-09: Use a cursor FOR loop to fetch all rows in a cursor unconditionally.
        7. SQL-10: Never use a cursor FOR loop to fetch just one row.
        8. SQL-11: Specify columns to be updated in a SELECT FOR UPDATE statement.
        9. SQL-12: Parameterize explicit cursors.
        10. SQL-13: Use RETURNING to retrieve information about modified rows (Oracle8).
        11. SQL-14: Use BULK COLLECT to improve performance of multi-row queries (Oracle8i).
      4. 6.3. Changing Data from PL/SQL
        1. SQL-15: Encapsulate INSERT, UPDATE, and DELETE statements behind procedure calls.
        2. SQL-16: Reference cursor attributes immediately after executing the SQL operation.
        3. SQL-17: Check SQL%ROWCOUNT when updating or removing data that "should" be there.
        4. SQL-18: Use FORALL to improve performance of collection-based DML (Oracle8i).
      5. 6.4. Dynamic SQL and Dynamic PL/SQL
        1. SQL-19: Encapsulate dynamic SQL parsing to improve error detection and cleanup.
        2. SQL-20: Bind, do not concatenate, variable values into dynamic SQL strings.
        3. SQL-21: Soft-code the maximum length of columns in DBMS_SQL.DEFINE_COLUMN calls.
        4. SQL-22: Apply the invoker rights method to all stored code that executes dynamic SQL (Oracle8i).
        5. SQL-23: Format dynamic SQL strings so they can be easily read and maintained.
    11. 7. Program Construction
      1. 7.1. Structure and Parameters
        1. MOD-01: Encapsulate and name business rules and formulas behind function headers.
        2. MOD-02: Standardize module structure using function and procedure templates.
        3. MOD-03: Limit execution section sizes to a single page using modularization.
        4. MOD-04: Use named notation to clarify, self-document, and simplify module calls.
        5. MOD-05: Avoid side-effects in your programs.
        6. MOD-06: Use NOCOPY to minimize overhead when collections and records are [IN] OUT parameters (Oracle8i).
      2. 7.2. Functions
        1. MOD-07: Limit functions to a single RETURN statement in the execution section.
        2. MOD-08: Keep functions pure by avoiding [IN] OUT parameters.
        3. MOD-09: Never return NULL from Boolean functions.
      3. 7.3. Triggers
        1. MOD-10: Minimize the size of trigger execution sections.
        2. MOD-11: Consolidate "overlapping" DML triggers to control execution order.
        3. MOD-12: Raise exceptions to report on do-nothing INSTEAD OF triggers.
        4. MOD-13: Implement server problem logs and "to do" lists using database triggers.
        5. MOD-14: Use ORA_% public synonyms to reference database and schema event trigger attributes.
        6. MOD-15: Validate complex business rules with DML triggers.
        7. MOD-16: Populate columns of derived values with triggers.
        8. MOD-17: Use operational directives to provide more meaningful error messages from within triggers.
    12. 8. Package Construction
      1. PKG-01: Group related data structures and functionality together in a single package.
      2. PKG-02: Provide well-defined interfaces to business data and functional manipulation using packages.
      3. PKG-03: Freeze and build package specifications before implementing package bodies.
      4. PKG-04: Implement flexible, user-adjustable functionality using package state toggles and related techniques.
      5. PKG-05: Build trace "windows" into your packages using standardized programs.
      6. PKG-06: Use package body persistent data structures to cache and optimize data-driven processing.
      7. PKG-07: Insulate applications from Oracle version sensitivity using version-specific implementations.
      8. PKG-08: Avoid bloating package code with unnecessary but easy-to-build modules.
      9. PKG-09: Simplify and encourage module usage using overloading to widen calling options.
      10. PKG-10: Consolidate the implementation of related overloaded modules.
      11. PKG-11: Separate package specifications and bodies into different source code files.
      12. PKG-12: Use a standard format for packages that include comment headers for each type of element defined in the package.
    13. 9. Built-in Packages
      1. 9.1. DBMS_OUTPUT
        1. BIP-01: Avoid using the DBMS_OUTPUT.PUT_LINE procedure directly.
      2. 9.2. UTL_FILE
        1. BIP-02: Improve the functionality and error handling of UTL_FILE by using a comprehensive encapsulation package.
        2. BIP-03: Validate the setup of UTL_FILE with simple tests.
        3. BIP-04: Handle expected and named exceptions when performing file I/O.
        4. BIP-05: Encapsulate UTL_FILE.GET_LINE to avoid propagating the NO_DATA_FOUND exception.
        5. BIP-06: Soft-code directory names in your calls to UTL_FILE.FOPEN.
      3. 9.3. DBMS_PIPE
        1. BIP-07: Encapsulate interaction with specific pipes.
        2. BIP-08: Provide explicit and appropriate timeout values when you send and receive messages.
        3. BIP-09: Use RESET_BUFFER in exception handlers and before you pack data into the message buffer.
      4. 9.4. DBMS_ JOB
        1. BIP-10: Use your own submission procedure to improve job management capabilities.
        2. BIP-11: Trap all errors in DBMS_ JOB-executed stored procedures and modify the job queue accordingly.
    14. A. Best Practices Quick Reference
      1. A.1. The Development Process
      2. A.2. Coding Style and Conventions
      3. A.3. Variables and Data Structures
        1. Declaring Variables and Data Structures
        2. Using Variables and Data Structures
        3. Declaring and Using Package Variables
      4. A.4. Control Structures
        1. Conditional and Boolean Logic
        2. Loop Processing
        3. Miscellaneous
      5. A.5. Exception Handling
        1. Raising Exceptions
        2. Handling Exceptions
        3. Declaring Exceptions
      6. A.6. Writing SQL in PL/SQL
        1. General SQL and Transaction Management
        2. Querying Data from PL/SQL
        3. Changing Data from PL/SQL
        4. Dynamic SQL and Dynamic PL/SQL
      7. A.7. Program Construction
        1. Structure and Parameters
        2. Functions
        3. Triggers
      8. A.8. Package Construction
      9. A.9. Built-in Packages
        1. DBMS_OUTPUT
        2. UTL_FILE
        3. DBMS_PIPE
        4. DBMS_ JOB
    15. About the Author
    16. Colophon
    17. SPECIAL OFFER: Upgrade this ebook with O’Reilly