• A First Programming Exercise For PLSQL code


    A First Programming Exercise For PLSQL code

    The Data Model

     The Physical Database Design

    1. CREATE TABLE books(
    2. isbn VARCHAR2(13) NOT NULL PRIMARY KEY,
    3. title VARCHAR2(200),
    4. summary VARCHAR2(2000),
    5. author VARCHAR2(200),
    6. date_published DATE,
    7. page_count NUMBER
    8. );
    9. CREATE TABLE book_copies(
    10. barcode_id VARCHAR2(100) NOT NULL PRIMARY KEY,
    11. isbn VARCHAR2(13)
    12. );
    1. SQL> desc books;
    2. Name Null? Type
    3. ----------------------------------------- -------- ----------------------------
    4. ISBN NOT NULL VARCHAR2(13)
    5. TITLE VARCHAR2(200)
    6. SUMMARY VARCHAR2(2000)
    7. AUTHOR VARCHAR2(200)
    8. DATE_PUBLISHED DATE
    9. PAGE_COUNT NUMBER
    10. SQL> desc book_copies;
    11. Name Null? Type
    12. ----------------------------------------- -------- ----------------------------
    13. BARCODE_ID NOT NULL VARCHAR2(100)
    14. ISBN VARCHAR2(13)
    15. SQL>

    Syntax to create a procedure

    1. CREATE [ OR REPLACE ] PROCEDURE procedure_name
    2. (parameter1 MODE DATATYPE [ DEFAULT expression ],
    3. parameter2 MODE DATATYPE [ DEFAULT expression ],
    4. ...)
    5. AS
    6. [ variable1 DATATYPE;
    7. variable2 DATATYPE;
    8. ... ]
    9. BEGIN
    10. executable_statements
    11. [ EXCEPTION
    12. WHEN exception_name
    13. THEN
    14. executable_statements ]
    15. END;
    16. /
    1. CREATE OR REPLACE PROCEDURE add_book(isbn_in IN VARCHAR2,
    2. barcode_id_in IN VARCHAR2,
    3. title_in IN VARCHAR2,
    4. author_in IN VARCHAR2,
    5. page_count_in IN NUMBER,
    6. summary_in IN VARCHAR2 DEFAULT NULL,
    7. date_published_in IN DATE DEFAULT NULL) AS
    8. BEGIN
    9. /* check for reasonable inputs */
    10. IF isbn_in IS NULL THEN
    11. RAISE VALUE_ERROR;
    12. END IF;
    13. /* put a record in the "books" table */
    14. INSERT INTO books
    15. (isbn, title, summary, author, date_published, page_count)
    16. VALUES
    17. (isbn_in,
    18. title_in,
    19. summary_in,
    20. author_in,
    21. date_published_in,
    22. page_count_in);
    23. /* if supplied, put a record in the "book_copies" table */
    24. IF barcode_id_in IS NOT NULL THEN
    25. INSERT INTO book_copies
    26. (isbn, barcode_id)
    27. VALUES
    28. (isbn_in, barcode_id_in);
    29. END IF;
    30. END add_book;
    31. /
    1. BEGIN
    2. add_book('1-56592-335-9',
    3. '100000001',
    4. 'Oracle PL/SQL Programming',
    5. 'Feuerstein, Steven, with Bill Pribyl',
    6. 987,
    7. 'Reference for PL/SQL developers, '
    8. || 'including examples and best practice recommendations.',
    9. TO_DATE('01-SEP-1997','DD-MON-YYYY'));
    10. END;
    11. /

     

     

    1. SQL> select * from books;
    2. ISBN TITLE SUMMARY AUTHOR DATE_PUBLISHED PAGE_COUNT
    3. ------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------- ----------
    4. 1-56592-335-9 Oracle PL/SQL Programming Reference for PL/SQL developers, including examples and best practice recommenda Feuerstein, Steven, with Bill Pribyl 9/1/97 987
    5. SQL>

     Named notation

    1. add_book(isbn_in => '1-56592-335-9',
    2. title_in => 'Oracle PL/SQL Programming',
    3. summary_in => 'Reference for PL/SQL developers, ' ||
    4. 'including examples and best practice recommendations.'
    5. author_in => 'Feuerstein, Steven, with Bill Pribyl',
    6. date_published_in => NULL,
    7. page_count_in => 987,
    8. barcode_id_in => '100000001')

    Retrieving a Book Count with a Function

    Syntax for Creating a Function

    1. CREATE [ OR REPLACE ] FUNCTION procedure_name
    2. (parameter1 MODE DATATYPE DEFAULT expression,
    3. parameter2 MODE DATATYPE DEFAULT expression,
    4. ...)
    5. RETURN DATATYPE
    6. AS
    7. [ variable1 DATATYPE;
    8. variable2 DATATYPE;
    9. ... ]
    10. BEGIN
    11. executable_statement;
    12. RETURN expression;
    13. [ EXCEPTION
    14. WHEN exception_name
    15. THEN
    16. executable_statement; ]
    17. END;
    18. /

    this code differs from a procedure in only two places:

    • the header, which specifies the returned datatype,
    • and the body,which must explicitly convey a value back to the caller.

    RETURN datatype

    In the header,the RETURN clause is part of the function declaration. It tells the compiler (and other programs) what datatype to expect back when you invoke the function

    RETURN expression

    Inside the executable section,this use of RETURN is known as the return statement,and it says “Okay,I’m all done; it’s time to send back (return) the following value.” You can also put a RETURN statement in the EXCEPTION section.

    Code for the book_copy_qty Function

    1. CREATE OR REPLACE FUNCTION book_copy_qty(isbn_in IN VARCHAR2)
    2. RETURN NUMBER
    3. AS
    4. number_o_copies NUMBER := 0;
    5. CURSOR bc_cur IS
    6. SELECT COUNT(*) FROM book_copies WHERE isbn = isbn_in;
    7. BEGIN
    8. IF isbn_in IS NOT NULL THEN
    9. OPEN bc_cur;
    10. FETCH bc_cur
    11. INTO number_o_copies;
    12. CLOSE bc_cur;
    13. END IF;
    14. RETURN number_o_copies;
    15. END;
    16. /

     Using the function

     

    1. DECLARE
    2. local_variable DATATYPE;
    3. BEGIN
    4. local_variable := function_name (argument1, argument2, ...);
    5. END;
    6. /

     

    1. SQL> DECLARE
    2. 2 how_many INTEGER;
    3. 3 BEGIN
    4. 4 how_many := book_copy_qty('1-56592-335-9');
    5. 5 END;
    6. 6 /
    7. PL/SQL procedure successfully completed
    8. SQL>

    pass the result to DBMS_OUTPUT.PUT_ LINE to print the result:

    1. SQL>
    2. SQL> SET SERVEROUTPUT ON
    3. SQL> BEGIN
    4. 2 DBMS_OUTPUT.PUT_LINE('Number of copies of 1-56592-335-9: '
    5. 3 || book_copy_qty('1-56592-335-9'));
    6. 4 END;
    7. 5 /
    8. Number of copies of 1-56592-335-9: 1
    9. PL/SQL procedure successfully completed
    10. SQL>

    Some rules about functions

    • You can’t create one of these standalone (or top-level) functions with the same name as a standalone procedure. If you adopt the practice of naming procedures with verb phrases,and functions with noun phrases,you shouldn’t have to worry about this potential clash.

    • If you forget the RETURN clause in the header,your function won’t compile. That’s a good thing,because compiler errors are considered “early notification.” But,if you forget the RETURN in the body,you won’t find out until you run the function,at which point Oracle will spit out the error ORA-06503: PL/SQL: Function returned without value. There’s a good argument for thorough testing.

    • When you invoke a function,the calling program must do something with the value the function returns,such as store it in a local variable. PL/SQL doesn’t tolerate “ignored” function results the way C does.

    • When the RETURN statement in the body gets executed,not only does the value flow back to the caller,but so does the “thread of execution.” In other words, code that appears below the RETURN will not run.

    A “Gotcha” about Exceptions Raised by Functions in the Declaration Section

    1. DECLARE
    2. how_many NUMBER := book_copy_qty('xyz');
    3. BEGIN
    4. ...whatever...
    5. EXCEPTION
    6. WHEN OTHERS
    7. THEN
    8. /* SURPRISE! Exceptions raised in the declaration section CANNOT be
    9. || handled here!
    10. */
    11. ...
    12. END;
    13. /

    A Results-Checking Utility

    1. SQL>
    2. SQL> CREATE OR REPLACE PROCEDURE reporteq (description IN VARCHAR2,
    3. 2 expected_value IN VARCHAR2, actual_value IN VARCHAR2) AS
    4. 3 BEGIN
    5. 4 DBMS_OUTPUT.PUT(description || ': ');
    6. 5 IF expected_value = actual_value
    7. 6 OR (expected_value IS NULL AND actual_value IS NULL)
    8. 7 THEN
    9. 8 DBMS_OUTPUT.PUT_LINE('PASSED');
    10. 9 ELSE
    11. 10 DBMS_OUTPUT.PUT_LINE('FAILED. Expected ' || expected_value
    12. 11 || '; got ' || actual_value);
    13. 12 END IF;
    14. 13 END;
    15. 14 /
    16. Procedure created
    17. SQL>

    Using PL/SQL Packages to Organize Code

    Parts of Packages

    For reasons that will become clear as we go on,packages usually have two parts: a specification (often abbreviated as spec) and a body.

    The package specification

    1. CREATE OR REPLACE PACKAGE package_name
    2. AS
    3. program1_header;
    4. program2_header;
    5. program3_header;
    6. END package_name;
    7. /
    1. CREATE OR REPLACE PACKAGE book
    2. AS
    3. PROCEDURE add(isbn_in IN VARCHAR2, title_in IN VARCHAR2,
    4. author_in IN VARCHAR2, page_count_in IN NUMBER,
    5. summary_in IN VARCHAR2 DEFAULT NULL,
    6. date_published_in IN DATE DEFAULT NULL,
    7. barcode_id_in IN VARCHAR2 DEFAULT NULL);
    8. PROCEDURE add_copy(isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2);
    9. FUNCTION book_copy_qty(isbn_in IN VARCHAR2)
    10. RETURN NUMBER;
    11. PROCEDURE change(isbn_in IN VARCHAR2, new_title IN VARCHAR2,
    12. new_author IN VARCHAR2, new_page_count IN NUMBER,
    13. new_summary IN VARCHAR2 DEFAULT NULL,
    14. new_date_published IN DATE DEFAULT NULL);
    15. PROCEDURE remove_copy(barcode_id_in IN VARCHAR2);
    16. PROCEDURE weed(isbn_in IN VARCHAR2);
    17. END book;
    18. /

    The package body

    1. CREATE OR REPLACE PACKAGE BODY package_name
    2. AS
    3. private_programs; /* optional */
    4. program1_body;
    5. program2_body;
    6. program3_body;
    7. END package_name;
    8. /
    1. CREATE OR REPLACE PACKAGE BODY book AS
    2. /* private procedure for use only in this package body */
    3. PROCEDURE assert_notnull(tested_variable IN VARCHAR2) IS
    4. BEGIN
    5. IF tested_variable IS NULL THEN
    6. RAISE VALUE_ERROR;
    7. END IF;
    8. END assert_notnull;
    9. FUNCTION book_copy_qty(isbn_in IN VARCHAR2) RETURN NUMBER AS
    10. number_o_copies NUMBER := 0;
    11. CURSOR bc_cur IS
    12. SELECT COUNT(*) FROM book_copies WHERE isbn = isbn_in;
    13. BEGIN
    14. IF isbn_in IS NOT NULL THEN
    15. OPEN bc_cur;
    16. FETCH bc_cur
    17. INTO number_o_copies;
    18. CLOSE bc_cur;
    19. END IF;
    20. RETURN number_o_copies;
    21. END;
    22. PROCEDURE add(isbn_in IN VARCHAR2,
    23. title_in IN VARCHAR2,
    24. author_in IN VARCHAR2,
    25. page_count_in IN NUMBER,
    26. summary_in IN VARCHAR2,
    27. date_published_in IN DATE,
    28. barcode_id_in IN VARCHAR2) IS
    29. BEGIN
    30. assert_notnull(isbn_in);
    31. INSERT INTO books
    32. (isbn, title, summary, author, date_published, page_count)
    33. VALUES
    34. (isbn_in,
    35. title_in,
    36. summary_in,
    37. author_in,
    38. date_published_in,
    39. page_count_in);
    40. IF barcode_id_in IS NOT NULL THEN
    41. add_copy(isbn_in, barcode_id_in);
    42. END IF;
    43. END add;
    44. PROCEDURE add_copy(isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2) IS
    45. BEGIN
    46. assert_notnull(isbn_in);
    47. assert_notnull(barcode_id_in);
    48. INSERT INTO book_copies
    49. (isbn, barcode_id)
    50. VALUES
    51. (isbn_in, barcode_id_in);
    52. EXCEPTION
    53. WHEN DUP_VAL_ON_INDEX THEN
    54. NULL;
    55. END;
    56. PROCEDURE change(isbn_in IN VARCHAR2,
    57. new_title IN VARCHAR2,
    58. new_author IN VARCHAR2,
    59. new_page_count IN NUMBER,
    60. new_summary IN VARCHAR2 DEFAULT NULL,
    61. new_date_published IN DATE DEFAULT NULL) IS
    62. BEGIN
    63. assert_notnull(isbn_in);
    64. UPDATE books
    65. SET title = new_title,
    66. author = new_author,
    67. page_count = new_page_count,
    68. summary = new_summary,
    69. date_published = new_date_published
    70. WHERE isbn = isbn_in;
    71. IF SQL%ROWCOUNT = 0 THEN
    72. RAISE NO_DATA_FOUND;
    73. END IF;
    74. END change;
    75. PROCEDURE remove_copy(barcode_id_in IN VARCHAR2) IS
    76. BEGIN
    77. assert_notnull(barcode_id_in);
    78. DELETE book_copies WHERE barcode_id = barcode_id_in;
    79. END remove_copy;
    80. PROCEDURE weed(isbn_in IN VARCHAR2) IS
    81. BEGIN
    82. assert_notnull(isbn_in);
    83. DELETE book_copies WHERE isbn = isbn_in;
    84. DELETE books WHERE isbn = isbn_in;
    85. IF SQL%ROWCOUNT = 0 THEN
    86. RAISE NO_DATA_FOUND;
    87. END IF;
    88. END weed;
    89. END book;
    90. /

     Benefits of Using Packages

    • Organization
    • Ease of comprehension
    • Design options
    • Performance
    • Session convenience features
    • Special PL/SQL features
    • Less recompilation pain

  • 相关阅读:
    git 中如何删除 Untracked files 文件
    简单有效的评估大小鼠的认知能力、空间记忆和学习能力——大小鼠T迷宫和Y迷宫
    研一R语言选修课程第二次课后习题分享(含代码)
    【Java】二月份有多少天?
    数据结构学习笔记(Ⅷ):排序
    Java保存数据同时支持 泰文,Emoji火星文
    我的创作纪念日--韦_恩
    Reed-Solomon Codes——RS纠错码
    Linux启动过程详解 Xmind导图笔记
    Pyg消息传递源码(MESSAGE PASSING)+实例
  • 原文地址:https://blog.csdn.net/u011868279/article/details/126152322