• Save
Plsql coding conventions
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Plsql coding conventions

on

  • 3,872 views

Brief introduction on PL/SQL coding style

Brief introduction on PL/SQL coding style

Statistics

Views

Total Views
3,872
Views on SlideShare
3,840
Embed Views
32

Actions

Likes
0
Downloads
0
Comments
0

5 Embeds 32

http://www.cnblogs.com 21
https://twitter.com 7
http://www.haogongju.net 2
http://www.docshut.com 1
http://www.slashdocs.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Plsql coding conventions Presentation Transcript

  • 1. PL/SQL Coding Conventions
    fang.yu@moodys.com
    Dec 28, 2010
  • 2. Agenda
    Naming Conventions
    Coding Style, Format and Comments
    PL/SQL Best Practices
  • 3. Naming Conventions
    • Why Naming Convention
    • 4. Some Facts that Matter
    • 5. An Appetizer
    • 6. General Guidelines
    • 7. Naming Conventions
  • 1.1 Why Naming Convention
    • Easier to read, test, maintain
    • 8. Higher quality, more robust
    • 9. Better products
    • 10. Higher reputation
  • 1.2 Some Facts that Matter
    • 30 characters
    • 11. Case insensitive
  • 1.3 An Appetizer
    Any problem with this procedure?
    CREATE PROCEDURE remove_emp_in_dept(depno IN NUMBER)
    AS
    BEGIN
    DELETE FROM emp WHERE depno = depno;
    END;/
  • 12. 1.4 General Guidelines
    • Use meaningful and specific names, abbreviations, table/column alias.
    • 13. Do not use reserved words as variable names.
    SELECT  keyword FROM v$reserved_words  
    • Avoid redundant or meaningless prefixes and suffixes.
    CREATE TABLE demo_table
    CREATE TABLE demo
    • Do not quote name with double quotes (“)
    SQL> create table "HelloWorld" (id number);
    Table created.
    SQL> select * from helloworld;
    select * from helloworld
    *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    SQL> select * from HelloWorld;
    select * from HelloWorld
    *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    SQL> select * from "HelloWorld";
    no rows selected
  • 14. 1.5 Naming Conventions for Variables
  • 15. 1.6 Naming Conventions for Cursors
  • 16. 1.7 Naming Conventions for Records and Collections
  • 17. 1.8 Naming Conventions for Database Objects
  • 18. Coding Style, Format and Comments
    • General Coding Style
    • 19. Some Examples
    • 20. Tools that format PL/SQL
    • 21. Code Commenting
    • 22. View/Trigger Comment Block
  • 2.1 General Coding Style
    • Keywords are written in uppercase, variable names are written in lowercase.
    • 23. Indention using tab or 3 spaces. Keep it consistent!
    • 24. One command per line.
    • 25. Specify columns explicitly in SELECT and INSERT statements
    • 26. SQL keywords are right-aligned / left-aligned within a SQL command. Keep it consistent!
    PROCEDURE set_salary(p_empno_in IN emp.empno%TYPE)
    IS
    CURSOR l_emp_cur(p_empnoemp.empno%TYPE)
    IS
    SELECT ename
    ,sal
    FROM emp
    WHERE empno = p_empno
    ORDER BY ename;
    l_empl_emp_cur%ROWTYPE;
    l_new_salemp.sal%TYPE;
    BEGIN
    OPEN l_emp_cur(p_empno_in);
    FETCH l_emp_cur INTO l_emp;
    CLOSE l_emp_cur;
    --
    get_new_salary (p_empno_in => in_empno
    , p_sal_out => l_new_sal);
    -- Check whether salary has changed
    IF l_emp.sal <> l_new_sal THEN
    UPDATE emp
    SET sal = l_new_sal
    WHERE empno = p_empno_in;
    END IF;
    END set_salary;
  • 27. 2.2 Some SQL Style Examples
    SELECT e.job, e.deptno FROM emp e WHERE e.name = 'SCOTT' AND e.sal > 100000
    SELECT
    e.job,
    e.deptno
    FROM
    emp e
    WHERE
    e.name = 'SCOTT' AND
    e.sal > 100000
    SELECT e.JOB
    ,e.deptno
    FROM emp e
    WHERE e.name = 'SCOTT'
    AND e.sal > 100000
    SELECT e.JOB
    , e.deptno
    FROM emp e
    WHERE e.name = 'SCOTT'
    AND e.sal > 100000
    SELECT e.JOB,
    e.deptno
    FROM emp e
    WHERE e.name = 'SCOTT'
    AND e.sal > 100000
  • 28. 2.3 Tools that format PL/SQL
    • Instant SQL Formatter http://www.dpriver.com/pp/sqlformat.htm
    • 29. Oracle SQL Developer
  • 2.4 Code Commenting
    • pldochttp://pldoc.sourceforge.net/maven-site/
    PACKAGE pack_syspar IS
    /**
    * Project: Test Project (<a href="http://pldoc.sourceforge.net">PLDoc</a>)<br/>
    * Description: System Parameters Management<br/>
    * DB impact: YES<br/>
    * Commit inside: NO<br/>
    * Rollback inside: NO<br/>
    * @headcom
    */
    /** Gets system parameter value.
    * @paramp_name parameter name
    * @return parameter value
    * @throws no_data_found if no parameter with such name found
    */
    FUNCTION get_char
    (p_name VARCHAR2)
    RETURN VARCHAR2;
    END pack_syspar ;
    /
  • 30. 2.5 View/Trigger Comment Block
    CREATE OR REPLACE TRIGGER tri_mytab_bi
    BEFORE INSERT ON mytab
    FOR EACH ROW
    DECLARE
    -- local variables here
    BEGIN
    NULL;
    END tri_mytab_bi
    /*******************************************************************
    Copyright YYYY by <Company Name>
    All Rights Reserved.
    <Short synopsis of trigger's purpose. Required.>
    <Optional design notes.>
    *******************************************************************/ ;
    /*******************************************************************
    Copyright YYYY by <Company Name>
    All Rights Reserved.
    <Short synopsis of trigger's purpose. Required.>
    <Optional design notes.>
    *******************************************************************/
    CREATE OR REPLACE TRIGGER tri_mytab_bi
    BEFORE INSERT ON mytab
    FOR EACH ROW
    DECLARE
    -- local variables here
    BEGIN
    NULL;
    END tri_mytab_bi;
  • 31. PL/SQL Best Practices
    • Literals, Constants and Variables
    • 32. Data Types
    • 33. Flow Control
    • 34. Exception Handling
    • 35. Dynamic SQL
    • 36. Stored Objects
    • 37. Other
  • 3.1 Literals, Constants and Variables
    • Avoid using literals in your code, abstract literals behind package constants
    • 38. Use a function to return a constant if the “constant” value may change at times
    • 39. Do not use public global variables, use getter/setter or parameters-passing
    • 40. Never put all of a system’s constants in a single package.
    • 41. Avoid initializing variables using functions in the declaration section.
  • 3.1 Literals, Constants and Variables (Examples)
    -- Bad
    DECLARE
    l_functionplayer.function_name%TYPE;
    BEGIN
    SELECT p.function
    INTO l_function
    FROM player p
    WHERE …
    --
    IF l_function = ‘LEADER’
    THEN
    -- Good
    CREATE OR REPLACE PACKAGE pack_constants
    IS
    gc_leader CONSTANT player.function_name%TYPE := ‘LEADER’;
    END pack_constants ;
    /
    DECLARE
    l_functionplayer.function_name%TYPE;
    BEGIN
    SELECT p.function INTO l_function FROM player p WHERE …
    --
    IF l_function = pack_constants.gc_leader
    THEN
    -- Bad
    DECLARE
    l_code_section VARCHAR2(30) := ‘TEST_PCK’;
    l_company_name VARCHAR2(30) := util_pck.get_company_name(in_id => 47);
    BEGIN

    END;
    -- Good
    DECLARE
    l_code_section VARCHAR2(30) := ‘TEST_PCK’;
    l_company_name VARCHAR2(30);
    BEGIN
    <<init>>
    BEGIN
    l_companyName := util_pck.get_company_name(inId => 47);
    EXCEPTION
    WHEN VALUE_ERROR THEN …;
    END;
    END;
  • 42. 3.2 Data Types
    • Anchor parameters and variables using %TYPE (or %ROWTYPE for cursor or entire table).
    • 43. Use SUBTYPE to avoid hard-coded variable length declarations.
    • 44. Avoid using CHAR data type.
    • 45. Never use zero-length strings to substitute NULL.
    • 46. (CLOB, BLOB or BFILE ) vs. (LONG or LONG RAW)
    • 47. NUMBER vs. PLS_INTEGER vs. SIMPLE_INTEGER (New in 11g, always not null)
    • 48. Avoid using ROWID or UROWID (Universal ROWID)
  • 3.2 Data Types (Examples)
    CREATE OR REPLACE PACKAGE PACK_TYPES
    AS
    SUBTYPE t_oracle_name IS VARCHAR2(30);
    SUBTYPE t_oracle_max_varchar IS VARCHAR2(4000);
    subtype t_plsql_max_varchar IS VARCHAR2(32767);
    END PACK_TYPES;
    /
    -- Bad
    l_code_sectionVARCHAR2(30) := ‘TEST_PCK’;
    -- Good
    l_code_sectionpack_types.t_oracle_name := ‘TEST_PCK’;
    -- Bad
    DECLARE
    l_ename VARCHAR2(10);
    BEGIN
    SELECT e.ename
    INTO l_ename
    FROM emp e
    WHERE …
    END;
    -- Good
    DECLARE
    l_enameemp.ename%TYPE;
    BEGIN
    SELECT e.ename
    INTO l_ename
    FROM emp e
    WHERE …
    END;
    -- Bad
    l_char := ‘’;
    -- Good
    l_char := NULL;
  • 49. 3.3 Flow Control
    • Always label your loops
    • 50. Always use a FOR loop to process the complete cursor results unless you are using bulk operation
    • 51. Always use a WHILE loop to process a loose array
    • 52. Always use FIRST..LAST when iterating through collections with a loop
    • 53. Always use EXIT WHEN instead of an IF statement to exit from a loop
    • 54. Never EXIT from within any FOR loop, use LOOP or WHILE loop instead
    • 55. Avoid hard-coded upper or lower bound values with FOR loops
    • 56. Never issue a RETURN statement inside a loop
  • 3.3 Flow Control (Examples)
    BEGIN
    <<process_employees>>
    FOR r_employee IN (SELECT * FROM emp)
    LOOP

    END LOOP process_employees;
    END;
    BEGIN
    <<process_employees>>
    FOR idx IN t_employees.FIRST()..t_employees.LAST()
    LOOP

    END LOOP process_employees;
    END;
    DECLARE
    l_index PLS_INTEGER;
    BEGIN
    l_index := t_employees.FIRST();
    <<ProcessEmployees>>
    WHILE l_index IS NOT NULL
    LOOP

    l_index := t_employees.NEXT(l_index);
    END LOOP process_employees;
    END;
    -- Bad
    BEGIN
    <<process_employees>>
    LOOP
    ...
    IF ...
    THEN
    EXIT process_employees;
    END IF;
    ...
    END LOOP process_employees;
    END;
    -- Good
    BEGIN
    <<process_employees>>
    LOOP
    ...
    EXIT process_employees WHEN (...);
    END LOOP process_employees;
    END;
  • 57. 3.4 Exception Handling
    • Never handle unnamed exceptions using the error number
    • 58. Never assign predefined exception names to user defined exceptions
    • 59. Avoid use of WHEN OTHERS clause in an exception section without any other specific handlers
    • 60. Avoid use of EXCEPTION_INIT pragma for -20, NNN error (-20,999 ~ -20,000)
    • 61. Use DBMS_UTILITY.format_error_stack instead of SQLERRM to obtain the full error message
    • 62. Replace status codes with exception handling within PL/SQL
  • 3.4 Exception Handling (Examples)
    -- Bad
    -- ORA-00001: unique constraint violated
    BEGIN
    ...
    EXCEPTION
    WHEN OTHERS THEN
    IF SQLCODE = -1
    THEN
    ...
    END IF;
    END;
    -- Good
    DECLARE
    e_employee_exists EXCEPTION;
    PRAGMA EXCEPTION_INIT(-1, e_employee_exists);
    ...
    BEGIN
    ...
    EXCEPTION
    WHEN e_employee_exists THEN
    ...
    END;
    -- Good
    EXCEPTION
    WHEN DUP_VAL_ON_INDEX
    THEN
    update_instead (...);
    WHEN OTHERS
    THEN
    err.log;
    RAISE;
  • 63. 3.5 Dynamic SQL
    • Always use a string variable to execute dynamic SQL (easier for debug)
    • 64. Use bind variables. Do not concatenate strings unless needed to identify schema or table/view.
    • 65. Format dynamic SQL strings as nicely as in static SQL.
  • 3.5 Dynamic SQL (Examples)
    -- Bad
    DECLARE
    l_empnoemp.empno%TYPE := 4711;
    BEGIN
    EXECUTE IMMEDIATE ‘DELETE FROM emp WHERE epno = :p_empno’ USING l_empno;
    END;
    -- Good
    DECLARE
    l_empnoemp.empno%TYPE := 4711;
    l_sql VARCHAR2(32767);
    BEGIN
    l_sql := ‘DELETE FROM emp WHERE epno = :p_empno’;
    EXECUTE IMMEDIATE l_sql USING l_empno;
    EXCEPTION
    WHEN others
    THEN
    DBMS_OUTPUT.PUT_LINE(l_sql);
    END;
  • 66. 3.6 Stored Objects
    • Try to keep packages small. Include only few procedures and functions that are used in the same context.
    • 67. Always use forward declaration for private functions and procedures in packages.
    • 68. Avoid standalone procedures or functions – put them in packages
    • 69. Avoid using RETURN statements in a procedure(one way in one way out)
    • 70. Try to use no more than one RETURN statement within a function
    • 71. Never use OUT parameters to return values from a function
  • 3.7 CASE / IF / DECODE / NVL / NVL2 / COALESCE
    • Try to use CASE rather than an IF statement with multiple ELSIF paths
    • 72. Try to use CASE rather than DECODE.
    • 73. Always use COALESCE instead of NVL, if parameter 2 of the NVL function is a function call or a SELECT statement.
    • 74. Always use CASE instead of NVL2 if parameter 2 or 3 of NVL2 is either a function call or a SELECT statement.
    • 75. The NVL function always evaluates both parameters before deciding which one to use. This can be harmful if parameter 2 is either a function call or a select statement, as it will be executed regardless of whether parameter 1 contains a NULL value or not.
    • 76. The COALESCE function does not have this drawback.
    • 77. NVL2 is similar.
    • 78. DECODE cannot be used in PL/SQL
  • 3.7 CASE / IF / DECODE / NVL / NVL2 / COALESCE (e.g.)
    -- Bad
    IF l_color = ′red′
    THEN
    ...
    ELSIF l_color = ′blue′
    THEN
    ...
    ELSIF l_color = ′black′
    THEN
    ...
    -- Good
    CASE l_color
    WHEN ′red′ THEN ...
    WHEN ′blue′ THEN ...
    WHEN ′black′ THEN ...
    END
    -- Bad
    SELECT NVL(dummy, function_call()) FROM dual;
    -- Good
    SELECT COALESCE(dummy, function_call()) FROM dual;
    -- Bad
    SELECT NVL2(dummy, ‘Yes’, ‘No’) FROM dual;
    -- Good
    SELECT CASE
    WHEN dummy IS NULL THEN ‘No’
    ELSE ‘Yes’
    END
    FROM dual;
  • 79. Thanks!
    Q&A
  • 80. © 2009 Moody’s Analytics, Inc. and/or its licensors and affiliates (collectively, “MOODY’S”). All rights reserved. ALL INFORMATION CONTAINED HEREIN IS PROTECTED BY COPYRIGHT LAW AND NONE OF SUCH INFORMATION MAY BE COPIED OR OTHERWISE REPRODUCED, REPACKAGED, FURTHER TRANSMITTED, TRANSFERRED, DISSEMINATED, REDISTRIBUTED OR RESOLD, OR STORED FOR SUBSEQUENT USE FOR ANY SUCH PURPOSE, IN WHOLE OR IN PART, IN ANY FORM OR MANNER OR BY ANY MEANS WHATSOEVER, BY ANY PERSON WITHOUT MOODY’S PRIOR WRITTEN CONSENT. All information contained herein is obtained by MOODY’S from sources believed by it to be accurate and reliable. Because of the possibility of human or mechanical error as well as other factors, however, all information contained herein is provided “AS IS” without warranty of any kind. Under no circumstances shall MOODY’S have any liability to any person or entity for (a) any loss or damage in whole or in part caused by, resulting from, or relating to, any error (negligent or otherwise) or other circumstance or contingency within or outside the control of MOODY’S or any of its directors, officers, employees or agents in connection with the procurement, collection, compilation, analysis, interpretation, communication, publication or delivery of any such information, or (b) any direct, indirect, special, consequential, compensatory or incidental damages whatsoever (including without limitation, lost profits), even if MOODY’S is advised in advance of the possibility of such damages, resulting from the use of or inability to use, any such information. The ratings, financial reporting analysis, projections, and other observations, if any, constituting part of the information contained herein are, and must be construed solely as, statements of opinion and not statements of fact or recommendations to purchase, sell or hold any securities. NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY, TIMELINESS, COMPLETENESS, MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OF ANY SUCH RATING OR OTHER OPINION OR INFORMATION IS GIVEN OR MADE BY MOODY’S IN ANY FORM OR MANNER WHATSOEVER. Each rating or other opinion must be weighed solely as one factor in any investment decision made by or on behalf of any user of the information contained herein, and each such user must accordingly make its own study and evaluation of each security and of each issuer and guarantor of, and each provider of credit support for, each security that it may consider purchasing, holding, or selling.