From 93975cf0b3f2cb9a296e591f29a941dd1f10fa84 Mon Sep 17 00:00:00 2001 From: Apress Date: Mon, 24 Oct 2016 19:29:09 +0100 Subject: [PATCH] First commit --- 2174_MasteringPLSQL_CODE/Ch01/ch1_01.txt | 9 + 2174_MasteringPLSQL_CODE/Ch01/ch1_02.txt | 31 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_03.txt | 6 + 2174_MasteringPLSQL_CODE/Ch01/ch1_04.txt | 17 + 2174_MasteringPLSQL_CODE/Ch01/ch1_05.txt | 15 + 2174_MasteringPLSQL_CODE/Ch01/ch1_06.txt | 15 + 2174_MasteringPLSQL_CODE/Ch01/ch1_07.txt | 7 + 2174_MasteringPLSQL_CODE/Ch01/ch1_08.txt | 21 + 2174_MasteringPLSQL_CODE/Ch01/ch1_09.txt | 29 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_10.txt | 29 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_11.txt | 22 + 2174_MasteringPLSQL_CODE/Ch01/ch1_12.txt | 10 + 2174_MasteringPLSQL_CODE/Ch01/ch1_13.txt | 19 + 2174_MasteringPLSQL_CODE/Ch01/ch1_14.txt | 11 + 2174_MasteringPLSQL_CODE/Ch01/ch1_15.txt | 10 + 2174_MasteringPLSQL_CODE/Ch01/ch1_16.txt | 14 + 2174_MasteringPLSQL_CODE/Ch01/ch1_17.txt | 39 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_18.txt | 17 + 2174_MasteringPLSQL_CODE/Ch01/ch1_19.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_20.txt | 39 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_21.txt | 44 ++ .../Ch01/ch1_22_reptest.txt | 65 +++ 2174_MasteringPLSQL_CODE/Ch01/ch1_23.txt | 30 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_24.txt | 39 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_25.txt | 4 + 2174_MasteringPLSQL_CODE/Ch01/ch1_26.txt | 17 + 2174_MasteringPLSQL_CODE/Ch01/ch1_27.txt | 22 + 2174_MasteringPLSQL_CODE/Ch01/ch1_28.txt | 22 + 2174_MasteringPLSQL_CODE/Ch01/ch1_29.txt | 3 + 2174_MasteringPLSQL_CODE/Ch01/ch1_30.txt | 36 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_31.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch01/ch1_32.txt | 16 + 2174_MasteringPLSQL_CODE/Ch01/ch1_33.txt | 27 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_01.txt | 23 + 2174_MasteringPLSQL_CODE/Ch02/ch2_02.txt | 45 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_03.txt | 5 + 2174_MasteringPLSQL_CODE/Ch02/ch2_04.txt | 2 + 2174_MasteringPLSQL_CODE/Ch02/ch2_05.txt | 36 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_06.txt | 21 + 2174_MasteringPLSQL_CODE/Ch02/ch2_07.txt | 46 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_08.txt | 12 + 2174_MasteringPLSQL_CODE/Ch02/ch2_09.txt | 58 +++ 2174_MasteringPLSQL_CODE/Ch02/ch2_10.txt | 12 + 2174_MasteringPLSQL_CODE/Ch02/ch2_11.txt | 42 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_12.txt | 11 + 2174_MasteringPLSQL_CODE/Ch02/ch2_13.txt | 35 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_14.txt | 16 + 2174_MasteringPLSQL_CODE/Ch02/ch2_15.txt | 13 + 2174_MasteringPLSQL_CODE/Ch02/ch2_16.txt | 58 +++ 2174_MasteringPLSQL_CODE/Ch02/ch2_17.txt | 23 + 2174_MasteringPLSQL_CODE/Ch02/ch2_18.txt | 41 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_20.txt | 8 + 2174_MasteringPLSQL_CODE/Ch02/ch2_21.txt | 26 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_22.txt | 41 ++ 2174_MasteringPLSQL_CODE/Ch02/ch2_23.txt | 5 + 2174_MasteringPLSQL_CODE/Ch02/ch2_24.txt | 68 +++ 2174_MasteringPLSQL_CODE/Ch02/ch2_25.txt | 15 + 2174_MasteringPLSQL_CODE/Ch02/ch2_26.txt | 16 + 2174_MasteringPLSQL_CODE/Ch02/ch2_27.txt | 18 + 2174_MasteringPLSQL_CODE/Ch03/ch3_01.txt | 28 ++ 2174_MasteringPLSQL_CODE/Ch03/ch3_02.txt | 15 + 2174_MasteringPLSQL_CODE/Ch03/ch3_03.txt | 18 + 2174_MasteringPLSQL_CODE/Ch03/ch3_04.txt | 34 ++ 2174_MasteringPLSQL_CODE/Ch03/ch3_05.txt | 16 + 2174_MasteringPLSQL_CODE/Ch03/ch3_06.txt | 6 + 2174_MasteringPLSQL_CODE/Ch03/ch3_07.txt | 19 + 2174_MasteringPLSQL_CODE/Ch03/ch3_08.txt | 19 + 2174_MasteringPLSQL_CODE/Ch03/ch3_09.txt | 17 + 2174_MasteringPLSQL_CODE/Ch03/ch3_10.txt | 30 ++ 2174_MasteringPLSQL_CODE/Ch03/ch3_11.txt | 23 + 2174_MasteringPLSQL_CODE/Ch03/ch3_12.txt | 13 + 2174_MasteringPLSQL_CODE/Ch03/ch3_13.txt | 9 + 2174_MasteringPLSQL_CODE/Ch03/ch3_14.txt | 5 + 2174_MasteringPLSQL_CODE/Ch03/ch3_15.txt | 20 + 2174_MasteringPLSQL_CODE/Ch03/ch3_16.txt | 13 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_01.txt | 27 ++ 2174_MasteringPLSQL_CODE/Ch04/Ch04_02.txt | 34 ++ 2174_MasteringPLSQL_CODE/Ch04/Ch04_03.txt | 20 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_04.txt | 26 ++ 2174_MasteringPLSQL_CODE/Ch04/Ch04_05.txt | 24 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_07.txt | 14 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_08.txt | 20 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_09.txt | 13 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_10.txt | 14 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_11.txt | 22 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_12.txt | 58 +++ 2174_MasteringPLSQL_CODE/Ch04/Ch04_14.txt | 6 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_15.txt | 23 + 2174_MasteringPLSQL_CODE/Ch04/Ch04_16.txt | 29 ++ 2174_MasteringPLSQL_CODE/Ch04/Ch04_17.txt | 51 +++ .../Ch04/Ch04_runstats.txt | 83 ++++ 2174_MasteringPLSQL_CODE/Ch04/ch4_06.txt | 7 + 2174_MasteringPLSQL_CODE/Ch04/ch4_18.txt | 34 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_19.txt | 51 +++ 2174_MasteringPLSQL_CODE/Ch04/ch4_20.txt | 44 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_21.txt | 22 + 2174_MasteringPLSQL_CODE/Ch04/ch4_22.txt | 29 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_23.txt | 27 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_24.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_25.txt | 29 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_26.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_27.txt | 22 + 2174_MasteringPLSQL_CODE/Ch04/ch4_28.txt | 38 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_29.txt | 37 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_30.txt | 45 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_31.txt | 23 + 2174_MasteringPLSQL_CODE/Ch04/ch4_32.txt | 42 ++ 2174_MasteringPLSQL_CODE/Ch04/ch4_33.txt | 23 + 2174_MasteringPLSQL_CODE/Ch04/ch4_34.txt | 12 + 2174_MasteringPLSQL_CODE/Ch04/ch4_35.txt | 23 + 2174_MasteringPLSQL_CODE/Ch04/ch4_36.txt | 10 + 2174_MasteringPLSQL_CODE/Ch04/ch4_37.txt | 43 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_01.txt | 32 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_02.txt | 29 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_03.txt | 24 + 2174_MasteringPLSQL_CODE/Ch05/ch5_04.txt | 78 ++++ 2174_MasteringPLSQL_CODE/Ch05/ch5_05.txt | 57 +++ 2174_MasteringPLSQL_CODE/Ch05/ch5_06.txt | 57 +++ 2174_MasteringPLSQL_CODE/Ch05/ch5_07.txt | 47 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_08.txt | 70 +++ 2174_MasteringPLSQL_CODE/Ch05/ch5_09.txt | 14 + 2174_MasteringPLSQL_CODE/Ch05/ch5_10.txt | 16 + 2174_MasteringPLSQL_CODE/Ch05/ch5_11.txt | 20 + 2174_MasteringPLSQL_CODE/Ch05/ch5_12.txt | 53 +++ 2174_MasteringPLSQL_CODE/Ch05/ch5_13.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_14.txt | 20 + 2174_MasteringPLSQL_CODE/Ch05/ch5_15.txt | 38 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_16.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_17.txt | 86 ++++ 2174_MasteringPLSQL_CODE/Ch05/ch5_18.txt | 44 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_19.txt | 22 + 2174_MasteringPLSQL_CODE/Ch05/ch5_20.txt | 80 ++++ 2174_MasteringPLSQL_CODE/Ch05/ch5_22.txt | 18 + 2174_MasteringPLSQL_CODE/Ch05/ch5_24.txt | 25 ++ 2174_MasteringPLSQL_CODE/Ch05/ch5_25.txt | 11 + 2174_MasteringPLSQL_CODE/Ch05/ch5_26.txt | 67 +++ 2174_MasteringPLSQL_CODE/Ch05/ch5_27.txt | 9 + 2174_MasteringPLSQL_CODE/Ch06/sql01.sql | 10 + 2174_MasteringPLSQL_CODE/Ch06/sql02.sql | 77 ++++ 2174_MasteringPLSQL_CODE/Ch06/sql03.sql | 28 ++ 2174_MasteringPLSQL_CODE/Ch06/sql04.sql | 15 + 2174_MasteringPLSQL_CODE/Ch06/sql05.sql | 41 ++ 2174_MasteringPLSQL_CODE/Ch06/sql06.sql | 16 + 2174_MasteringPLSQL_CODE/Ch06/sql07.sql | 26 ++ 2174_MasteringPLSQL_CODE/Ch06/sql08.sql | 3 + 2174_MasteringPLSQL_CODE/Ch06/sql09.sql | 60 +++ 2174_MasteringPLSQL_CODE/Ch06/sql10.sql | 18 + 2174_MasteringPLSQL_CODE/Ch06/sql11.sql | 12 + 2174_MasteringPLSQL_CODE/Ch06/sql12.sql | 24 + 2174_MasteringPLSQL_CODE/Ch06/sql13.sql | 9 + 2174_MasteringPLSQL_CODE/Ch06/sql14.sql | 39 ++ 2174_MasteringPLSQL_CODE/Ch06/sql15.sql | 55 +++ 2174_MasteringPLSQL_CODE/Ch06/sql16.sql | 12 + 2174_MasteringPLSQL_CODE/Ch06/sql17.sql | 63 +++ 2174_MasteringPLSQL_CODE/Ch06/sql18.sql | 34 ++ 2174_MasteringPLSQL_CODE/Ch06/sql19.sql | 30 ++ 2174_MasteringPLSQL_CODE/Ch06/sql20.sql | 18 + 2174_MasteringPLSQL_CODE/Ch06/sql21.sql | 6 + 2174_MasteringPLSQL_CODE/Ch06/sql22.sql | 37 ++ 2174_MasteringPLSQL_CODE/Ch06/sql23.sql | 14 + 2174_MasteringPLSQL_CODE/Ch06/sql24.sql | 6 + 2174_MasteringPLSQL_CODE/Ch06/sql25.sql | 25 ++ 2174_MasteringPLSQL_CODE/Ch06/sql26.sql | 34 ++ .../Ch07/Db_history_pkg_body.sql | 72 +++ .../Ch07/Db_history_pkg_spec.sql | 17 + .../Ch07/alert_file_pkg_body.sql | 180 ++++++++ .../Ch07/alert_file_pkg_spec.sql | 13 + .../Ch07/alert_file_view.sql | 33 ++ .../Ch07/create_alert_file_external_table.sql | 26 ++ .../create_notifications_alerts_table.sql | 11 + .../Ch07/notification_pkg_body.sql | 119 +++++ .../Ch07/notification_pkg_spec.sql | 21 + .../Ch07/proactive_db_pkg_body.sql | 104 +++++ .../Ch07/proactive_db_pkg_spec.sql | 19 + .../Ch08/my_proc_wrap_demo.sql | 9 + 2174_MasteringPLSQL_CODE/Ch08/page417.sql | 25 ++ 2174_MasteringPLSQL_CODE/Ch08/page418.sql | 17 + 2174_MasteringPLSQL_CODE/Ch08/page419.sql | 17 + 2174_MasteringPLSQL_CODE/Ch08/page421.sql | 26 ++ 2174_MasteringPLSQL_CODE/Ch08/page423.sql | 13 + 2174_MasteringPLSQL_CODE/Ch08/page424.sql | 3 + 2174_MasteringPLSQL_CODE/Ch08/page426.sql | 14 + 2174_MasteringPLSQL_CODE/Ch08/page427.sql | 31 ++ 2174_MasteringPLSQL_CODE/Ch08/page428.sql | 16 + 2174_MasteringPLSQL_CODE/Ch08/page432.sql | 15 + 2174_MasteringPLSQL_CODE/Ch08/page434.sql | 96 ++++ 2174_MasteringPLSQL_CODE/Ch08/page436.sql | 8 + 2174_MasteringPLSQL_CODE/Ch08/page441.sql | 9 + 2174_MasteringPLSQL_CODE/Ch08/page442.sql | 31 ++ 2174_MasteringPLSQL_CODE/Ch08/page443.sql | 79 ++++ 2174_MasteringPLSQL_CODE/Ch08/page444.sql | 52 +++ 2174_MasteringPLSQL_CODE/Ch08/page447.sql | 32 ++ 2174_MasteringPLSQL_CODE/Ch08/page449.sql | 14 + 2174_MasteringPLSQL_CODE/Ch08/page450.sql | 15 + 2174_MasteringPLSQL_CODE/Ch08/page451.sql | 14 + 2174_MasteringPLSQL_CODE/Ch08/page452.sql | 15 + 2174_MasteringPLSQL_CODE/Ch08/page455.sql | 27 ++ 2174_MasteringPLSQL_CODE/Ch08/pgae454.sql | 19 + 2174_MasteringPLSQL_CODE/Ch10/debug.pkh | 56 +++ 2174_MasteringPLSQL_CODE/Ch10/debug.sql | 417 ++++++++++++++++++ 2174_MasteringPLSQL_CODE/Ch10/debug_ddl.sql | 77 ++++ 2174_MasteringPLSQL_CODE/ch09/ch9-1.sql | 14 + 2174_MasteringPLSQL_CODE/ch09/ch9-10.sql | 29 ++ 2174_MasteringPLSQL_CODE/ch09/ch9-11.sql | 16 + 2174_MasteringPLSQL_CODE/ch09/ch9-12.sql | 20 + 2174_MasteringPLSQL_CODE/ch09/ch9-13.sql | 29 ++ 2174_MasteringPLSQL_CODE/ch09/ch9-14.sql | 4 + 2174_MasteringPLSQL_CODE/ch09/ch9-15.sql | 32 ++ 2174_MasteringPLSQL_CODE/ch09/ch9-16.sql | 45 ++ 2174_MasteringPLSQL_CODE/ch09/ch9-17.sql | 92 ++++ 2174_MasteringPLSQL_CODE/ch09/ch9-18.sql | 123 ++++++ 2174_MasteringPLSQL_CODE/ch09/ch9-19.sql | 53 +++ 2174_MasteringPLSQL_CODE/ch09/ch9-2.sql | 10 + 2174_MasteringPLSQL_CODE/ch09/ch9-20.sql | 62 +++ 2174_MasteringPLSQL_CODE/ch09/ch9-3.sql | 38 ++ 2174_MasteringPLSQL_CODE/ch09/ch9-4.sql | 7 + 2174_MasteringPLSQL_CODE/ch09/ch9-5.sql | 30 ++ 2174_MasteringPLSQL_CODE/ch09/ch9-6.sql | 11 + 2174_MasteringPLSQL_CODE/ch09/ch9-7.sql | 7 + 2174_MasteringPLSQL_CODE/ch09/ch9-8.sql | 8 + 2174_MasteringPLSQL_CODE/ch09/ch9-9.sql | 24 + 9781590592175.jpg | Bin 0 -> 9028 bytes LICENSE.txt | 27 ++ README.md | 15 + contributing.md | 14 + 225 files changed, 6942 insertions(+) create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_01.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_02.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_03.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_04.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_05.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_06.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_07.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_08.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_09.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_10.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_11.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_12.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_13.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_14.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_15.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_16.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_17.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_18.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_19.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_20.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_21.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_22_reptest.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_23.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_24.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_25.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_26.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_27.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_28.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_29.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_30.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_31.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_32.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch01/ch1_33.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_01.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_02.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_03.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_04.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_05.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_06.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_07.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_08.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_09.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_10.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_11.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_12.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_13.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_14.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_15.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_16.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_17.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_18.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_20.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_21.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_22.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_23.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_24.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_25.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_26.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch02/ch2_27.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_01.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_02.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_03.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_04.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_05.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_06.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_07.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_08.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_09.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_10.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_11.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_12.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_13.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_14.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_15.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch03/ch3_16.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_01.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_02.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_03.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_04.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_05.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_07.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_08.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_09.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_10.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_11.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_12.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_14.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_15.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_16.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_17.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/Ch04_runstats.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_06.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_18.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_19.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_20.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_21.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_22.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_23.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_24.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_25.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_26.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_27.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_28.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_29.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_30.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_31.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_32.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_33.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_34.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_35.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_36.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch04/ch4_37.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_01.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_02.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_03.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_04.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_05.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_06.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_07.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_08.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_09.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_10.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_11.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_12.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_13.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_14.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_15.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_16.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_17.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_18.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_19.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_20.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_22.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_24.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_25.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_26.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch05/ch5_27.txt create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql01.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql02.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql03.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql04.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql05.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql06.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql07.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql08.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql09.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql10.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql11.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql12.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql13.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql14.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql15.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql16.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql17.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql18.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql19.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql20.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql21.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql22.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql23.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql24.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql25.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch06/sql26.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_body.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_spec.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_body.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_spec.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/alert_file_view.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/create_alert_file_external_table.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/create_notifications_alerts_table.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/notification_pkg_body.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/notification_pkg_spec.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_body.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_spec.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/my_proc_wrap_demo.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page417.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page418.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page419.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page421.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page423.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page424.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page426.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page427.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page428.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page432.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page434.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page436.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page441.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page442.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page443.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page444.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page447.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page449.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page450.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page451.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page452.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/page455.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch08/pgae454.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch10/debug.pkh create mode 100755 2174_MasteringPLSQL_CODE/Ch10/debug.sql create mode 100755 2174_MasteringPLSQL_CODE/Ch10/debug_ddl.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-1.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-10.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-11.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-12.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-13.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-14.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-15.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-16.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-17.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-18.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-19.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-2.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-20.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-3.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-4.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-5.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-6.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-7.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-8.sql create mode 100755 2174_MasteringPLSQL_CODE/ch09/ch9-9.sql create mode 100755 9781590592175.jpg create mode 100755 LICENSE.txt create mode 100755 README.md create mode 100755 contributing.md diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_01.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_01.txt new file mode 100755 index 0000000..a24bf59 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_01.txt @@ -0,0 +1,9 @@ +PROCEDURE insert_blob_proc IS + Blob_loc BLOB; +BEGIN + SELECT ad_photo INTO Blob_loc + FROM Print_media + WHERE product_id = 3106 AND ad_id=13001; + INSERT INTO Print_media VALUES (2056, 12001, Blob_loc); +END; + diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_02.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_02.txt new file mode 100755 index 0000000..537a946 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_02.txt @@ -0,0 +1,31 @@ +#include +#include +#include +void Sample_Error() +{ +EXEC SQL WHENEVER SQLERROR CONTINUE; +printf(“%.*s\n”, sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc); +EXEC SQL ROLLBACK WORK RELEASE; +exit(1); +} +void insertBLOB_proc() +{ +OCIBlobLocator *Lob_loc; +EXEC SQL WHENEVER SQLERROR DO Sample_Error(); +/* Initialize the BLOB Locator: */ +EXEC SQL ALLOCATE :Lob_loc; +EXEC SQL SELECT ad_photo INTO :Lob_loc +FROM Print_media WHERE product_id = 2268 AND ad_id = 21001; +/* Insert into the row where product_id = 3106 and ad_id = 13001: */ +EXEC SQL INSERT INTO Print_media +VALUES (3106, 13001, :Lob_loc); +/* Release resources held by the locator: */ +EXEC SQL FREE :Lob_loc; +} +void main() +{ +char *samp = “pm/pm”; +EXEC SQL CONNECT :pm; +insertBLOB_proc(); +EXEC SQL ROLLBACK WORK RELEASE; +} \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_03.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_03.txt new file mode 100755 index 0000000..1fd09dc --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_03.txt @@ -0,0 +1,6 @@ +create table customers ( +pin_number number(6) ); + +alter table customers +add constraint customers_pk +primary key (pin_number); diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_04.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_04.txt new file mode 100755 index 0000000..c6ef21e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_04.txt @@ -0,0 +1,17 @@ +create or replace +procedure gen_customer is + v_new_cid customers.pin_number%type; +begin + loop + begin + v_new_cid := round(dbms_random.value(1000000,9999999)); + insert into customers + values (v_new_cid); + exit; + exception when dup_val_on_index then + null; + end; + end loop; +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_05.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_05.txt new file mode 100755 index 0000000..65dfd6b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_05.txt @@ -0,0 +1,15 @@ +set timing on +begin + gen_customer; + commit; +end; +/ + +begin + for i in 1 .. 100000 loop + gen_customer; + end loop; + commit; +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_06.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_06.txt new file mode 100755 index 0000000..3c0dc63 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_06.txt @@ -0,0 +1,15 @@ +alter table CUSTOMERS modify PIN_NUMBER number(12); +create sequence cust_seq cache 1000 +start with 100000; + +create or replace +procedure gen_customer is + v_new_cid customers.pin_number%type; +begin + insert into customers + values (cust_seq.nextval*100000+ + round(dbms_random.value(100000,999999))); +end; +/ + + diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_07.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_07.txt new file mode 100755 index 0000000..03640a7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_07.txt @@ -0,0 +1,7 @@ +begin +for i in 1 .. 10000 loop +gen_customer; +end loop; +commit; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_08.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_08.txt new file mode 100755 index 0000000..7fd8400 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_08.txt @@ -0,0 +1,21 @@ +alter system set job_queue_processes = 20; +create table CUSTLOG ( elapsed_centiseconds number); + +declare + j number; + job_string varchar2(1000) := + ‘declare + s number := dbms_utility.get_time; + begin + for i in 1 .. 10000 loop + gen_customer; + end loop; + insert into custlog values (dbms_utility.get_time-s); + commit; + end;’; +begin + for i in 1 .. 20 loop + dbms_job.submit(j,job_string); +end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_09.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_09.txt new file mode 100755 index 0000000..b1e04c5 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_09.txt @@ -0,0 +1,29 @@ +create table people( pid primary key ) + organization index + as select rownum from all_objects + where rownum <= 10000; + +create or replace +procedure literals is + c number; + p number; + x number; + x1 number; +begin +for i in 1 .. 10000 loop + c := dbms_sql.open_cursor; + dbms_sql.parse(c, + ‘select pid from people ‘|| + ‘where pid = ‘||i, dbms_sql.native); + x := dbms_sql.execute(c); + x1 := dbms_sql.fetch_rows(c); + dbms_sql.close_cursor(c); +end loop; +end; +/ + +set timing on +alter session set sql_trace = true; +exec literals; +alter session set sql_trace = false; + diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_10.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_10.txt new file mode 100755 index 0000000..64af5fc --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_10.txt @@ -0,0 +1,29 @@ +create or replace +procedure literals(tag number) is + c number; + p number; + x number; + x1 number; +begin +for i in 1 .. 10000 loop + c := dbms_sql.open_cursor; + dbms_sql.parse(c, + ‘select pid t’||tag||’ from people ‘|| + ‘where pid = ‘||i, dbms_sql.native); + x := dbms_sql.execute(c); + x1 := dbms_sql.fetch_rows(c); + dbms_sql.close_cursor(c); +end loop; +end; +/ + + +exec literals(1); +exec literals(2); +exec literals(3); +exec literals(4); + +select sid, event, time_waited +from v$session_event +where sid = &sid +and event = ‘latch free’; diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_11.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_11.txt new file mode 100755 index 0000000..2ce6ea4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_11.txt @@ -0,0 +1,22 @@ +create or replace + procedure binding is + c number; + p number; + x number; + x1 number; +begin + for i in 1 .. 10000 loop + c := dbms_sql.open_cursor; + dbms_sql.parse(c, + ‘select pid from people ‘|| + ‘where pid = :b1’, dbms_sql.native); + dbms_sql.bind_variable(c,’:b1’,i); + x := dbms_sql.execute(c); + x1 := dbms_sql.fetch_rows(c); + dbms_sql.close_cursor(c); + end loop; + end; +/ + +alter session set sql_trace = true; +exec binding diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_12.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_12.txt new file mode 100755 index 0000000..847e242 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_12.txt @@ -0,0 +1,10 @@ +create or replace + view V$MYSTATS as + select s.name, m.value + from v$mystat m, v$statname s + where s.statistic# = m.statistic#; + +grant select on V$MYSTATS to public; +create or replace public synonym V$MYSTATS for V$MYSTATS; +select * from v$mystats +where name like ‘parse%’; diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_13.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_13.txt new file mode 100755 index 0000000..09ec2c6 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_13.txt @@ -0,0 +1,19 @@ +create or replace +procedure binding is + c number; + p number; + x number; + x1 number; + begin + c := dbms_sql.open_cursor; + dbms_sql.parse(c, + ‘select pid from people ‘|| + ‘where pid = :b1’, dbms_sql.native); + for i in 1 .. 10000 loop + dbms_sql.bind_variable(c,’:b1’,i); + x := dbms_sql.execute(c); + x1 := dbms_sql.fetch_rows(c); + end loop; + dbms_sql.close_cursor(c); +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_14.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_14.txt new file mode 100755 index 0000000..77c8e94 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_14.txt @@ -0,0 +1,11 @@ +create or replace + procedure EASY_AS_THAT is + x1 number; +begin + for i in 1 .. 10000 loop + select pid into x1 + from people + where pid = i; + end loop; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_15.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_15.txt new file mode 100755 index 0000000..a6d6529 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_15.txt @@ -0,0 +1,10 @@ +create or replace + procedure UPDATE_EMP(p_empno number, p_decrease number) is + begin + update EMP + set SAL = SAL / p_decrease + where empno = p_empno; +end; +/ +exec UPDATE_EMP(7369,2); +exec UPDATE_EMP(7369,0); diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_16.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_16.txt new file mode 100755 index 0000000..53348fb --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_16.txt @@ -0,0 +1,14 @@ +create or replace +procedure UPDATE_EMP(p_empno number, p_decrease number, +p_success out boolean) is + begin + if p_decrease = 0 then + p_success := false; + else + update EMP + set SAL = SAL / p_decrease + where empno = p_empno; + p_success := true; + end if; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_17.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_17.txt new file mode 100755 index 0000000..b2dd26e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_17.txt @@ -0,0 +1,39 @@ +create or replace + function binary_and(x number, y number) return number is + max_bin number(22) := power(2,64); + l_x number := x; + l_y number := y; + result number := 0; + begin + for i in reverse 0 .. 64 loop + if l_x >= max_bin and l_y >= max_bin then + result := result + max_bin; + end if; + if l_x >= max_bin then + l_x := l_x - max_bin; + end if; + if l_y >= max_bin then + l_y := l_y - max_bin; + end if; + max_bin := max_bin/2; + end loop; + return result; +end; +/ + +declare + x number; +begin + for i in 1 .. 50000 loop + x:= binary_and(i,i+1); + end loop; +end; +/ +declare + x number; +begin + for i in 1 .. 50000 loop + x:= bitand(i,i+1); + end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_18.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_18.txt new file mode 100755 index 0000000..0f4c495 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_18.txt @@ -0,0 +1,17 @@ +create table SRC ( x number ) pctfree 0; +insert into SRC + select rownum + from all_objects + where rownum < 10000; + + +create table T1 as + select trunc(created) created + from all_objects; + +select trunc(sysdate)-14+x created, count(created) no_of_obj + from t1, src + where trunc(sysdate)-14+x = t1.created(+) + and x <= 14 + group by trunc(sysdate)-14+x +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_19.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_19.txt new file mode 100755 index 0000000..6411777 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_19.txt @@ -0,0 +1,25 @@ +create or replace + type date_list is table of Date; +/ +create or replace + function pipe_date(p_start date, p_limit number) + return date_list pipelined is + begin + for i in 0 .. p_limit-1 loop + pipe row (p_start + i); + end loop; + return; + end; +/ + +select column_value, count(created) no_of_obj + from t1, table(pipe_date(trunc(sysdate)-14,14)) + where column_value = t1.created(+) + group by column_value +/ + +select /*+ CARDINALITY(t 14) */ column_value, count(created) no_of_obj + from t1, table(pipe_date(trunc(sysdate)-14,14)) t + where column_value = t1.created(+) + group by column_value +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_20.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_20.txt new file mode 100755 index 0000000..7e576ed --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_20.txt @@ -0,0 +1,39 @@ +drop table EMP; +drop table DEPT; +create table EMP ( + EMPNO NUMBER(8), + ENAME VARCHAR2(20), + HIREDATE DATE, + SAL NUMBER(7,2), + DEPTNO NUMBER(6) ); +create table DEPT ( + DEPTNO NUMBER(6), + DNAME VARCHAR2(20) ); +alter table EMP add constraint EMP_PK + primary key (EMPNO); +alter table DEPT add constraint DEPT_PK + primary key (DEPTNO); + +create table SRC ( x varchar2(10)); + +begin + for i in 1 .. 200000 loop + insert into SRC values (‘x’); + end loop; + end; +/ +commit; + +insert into EMP + select rownum, + ‘Name’||rownum, + sysdate+rownum/100, + dbms_random.value(7500,10000), + dbms_random.value(1,10) + from SRC + where rownum <= 500; + +insert into DEPT + select rownum, ‘Dept’||rownum + from SRC + where rownum <= 10; diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_21.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_21.txt new file mode 100755 index 0000000..2e3f945 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_21.txt @@ -0,0 +1,44 @@ +create table EMP_SAL_LOG ( + ENAME VARCHAR2(20), + HIREDATE DATE, + SAL NUMBER(7,2), + DNAME VARCHAR2(20), + MIN_SAL VARCHAR2(1) ); + + +create or replace + procedure report_sal_adjustment is + v_avg_dept_sal emp.sal%type; + v_min_dept_sal emp.sal%type; + v_dname dept.dname%type; + cursor c_emp_list is + select empno, ename, deptno, sal, hiredate + from emp; +begin + for each_emp in c_emp_list loop + select avg(sal) + into v_avg_dept_sal + from emp + where deptno = each_emp.deptno; + if abs(each_emp.sal - v_avg_dept_sal ) / v_avg_dept_sal > 0.20 then + select dept.dname, min(emp.sal) + into v_dname, v_min_dept_sal + from dept, emp + where dept.deptno = each_emp.deptno + and emp.deptno = dept.deptno + group by dname; + if v_min_dept_sal = each_emp.sal then + insert into emp_sal_log + values ( each_emp.ename, each_emp.hiredate, + each_emp.sal, v_dname, ‘Y’); + else + insert into emp_sal_log + values ( each_emp.ename, each_emp.hiredate, + each_emp.sal, v_dname, ‘Y’); + end if; + end if; +end loop; +end; +/ + +exec report_sal_adjustment diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_22_reptest.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_22_reptest.txt new file mode 100755 index 0000000..7322966 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_22_reptest.txt @@ -0,0 +1,65 @@ +rem REPTEST.SQL +rem —————— +rem Takes as input two parameters, the first being +rem the number of employees, the second the number +rem of departments. Employees are assigned at random +rem to departments, and salaries are randomised between +rem 7500 and 10000 +rem +set termout off +rem Number of employees will be passed as the first parameter, +rem number of departments as the second. We want to assign these +rem values to two SQL Plus substitution variables called NUM_EMPS +rem and NUM_DEPTS respectively +col x new_value num_emps +col y new_value num_depts +rem Select the values from DUAL to complete the assigment +select &1 x, &2 y from dual; +rem Now we erase the contents of the EMP table and DEPT table +rem in preparation for population with sample data +truncate table EMP reuse storage; +truncate table DEPT reuse storage; +rem Now we load up the EMP table just like we did in the +rem previous example, using the SRC table to generate as +rem many rows as we require +insert into EMP +select rownum, +‘Name’||rownum, +sysdate+rownum/100, +dbms_random.value(7500,10000), +dbms_random.value(1,&num_depts) +from SRC +where rownum <= &num_emps; +rem We do a similar exercise with the DEPT table to load +rem the required number of department rows +insert into DEPT +select rownum, ‘Dept’||rownum +from sys.source$ +where rownum <= &num_depts; +rem And for good measure, we will calculate optimizer +rem statistics on the two tables, because no-one should +rem be using the rule based optimizer anymore +analyze table emp compute statistics; +analyze table dept compute statistics; +rem We truncate our results table in preparation for the test +truncate table EMP_SAL_LOG; +rem And now, here is the real testing portion of the script +rem We will run the procedure 3 times, and report an average +rem execution time across the 3 executions. To do this, we +rem use the DBMS_UTILITY.GET_TIME function to give start and +rem end timings for the test – the delta of these two times +rem is the total time elapsed (in centiseconds). Dividing +rem by 100 and then by 3, gives us the average execution +rem time in seconds. +set serverout on +set termout on +declare +x number := dbms_utility.get_time; +begin +for i in 1 .. 3 loop +report_sal_adjustment; +end loop; +dbms_output.put_line(‘Average run time: ‘|| +round((dbms_utility.get_time-x)/3/100,2)); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_23.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_23.txt new file mode 100755 index 0000000..2a49e1b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_23.txt @@ -0,0 +1,30 @@ +create or replace + procedure report_sal_adjustment2 is + v_avg_dept_sal emp.sal%type; + v_min_dept_sal emp.sal%type; + v_dname dept.dname%type; + cursor c_emp_list is + select empno, ename, deptno, sal, hiredate + from emp; +begin + for each_emp in c_emp_list loop + select avg(emp.sal), min(emp.sal), dept.dname + into v_avg_dept_sal, v_min_dept_sal,v_dname + from dept, emp + where dept.deptno = each_emp.deptno + and emp.deptno = dept.deptno + group by dname; + if abs(each_emp.sal - v_avg_dept_sal ) / v_avg_dept_sal > 0.20 then + if v_min_dept_sal = each_emp.sal then + insert into emp_sal_log + values ( each_emp.ename, each_emp.hiredate, + each_emp.sal, v_dname, ‘Y’); + else + insert into emp_sal_log + values ( each_emp.ename, each_emp.hiredate, + each_emp.sal, v_dname, ‘Y’); + end if; + end if; + end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_24.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_24.txt new file mode 100755 index 0000000..1a5035a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_24.txt @@ -0,0 +1,39 @@ +create or replace + procedure report_sal_adjustment3 is + type dept_sal_details is record ( + avg_dept_sal emp.sal%type, + min_dept_sal emp.sal%type, + dname dept.dname%type ); + type dept_sals is table of dept_sal_details + index by binary_integer; + v_dept_sal dept_sals; + cursor c_emp_list is + select empno, ename, deptno, sal, hiredate + from emp; + cursor c_dept_salaries is + select avg(sal) asal, min(sal) msal, dname, dept.deptno + from dept, emp + where emp.deptno = dept.deptno + group by dname, dept.deptno; +begin + for i in c_dept_salaries loop + v_dept_sal(i.deptno).avg_dept_sal := i.asal; + v_dept_sal(i.deptno).min_dept_sal := i.msal; + v_dept_sal(i.deptno).dname := i.dname; + end loop; + for each_emp in c_emp_list loop + if abs(each_emp.sal - v_dept_sal(each_emp.deptno).avg_dept_sal ) / + v_dept_sal(each_emp.deptno).avg_dept_sal > 0.20 then + if v_dept_sal(each_emp.deptno).min_dept_sal = each_emp.sal then + insert into emp_sal_log + values ( each_emp.ename, each_emp.hiredate, + each_emp.sal, v_dept_sal(each_emp.deptno).dname, ‘Y’); + else + insert into emp_sal_log + values ( each_emp.ename, each_emp.hiredate, each_emp.sal, + v_dept_sal(each_emp.deptno).dname, ‘Y’); + end if; + end if; +end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_25.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_25.txt new file mode 100755 index 0000000..60297f9 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_25.txt @@ -0,0 +1,4 @@ +col value format 999,999,999 +select * from v$mystats + where name = ‘ session pga memory max’ +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_26.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_26.txt new file mode 100755 index 0000000..999143a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_26.txt @@ -0,0 +1,17 @@ +create or replace + procedure report_sal_adjustment4 is +begin + insert into emp_sal_log + select e.empno, e.hiredate, e.sal, dept.dname, + case when sal > avg_sal then ‘Y’ + else ‘N’ + end case + from ( + select empno, hiredate, sal, deptno, + avg(sal) over ( partition by deptno ) as avg_sal, + min(sal) over ( partition by deptno ) as min_sal + from emp ) e, dept + where e.deptno = dept.deptno + and abs(e.sal - e.avg_sal)/e.avg_sal > 0.20; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_27.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_27.txt new file mode 100755 index 0000000..3b96e65 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_27.txt @@ -0,0 +1,22 @@ +create or replace view YEARLY_BONUS as +select emp.empno, emp.ename, dept.dname, emp.bonus +from EMP, DEPT +where emp.hiredate < sysdate + 1 +and emp.deptno = dept.deptno; + +create or replace +procedure XXX is +begin +for i in ( select empno from yearly_bonus ) loop +update emp +set bonus = bonus * 1.1 +where empno = i.empno; +end; +/ + + +update ( select emp.ename, dept.dname, emp.bonus +from EMP, DEPT +where emp.hiredate < sysdate + 1 +and emp.deptno = dept.deptno) +set bonus = bonus * 1.1; diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_28.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_28.txt new file mode 100755 index 0000000..facc5e1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_28.txt @@ -0,0 +1,22 @@ +col dte new_value mdate +select ‘23-JUN-03’ dte from dual; +select + max(decode(dow,1,d,null)) Sun, + max(decode(dow,2,d,null)) Mon, + max(decode(dow,3,d,null)) Tue, + max(decode(dow,4,d,null)) Wed, + max(decode(dow,5,d,null)) Thu, + max(decode(dow,6,d,null)) Fri, + max(decode(dow,7,d,null)) Sat + from + ( select rownum d, + rownum-2+to_number( + to_char(trunc( + to_date(‘&mdate’),’MM’),’D’)) p, + to_char(trunc(to_date(‘&mdate’),’MM’) + -1+rownum,’D’) dow + from SRC + where rownum <= to_number(to_char( + last_day(to_date(‘&mdate’)),’DD’))) + group by trunc(p/7) +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_29.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_29.txt new file mode 100755 index 0000000..7079d74 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_29.txt @@ -0,0 +1,3 @@ +select percentile_cont(0.5) + within group (order by sal desc ) median_sal + from emp; diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_30.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_30.txt new file mode 100755 index 0000000..d533f37 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_30.txt @@ -0,0 +1,36 @@ +@$ORACLE_HOME/sqlplus/demo/demobld.sql +create table STAFF ( + staffno number, + name varchar2(30), + class_type number, + class_id number); + +reate table part_time_package ( + id number, + fixed_price number ); + +create table contract_package ( + id number, + hrly_rate number, + hrs number ); + +create table perm_package ( + id number, + annual_sal number, + bonus number ); + +insert into part_time_package + select rownum, rownum*130 + from SRC where rownum < 6; + +insert into contract_package + select rownum, rownum*10, rownum*30 + from SRC where rownum < 6; + +insert into perm_package + select rownum, rownum*10000, rownum*500 + from SRC where rownum < 6; + rows created. + +insert into staff + select empno, ename, mod(rownum,3)+1, mod(rownum,5)+1 from emp; diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_31.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_31.txt new file mode 100755 index 0000000..4e2f380 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_31.txt @@ -0,0 +1,25 @@ +create or replace + procedure SHOW_SAL is + v_sal number; + begin + for i in ( select * from staff ) loop + if i.class_type = 1 then + select fixed_price + into v_sal + from part_time_package + where id = i.class_id; + elsif i.class_type = 2 then + select hrs * hrly_rate + into v_sal + from contract_package + where id = i.class_id; + elsif i.class_type = 3 then — permanent + select annual_sal + bonus + into v_sal + from perm_package + where id = i.class_id; + end if; + dbms_output.put_line(rpad(i.name,20)||lpad(v_sal,10)); + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_32.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_32.txt new file mode 100755 index 0000000..be871ea --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_32.txt @@ -0,0 +1,16 @@ +select s.name, + case class_type + when 1 then ( + select fixed_price + from part_time_package + where id = s.class_id ) + when 2 then ( + select hrs * hrly_rate + from contract_package + where id = s.class_id ) + when 3 then ( + select annual_sal + bonus + from perm_package + where id = s.class_id ) + end sal + from staff s; \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch01/ch1_33.txt b/2174_MasteringPLSQL_CODE/Ch01/ch1_33.txt new file mode 100755 index 0000000..366a1d4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch01/ch1_33.txt @@ -0,0 +1,27 @@ +create table SAMPLES ( + lab_id varchar2(10), + animal varchar2(10), + experiment_id number, + probability number ); +set feedback off +insert into SAMPLES values (‘OXFORD’,’RATS’,1,0.993); +insert into SAMPLES values (‘OXFORD’,’RATS’,2,0.93); +insert into SAMPLES values (‘OXFORD’,’RATS’,3,0.91); +insert into SAMPLES values (‘OXFORD’,’MICE’,1,0.91); +insert into SAMPLES values (‘OXFORD’,’MICE’,2,0.99); +insert into SAMPLES values (‘OXFORD’,’MICE’,3,0.90); +insert into SAMPLES values (‘HARVARD’,’RATS’,1,0.993); +insert into SAMPLES values (‘HARVARD’,’RATS’,2,0.93); +insert into SAMPLES values (‘HARVARD’,’RATS’,3,0.91); +insert into SAMPLES values (‘HARVARD’,’MICE’,1,0.91); +insert into SAMPLES values (‘HARVARD’,’MICE’,2,0.99); +insert into SAMPLES values (‘HARVARD’,’MICE’,3,0.90); +set feedback on + +SELECT lab_id, animal, experiment_id, s + FROM samples + SPREADSHEET PARTITION BY (lab_id) + DIMENSION BY (animal, experiment_id) + MEASURES (probability s) IGNORE nav + (s[‘MICE’,-1]=s[‘MICE’,1]*s[‘MICE’,2]*s[‘MICE’,3], + s[‘RATS’,-1]=s[‘RATS’,1]*s[‘RATS’,2]*s[‘RATS’,3]); diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_01.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_01.txt new file mode 100755 index 0000000..bafb85e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_01.txt @@ -0,0 +1,23 @@ +create or replace +package emp_maint is +procedure hire_emp(p_empno number, p_name varchar2); +procedure fire_emp(p_empno); +procedure raise_salary(p_empno number, p_salary number); +end; +/ +create or replace +package body emp_maint is +procedure hire_emp(p_empno number, p_name varchar2) is +begin +insert into emp (empno, name) values (p_empno, p_name); +end; +procedure fire_emp(p_empno) is +begin +delete from emp where empno = p_empno; +end; +procedure raise_salary(p_empno number, p_salary number) is +begin +update emp set sal = p_salary where empno = p_empno; +end; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_02.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_02.txt new file mode 100755 index 0000000..2cc1fa1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_02.txt @@ -0,0 +1,45 @@ +create or replace +package emp_maint is +cursor annual_review_candidates return emp%rowtype; +v_last_empno_used number; +procedure hire_emp(p_empno number, p_name varchar2); +procedure fire_emp(p_empno number); +procedure raise_salary(p_empno number, p_salary number); +procedure hire_emp (p_empno number, p_name varchar2, +p_hiredate date, p_sal number); +end; +/ +create or replace +package body emp_maint is +cursor annual_review_candidates return emp%rowtype is +select * from emp where hiredate > trunc(sysdate,'YYYY'); +v_pkg_execution_count number := 0; +procedure hire_emp(p_empno number, p_name varchar2) is +begin +insert into emp … +end; +procedure fire_emp(p_empno number) is +begin +delete from emp … +end; +procedure raise_salary(p_empno number, p_salary number) is +begin +update emp … +end; +procedure check_sal_limit(p_empno number) is +begin +… +end; +procedure hire_emp(p_empno number, p_name varchar2, +p_hiredate date, p_sal number) is +begin +check_sal_limit(p_empno); +insert into emp.. +end; +begin +select empno into v_last_empno_used from EMP +where hiredate = ( select max(hiredate) +from emp ) +and rownum = 1; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_03.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_03.txt new file mode 100755 index 0000000..05a81cd --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_03.txt @@ -0,0 +1,5 @@ +select name, type, + referenced_name, referenced_type + from user_Dependencies + where name = 'EMP_MAINT' +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_04.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_04.txt new file mode 100755 index 0000000..46b33be --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_04.txt @@ -0,0 +1,2 @@ +exec deptree_fill('TABLE',user,'EMP'); +select * from ideptree; \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_05.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_05.txt new file mode 100755 index 0000000..d9edb4e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_05.txt @@ -0,0 +1,36 @@ +create or replace + procedure P1 is + v_cnt number; + begin + select count(*) + into v_cnt + from emp; + end; +/ +create or replace + procedure P2 is + begin + P1; + end; +/ +create or replace + procedure P3 is + begin + P2; + end; +/ +create or replace + procedure P4 is + begin + P3; + end; +/ + +select name, type, +referenced_name, referenced_type + from user_Dependencies +/ + +select object_name, status + from user_objects + where object_name in ('P1','P2','P3','P4'); diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_06.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_06.txt new file mode 100755 index 0000000..bdfccdb --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_06.txt @@ -0,0 +1,21 @@ +create or replace + procedure P1 is + v_cnt number; + begin + select count(*) + into v_cnt + from emp + where empno > 0; + end; +/ + +select object_name, status + from user_objects + where object_name in ('P1','P2','P3','P4'); + +exec p3 + +select object_name, status + from user_objects + where object_name in ('P1','P2','P3','P4'); + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_07.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_07.txt new file mode 100755 index 0000000..cdcd4f3 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_07.txt @@ -0,0 +1,46 @@ +create or replace + procedure p0 is + begin + null; + end; + / + +declare + x varchar2(32767); + y varchar2(32767); + begin + for i in 1 .. 50 loop + execute immediate + 'create or replace procedure prc_'||to_char(i,'fm0000')|| + ' is begin p0; end;'; + x := x || 'prc_'||to_char(i,'fm0000')||'; '; + end loop; + for i in 51 .. 100 loop + execute immediate + 'create or replace procedure prc_'||to_char(i,'fm0000')|| + ' is begin '||x||' end;'; + y := y || 'prc_'||to_char(i,'fm0000')||'; '; + end loop; + execute immediate + 'create or replace procedure prc_main '|| + ' is begin '||y||' end;'; + end; +/ +select name, type, + referenced_name, referenced_type + from user_Dependencies +where name like 'PRC_____' + + +create or replace + procedure P0 is + x number; + begin + x := 1; + end; +/ + +select object_name, status + from user_Objects + where object_name like 'PRC%' +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_08.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_08.txt new file mode 100755 index 0000000..d24a6f2 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_08.txt @@ -0,0 +1,12 @@ +create table x1 as select * from v$mystats; +exec prc_main; +create table x2 as select * from v$mystats; +exec prc_main; +create table x3 as select * from v$mystats; + +select x2.name, x3.value-x2.value NORMAL_RUN, + x2.value-x1.value WITH_RECOMP + from x1, x2, x3 + where x2.name = x1.name + and x3.name = x2.name + order by 3; diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_09.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_09.txt new file mode 100755 index 0000000..e09278f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_09.txt @@ -0,0 +1,58 @@ +create or replace package PKG1 is + procedure P1; end; +/ +create or replace package body PKG1 is + procedure P1 is + v_cnt number; + begin + select count(*) + into v_cnt + from emp; + end; + end; +/ +create or replace package PKG2 is +procedure P2; end; +/ +create or replace package body PKG2 is + procedure P2 is + begin + PKG1.P1; + end; + end; +/ +create or replace package PKG3 is + procedure P3; end; +/ +create or replace package body PKG3 is + procedure P3 is + begin + PKG2.P2; + end; +end; +/ +create or replace package PKG4 is + procedure P4; end; +/ +create or replace package body PKG4 is + procedure P4 is + begin + PKG3.P3; + end; + end; +/ +create or replace package body PKG1 is + procedure P1 is + v_cnt number; + begin + select count(*) + into v_cnt + from emp + where empno > 0; + end; + end; +/ + +select object_name, object_type, status + from user_objects + where object_name in ('PKG1','PKG2','PKG3','PKG4'); diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_10.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_10.txt new file mode 100755 index 0000000..5a3d7a7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_10.txt @@ -0,0 +1,12 @@ +create or replace +package globals is +g_gender_m constant char(1) := 'M'; +g_gender_f constant char(1) := 'F'; +g_error_msg_misc constant varchar2(80) +:= 'An unknown error has occurred'; +g_error_msg_gender constant varchar2(80) +:= 'Gender must be '|| g_gender_m|| ' or '|| g_gender_f; +… +… +end; + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_11.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_11.txt new file mode 100755 index 0000000..1a38c7d --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_11.txt @@ -0,0 +1,42 @@ +create or replace + package globals is + g_1 constant number(5) := 1; + g_2 constant number(5) := 1; + g_3 constant number(5) := 1; + end; +/ + +create or replace + function use_g1 return number is + begin + return globals.g_1; + end; +/ + +create or replace + function use_g2 return number is + x number; + begin + select globals.g_3 into x + from dual + where globals.g_2 = globals.g_2; + return x; + end; +/ + +declare + d number; + s number; + begin + s := dbms_utility.get_time; + for i in 1 .. 1000000 loop + d := use_g1; + end loop; + dbms_output.put_line((dbms_utility.get_time-s)/100||' seconds for usage'); + s := dbms_utility.get_time; + for i in 1 .. 50000 loop + d := use_g2; + end loop; + dbms_output.put_line((dbms_utility.get_time-s)/100' seconds for usage in SQL'); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_12.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_12.txt new file mode 100755 index 0000000..abd04e2 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_12.txt @@ -0,0 +1,11 @@ +create or replace + package globals is + g_1 number(5) := 1; + g_2 number(5) := 1; + g_3 number(5) := 1; + g_new_global number(5) := 1; + end; +/ +select object_name, status + from user_Objects + where object_name in ('USE_G1','USE_G2'); diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_13.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_13.txt new file mode 100755 index 0000000..94bebcf --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_13.txt @@ -0,0 +1,35 @@ +create or replace + context glob using pkg_security.set_values; +create or replace + package PKG_SECURITY is + procedure set_values; + end; +/ +create or replace + package body PKG_SECURITY is + procedure set_values is + begin + dbms_session.set_context('glob','g_1',1); + dbms_session.set_context('glob','g_2',2); + dbms_session.set_context('glob','g_3',3); + end; +/ + +create or replace + function use_g1 return number is + begin + return sys_context('glob','g_1'); + end; +/ + +create or replace + function use_g2 return number is + x number; + begin + select sys_context('glob','g_3') into x + from dual + where sys_context(‘glob’,’g_2’) = sys_context(‘glob’,’g_2’); + return x; + end; +/ +exec set_values diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_14.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_14.txt new file mode 100755 index 0000000..a28cd44 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_14.txt @@ -0,0 +1,16 @@ +declare + d number; + s number; + begin + s := dbms_utility.get_time; + for i in 1 .. 50000 loop + d := use_g1; + end loop; + dbms_output.put_line((dbms_utility.get_time-s)/100||' seconds for usage'); + s := dbms_utility.get_time; + for i in 1 .. 50000 loop + d := use_g2; + end loop; + dbms_output.put_line((dbms_utility.get_time-s)/100' seconds for usage in SQL'); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_15.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_15.txt new file mode 100755 index 0000000..66b949e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_15.txt @@ -0,0 +1,13 @@ +create or replace + package body PKG_SECURITY is + procedure set_values is + begin + dbms_session.set_context('glob','g_1',1); + dbms_session.set_context('glob','g_2',2); + dbms_session.set_context('glob','g_3',3); + dbms_session.set_context(‘glob’,’g_new_global’,3); + end; +/ +select object_name, status +from user_Objects +where object_name in ('USE_G1','USE_G2'); diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_16.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_16.txt new file mode 100755 index 0000000..2b809d1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_16.txt @@ -0,0 +1,58 @@ +create or replace + package new_globals is + function g(gname in varchar2) return number; + end; +/ +create or replace + package body new_globals is + + type num_tab is table of number + index by varchar2(30); + + n num_tab; + + function g(gname in varchar2) return number is + begin + return n(gname); + end; + + begin + n('g_1') := 1; + n('g_2') := 1; + n('g_3') := 1; + end; +/ + +create or replace + function use_g1 return number is + begin + return new_globals.g('g_1'); + end; +/ +create or replace + function use_g2 return number is + x number; + begin + select new_globals.g('g_3') into x + from dual + where new_globals.g('g_2') = new_globals.g('g_2'); + return x; + end; +/ + +declare + d number; + s number; + begin + s := dbms_utility.get_time; + for i in 1 .. 1000000 loop + d := use_g1; + end loop; + dbms_output.put_line((dbms_utility.get_time-s)/100||' seconds for usage'); + s := dbms_utility.get_time; + for i in 1 .. 50000 loop + d := use_g2; + end loop; + dbms_output.put_line((dbms_utility.get_time-s)/100' seconds for usage in SQL'); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_17.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_17.txt new file mode 100755 index 0000000..ef53eb8 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_17.txt @@ -0,0 +1,23 @@ +create or replace + package body new_globals is + + type num_tab is table of number + index by varchar2(30); + + n num_tab; + + function g(gname in varchar2) return number is + begin + return n(gname); + end; + + begin + n('g_1') := 1; + n('g_2') := 1; + n('g_3') := 1; + n(‘g_new_global’) := 1; + end; +/ +select object_name, status + from user_Objects + where object_name in ('USE_G1','USE_G2'); diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_18.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_18.txt new file mode 100755 index 0000000..e271db0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_18.txt @@ -0,0 +1,41 @@ +create or replace + procedure A(p number) is + begin + if p < 5 then + B(p+1); + end if; + end; +/ +create or replace + procedure B(p number) is + begin + if p < 5 then + A(p+1); + end if; + end; +/ + +create package RECURSION is + procedure A(p number); + procedure B(p number); + end; +/ +create or replace + package body RECURSION is + + procedure A(p number) is + begin + if p < 5 then + B(p+1); + end if; + end; + + procedure B(p number) is + begin + if p < 5 then + A(p+1); + end if; + end; + + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_20.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_20.txt new file mode 100755 index 0000000..1c9fb39 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_20.txt @@ -0,0 +1,8 @@ +select bytes chunk_size, count(*) no_of_chunks from + ( + select power(10,trunc(ln(ksmchsiz)/ln(10)))||' to '|| + (power(10,trunc(ln(ksmchsiz)/ln(10))+1)-1) chunk_size + from x$ksmsp + where ksmchcls != 'perm' ) + group by bytes +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_21.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_21.txt new file mode 100755 index 0000000..a312551 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_21.txt @@ -0,0 +1,26 @@ +declare + x varchar2(32767); + begin + for i in 1 .. 300 loop + x := x || ' procedure X'||i||';'; + end loop; + execute immediate + 'create or replace package MEMTEST is '||x||' end;'; + x := replace(x,';',' is y number; begin y := 1; end;'); + execute immediate + 'create or replace package body MEMTEST is '||x||' end;'; + end; +/ +alter system flush shared_pool; +exec memtest.x1; +select * from v$sgastat + where name like 'PL/SQL MPCODE'; +exec memtest.x2; +select * from v$sgastat + where name like 'PL/SQL MPCODE'; +exec memtest.x10; +select * from v$sgastat + where name like 'PL/SQL MPCODE'; +exec memtest.x100; +select * from v$sgastat +where name like 'PL/SQL MPCODE'; diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_22.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_22.txt new file mode 100755 index 0000000..3d0770b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_22.txt @@ -0,0 +1,41 @@ +create table x ( x number, y varchar2(30)); +insert into x + select rownum, 'xxxxx'||rownum + from SRC + where rownum < 10000; +create or replace + package FBI is + function ix(p varchar2) return varchar2 deterministic; + end; +/ +create or replace + package body FBI is + function ix(p varchar2) return varchar2 + deterministic is + begin + return p; + end; + end; +/ +create index x1 on x ( FBI.ix(y)); +analyze table x estimate statistics +set autotrace on +select * + from x + where FBI.ix(y) = 'xxxxx123'; +create or replace + package body p1 is + function ix(p varchar2) return varchar2 + deterministic is + begin + return p||’abc’; + end; + end; +/ +select * + from x + where p1.ix(y) = 'xxxxx123'; +select /*+ FULL(x) */ * + from x + where p1.ix(y) = 'xxxxx123'; + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_23.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_23.txt new file mode 100755 index 0000000..d37a9a7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_23.txt @@ -0,0 +1,5 @@ +select object_name + from dba_objects + where owner = 'SYS' + and object_type = 'PACKAGE'; + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_24.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_24.txt new file mode 100755 index 0000000..56a83ac --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_24.txt @@ -0,0 +1,68 @@ +create or replace + package stack is + type module_list is + table of varchar2(80) + index by binary_integer; + procedure push(module_name varchar2); + procedure pop; + procedure show_stack; +end; +/ + +create or replace + package body stack is + + m module_list; + + procedure push(module_name varchar2) is + begin + m(m.count+1) := module_name; + end; + + procedure pop is + begin + m.delete(m.count); + end; + + procedure show_stack is + begin + for i in 1 .. m.count loop + dbms_output.put_line(rpad('-',i,'-')||m(i)); + end loop; + end; + + end; +/ + +create or replace + procedure p1 is + begin + stack.push('P1'); + stack.show_stack; + stack.pop; + end; +/ +create or replace + procedure p2 is + begin + stack.push('P2'); + p1; + stack.pop; + end; +/ +create or replace + procedure p3 is + begin + stack.push('P3'); + p2; + stack.pop; + end; +/ +create or replace + procedure p1 is + begin + dbms_output.put_line( + substr(dbms_utility.format_call_stack,1,255)); + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_25.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_25.txt new file mode 100755 index 0000000..baae27c --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_25.txt @@ -0,0 +1,15 @@ +select dbms_metadata.get_ddl('TABLE','EMP','SCOTT') + from dual; + + +begin +DBMS_METADATA.SET_TRANSFORM_PARAM( +DBMS_METADATA.SESSION_TRANSFORM, +'STORAGE', +false); +end; +/ + +select dbms_metadata.get_ddl('USER','SCOTT') + from dual; + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_26.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_26.txt new file mode 100755 index 0000000..0976c7f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_26.txt @@ -0,0 +1,16 @@ +update emp + set sal = sal * 1.1 + where hiredate < to_date('08/SEP/1981','DD/MON/YYYY'); + +select row_wait_obj#, row_wait_file#, + row_wait_block#, row_wait_row# + from v$session + where row_wait_obj# in ( + select data_object_id + from user_objects + where object_name = 'EMP'); + +select * + from emp + where rowid = dbms_rowid.rowid_create(1,49627,7,138,0); + diff --git a/2174_MasteringPLSQL_CODE/Ch02/ch2_27.txt b/2174_MasteringPLSQL_CODE/Ch02/ch2_27.txt new file mode 100755 index 0000000..4c62728 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch02/ch2_27.txt @@ -0,0 +1,18 @@ +create table LIST_OF_FILES ( + fname varchar2(30), + fdir varchar2(30)) ; + +insert into LIST_OF_FILES + values ('demo.dat','/tmp'); + +create or replace + trigger DEL_FILE + before delete on LIST_OF_FILES + for each row + declare + j number; + begin + dbms_job.submit(j,'utl_file.fremove('''|| + :old.fdir||''','''||:old.fname||''');'); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_01.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_01.txt new file mode 100755 index 0000000..99bfcc2 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_01.txt @@ -0,0 +1,28 @@ +create table one_row_tab ( x primary key ) + organization index as select 1 from dual; +create or replace + procedure implicit is + dummy number; + begin + for i in 1 .. 50000 loop + select 1 + into dummy + from one_row_tab; + end loop; +end; +/ +create or replace + procedure explicit is + cursor explicit_cur is + select 1 + from one_row_tab; + dummy number; + begin + for i in 1 .. 50000 loop + open explicit_cur; + fetch explicit_cur + into dummy; + close explicit_cur; + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_02.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_02.txt new file mode 100755 index 0000000..f5e63c1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_02.txt @@ -0,0 +1,15 @@ +create or replace + procedure explicit2 is + cursor explicit_cur is + select 1 + from one_row_tab; + dummy number; + begin + open explicit_cur; — placed before loop + for i in 1 .. 50000 loop + fetch explicit_cur + into dummy; + end loop; + close explicit_cur; — placed after loop + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_03.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_03.txt new file mode 100755 index 0000000..59e2911 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_03.txt @@ -0,0 +1,18 @@ +create or replace + procedure explicit2 is + cursor explicit_cur is + select 1 + from one_row_tab; + dummy number; + begin + open explicit_cur; + for i in 1 .. 50000 loop + fetch explicit_cur + into dummy; + if explicit_cur%found then + dbms_output.put_line(‘I worked’); + end if; + end loop; + close explicit_cur; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_04.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_04.txt new file mode 100755 index 0000000..0d7e82a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_04.txt @@ -0,0 +1,34 @@ +create table EXPLICIT_IS_BEST + ( x number, y char(100)); +insert into EXPLICIT_IS_BEST + select rownum, ‘padding’ + from all_objects + where rownum < 10001; +create or replace + procedure implicit is + dummy number; + begin + for i in 1 .. 50000 loop + select 1 + into dummy + from explicit_is_best + where x = 1; + end loop; +end; +/ +create or replace + procedure explicit is + cursor explicit_cur is + select 1 + from explicit_is_best + where x = 1; + dummy number; + begin + for i in 1 .. 50000 loop + open explicit_cur; + fetch explicit_cur + into dummy; + close explicit_cur; + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_05.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_05.txt new file mode 100755 index 0000000..e7de135 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_05.txt @@ -0,0 +1,16 @@ +delete from explicit_is_best + where x= 1; +insert into explicit_is_best + values (1,’padding’); +create or replace + procedure implicit is + dummy number; + begin + for i in 1 .. 1000 loop + select 1 + into dummy + from explicit_is_best + where x = 2 and rownum = 1; + end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_06.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_06.txt new file mode 100755 index 0000000..659e2f8 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_06.txt @@ -0,0 +1,6 @@ +begin + for i in ( select ename from emp ) loop + dbms_output.put_line(i.ename); + end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_07.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_07.txt new file mode 100755 index 0000000..d508bf3 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_07.txt @@ -0,0 +1,19 @@ +declare + cursor c is select ename from emp ; + begin + for i in c loop + null; + end loop; + dbms_output.put_line(c%rowcount); + end; +/ + +declare + cnt pls_integer := 0; + begin + for i in (select ename from emp) loop + cnt := cnt + 1; + end loop; + dbms_output.put_line(cnt); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_08.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_08.txt new file mode 100755 index 0000000..ea88fcf --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_08.txt @@ -0,0 +1,19 @@ +create or replace + function IS_EMP_THERE return varchar2 is + cursor C is + select 1 from emp + where hiredate > trunc(sysdate,’MM); + r number; + v varchar2(3); + begin + open C; + fetch C into r; + if C%FOUND then + v := ‘YES’; + else + v := ‘NO’; + end if; + close C; + return v; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_09.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_09.txt new file mode 100755 index 0000000..288524e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_09.txt @@ -0,0 +1,17 @@ +create or replace + procedure PROCESS_EMP is + cursor C is + select empno, sal, comm + from emp; + v_bonus number := 10000; + begin + for i in c loop + v_bonus := v_bonus + i.comm / i.sal; + end loop; + exception + when zero_divide then + if C%ISOPEN then + close C; + end if; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_10.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_10.txt new file mode 100755 index 0000000..9cc4efa --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_10.txt @@ -0,0 +1,30 @@ +create or replace + procedure explicit is + cursor explicit_cur is + select x + from explicit_is_best + order by y desc; + dummy number; + begin + for i in 1 .. 500 loop + open explicit_cur; + fetch explicit_cur + into dummy; + close explicit_cur; + end loop; + end; +/ + +create or replace + procedure implicit is + dummy number; + begin + for i in 1 .. 500 loop + select x into dummy + from ( select x + from explicit_is_best + order by y desc ) + where rownum = 1; + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_11.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_11.txt new file mode 100755 index 0000000..4d09cb0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_11.txt @@ -0,0 +1,23 @@ +create or replace + function emp_list return sys_refcursor is + rc sys_refcursor; + begin + open rc for select * from emp; + return rc; + end; +/ + +create or replace + procedure list_emps is + e sys_refcursor; + r emp%rowtype; + begin + e := emp_list; + loop + fetch e into r; + exit when e%notfound; + dbms_output.put_line(r.empno||’,’||r.hiredate); + end loop; + close e; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_12.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_12.txt new file mode 100755 index 0000000..01779ee --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_12.txt @@ -0,0 +1,13 @@ +variable x refcursor +declare + r emp%rowtype; + begin + :x := emp_list; + loop + fetch :x into r; + exit when :x%notfound; + dbms_output.put_line(r.empno||’,’||r.hiredate); + end loop; + close :x; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_13.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_13.txt new file mode 100755 index 0000000..4670bba --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_13.txt @@ -0,0 +1,9 @@ +declare + v_bonus number := 10000; + v_max_sal number; + begin + select max(sal)+v_bonus + into v_max_sal + from emp; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_14.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_14.txt new file mode 100755 index 0000000..8ea365e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_14.txt @@ -0,0 +1,5 @@ +select deptno, dname, +cursor(select empno, ename +from emp +where deptno = d.deptno) +from dept d; diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_15.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_15.txt new file mode 100755 index 0000000..97ad139 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_15.txt @@ -0,0 +1,20 @@ +create or replace + function dept_emp_cust return sys_refcursor is + rc sys_refcursor; + begin + open rc for + select deptno, dname, + cursor(select empno, ename + from emp + where deptno = d.deptno) emps, + cursor(select custid, custname + from customers + where purchasing_dept = d.deptno) custs + from dept d; + return rc; + end; +/ + +variable x refcursor +exec :x := dept_emp_cust; +print x diff --git a/2174_MasteringPLSQL_CODE/Ch03/ch3_16.txt b/2174_MasteringPLSQL_CODE/Ch03/ch3_16.txt new file mode 100755 index 0000000..e536aba --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch03/ch3_16.txt @@ -0,0 +1,13 @@ +set arraysize 50 +set autotrace on statistics +select empno, deptno + from emp +/ + +create table IX ( x number primary key ) + organization index; +analyze table IX estimate statistics; +select empno, cursor(select x from ix) + from emp +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_01.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_01.txt new file mode 100755 index 0000000..74b4e88 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_01.txt @@ -0,0 +1,27 @@ +@$ORACLE_HOME/sqlplus/demo/demobld.sql + +create or replace + procedure WITHOUT_TYPE is + v_salary number(7,2); + begin + select max(sal) + into v_salary + from emp; +end; +/ +create or replace + procedure WITH_TYPE is + v_salary emp.sal%type; + begin + select max(sal) + into v_salary + from emp; + end; +/ + +alter table EMP modify sal number(10,2); +update EMP set sal = 1,000,000 + where EMPNO = 7369; + +exec WITHOUT_TYPE; +exec WITH_TYPE; \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_02.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_02.txt new file mode 100755 index 0000000..c7d1113 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_02.txt @@ -0,0 +1,34 @@ +create or replace +procedure MY_PROC(p_input varchar2) is +v1 varchar2(30); +v2 varchar2(30); +v3 varchar2(30); +v4 varchar2(30); +begin + v1 := p_input; +end; +/ +create or replace +package MY_PKG is + glob_var varchar2(40) := rpad('*',40); +end; +/ + +exec MY_PROC(my_pkg.glob_var); + + +create or replace +procedure MY_PROC(p_input varchar2) is +v1 my_pkg.glob_var%type; +v2 my_pkg.glob_var%type; +v3 my_pkg.glob_var%type; +v4 my_pkg.glob_var%type; +begin + null; +end; +/ +create or replace + package MY_PKG is + glob_var varchar2(60) := rpad(‘x’,60); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_03.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_03.txt new file mode 100755 index 0000000..7331981 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_03.txt @@ -0,0 +1,20 @@ +create or replace + package APPLICATION_TYPES is + subtype short_varchar2 is varchar2(40); + end; +/ +create or replace + procedure MY_PROC(p_input application_types.short_varchar2) is + v1 application_types.short_varchar2; + v2 application_types.short_varchar2; + v3 application_types.short_varchar2; + v4 application_types.short_varchar2; + begin +null; +end; +/ +create or replace + package MY_PKG is + glob_var application_types.short_varchar2 := rpad(‘x’,40); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_04.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_04.txt new file mode 100755 index 0000000..9f06ac4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_04.txt @@ -0,0 +1,26 @@ +reate or replace + procedure data_type_test is + x date; + y varchar2(12) := ‘01-MAR-03’; + t number := dbms_utility.get_time; + begin + for i in 1 .. 1000000 loop + x := y; — implicit char to date + end loop; + dbms_output.put_line((dbms_utility.get_time-t)||’cs’); + end; +/ + + +create or replace + procedure data_type_test is + x date; + y x%type := to_date(‘01-MAR-03’); + t number := dbms_utility.get_time; + begin + for i in 1 .. 1000000 loop + x := y; + end loop; + dbms_output.put_line((dbms_utility.get_time-t)||’cs’); + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_05.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_05.txt new file mode 100755 index 0000000..1160d9a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_05.txt @@ -0,0 +1,24 @@ +create or replace + procedure num_test_as_integer is + x integer; + t number := dbms_utility.get_time; + begin + for i in 1 .. 10000000 loop + x := i; + end loop; + dbms_output.put_line((dbms_utility.get_time-t)||’cs’); + end; +/ + +create or replace + procedure num_test_as_pls is + x pls_integer; + t number := dbms_utility.get_time; + begin + for i in 1 .. 10000000 loop + x := i; + end loop; +dbms_output.put_line((dbms_utility.get_time-t)||’cs’); + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_07.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_07.txt new file mode 100755 index 0000000..0bd335a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_07.txt @@ -0,0 +1,14 @@ +create table T ( + c1 number, + c2 number ); +insert into T values (1,2); +create or replace + procedure WITH_ROWTYPE is + r T%ROWTYPE; + begin + select * + into r + from T + where rownum = 1; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_08.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_08.txt new file mode 100755 index 0000000..e50c493 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_08.txt @@ -0,0 +1,20 @@ +drop table T; +create table T ( + c1 number, + c2 number ); +insert into T values (1,2); +create table T1 as select * from T; +create or replace + procedure WITH_ROWTYPE is + r T%ROWTYPE; + begin + select * + into r + from T + where rownum = 1; + + insert into T1 + values (r.c1, r.c2); + end; +/ +exec WITH_ROWTYPE \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_09.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_09.txt new file mode 100755 index 0000000..4928462 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_09.txt @@ -0,0 +1,13 @@ +create or replace + procedure WITH_ROWTYPE is + r T%ROWTYPE; + begin + select * + into r + from T + where rownum = 1; + + insert into T1 + values r; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_10.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_10.txt new file mode 100755 index 0000000..422cd6e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_10.txt @@ -0,0 +1,14 @@ +create or replace + procedure WITH_ROWTYPE is + r T%ROWTYPE; + begin + select * + into r + from T + where rownum = 1; + + update T1 + set row = r + where rownum = 1; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_11.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_11.txt new file mode 100755 index 0000000..cd50f27 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_11.txt @@ -0,0 +1,22 @@ +create or replace type STOLEN_ITEMS as object ( + firstname varchar2(30), + surname varchar2(30), + date_of_birth date, + incident_date date, + item_count number(4), + items_retrieved varchar2(1) +) +/ +create table CRIMES ( + person_id number(10), + crime_details stolen_items ); + +set long 50000 +select text + from dba_views + where view_name = ‘DBA_TAB_COLUMNS’ +/ +select column_name, hidden_column, data_type + from DBA_TAB_COLS + where table_name = ‘CRIMES’ +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_12.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_12.txt new file mode 100755 index 0000000..357dc05 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_12.txt @@ -0,0 +1,58 @@ +create or replace view stats + as select ‘S:’ || a.name name, b.value + from v$statname a, v$mystat b + where a.statistic# = b.statistic# + union all + select ‘L:’ || name, gets + from v$latch + union all + select ‘E:Elapsed’, hsecs from v$timer; + +create or replace type stats_line as object + ( snapid number(10), + name varchar2(66), + value int ); +/ + +create or replace type stats_array as + table of stats_line; +/ + + +declare +v_snap_id number := 0; +s stats_array := stats_array(); +begin +v_snapid := v_snapid + 1; +for i in ( select * from stats) loop +s.extend; +s(s.count) := stats_line(v_snapid, i.name,i.value ); +end loop; +end; + +create or replace + type run_stats_line as object ( + tag varchar2(66), + run1 int, + run2 int, + diff2 int, + pct2 int, + run3 int, + diff3 int, + pct3 int, + run4 int, + diff4 int, + pct4 int, + run5 int, + diff5 int, + pct5 int, + run6 int, + diff6 int, + pct6 int); +/ + + +create or replace type run_stats_output + as table of run_stats_line; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_14.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_14.txt new file mode 100755 index 0000000..7d837d6 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_14.txt @@ -0,0 +1,6 @@ +set autotrace traceonly statistics +set arraysize 1 +set timing on +select * from SRC; +set arraysize 500 +select * from SRC; \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_15.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_15.txt new file mode 100755 index 0000000..ffa990b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_15.txt @@ -0,0 +1,23 @@ +create or replace + procedure BIG_PARM(p in out nocopy Rec_list) is + begin + null; + end; +/ +declare + x rec_list := rec_list(); + t1 number; + t2 number; + begin + for i in 1 .. 50000 loop + x.extend; + x(i) := rec(i,i,rpad(i,30)); + end loop; + t2 := dbms_utility.get_time; + for i in 1 .. 500000 loop + big_parm(x); + end loop; + t1 := dbms_utility.get_time; + dbms_output.put_line(‘Collection:’||(t1-t2)); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_16.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_16.txt new file mode 100755 index 0000000..96cc2f1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_16.txt @@ -0,0 +1,29 @@ +create or replace + procedure ARRAY_PROCESS is + s integer := dbms_sql.open_cursor; + n1 dbms_sql.number_table; + d number; + c number; + BEGIN + dbms_sql.parse(s,’select * from SRC’, + DBMS_SQL.native); + dbms_sql.define_array(s,1,n1,500,1); + d := dbms_sql.execute(s); + loop + c := DBMS_SQL.FETCH_ROWS(s); + DBMS_SQL.COLUMN_VALUE(s, 1, n1); + exit when c < 500; + end loop; + + DBMS_SQL.CLOSE_CURSOR(s); + END; +/ + +create or replace + procedure SINGLE_ROW_PROCESS is + begin + for i in ( select * from SRC ) loop + null; + end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_17.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_17.txt new file mode 100755 index 0000000..a15e156 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_17.txt @@ -0,0 +1,51 @@ +declare + x number; + begin + select object_id + into x + from all_objects + where rownum <= 1; + end; +/ + +declare + type numlist is table of number; + x numlist; + begin + select object_id + bulk collect into x + from all_objects + where rownum <= 500; +end; +/ + +create or replace +directory REPORT_DIR as ‘C:\TEMP’; + + +create or replace + procedure report_sal_adjustment4 is + f utl_file.file_type; + begin + f := utl_file.fopen(‘REPORT_DIR’,’report.dat’,’W’); + for i in ( + select e.empno, e.hiredate, e.sal, dept.dname, + case when sal > avg_sal then ‘Y’ + else ‘N’ + end status + from ( + select empno, hiredate, sal, deptno, + avg(sal) over ( partition by deptno ) as avg_sal, + min(sal) over ( partition by deptno ) as min_sal + from emp ) e, dept + where e.deptno = dept.deptno + and abs(e.sal - e.avg_sal)/e.avg_sal > 0.10 ) loop + utl_file.put_line(f,i.empno|| + i.hiredate|| + i.sal|| + i.dname|| + i.status); + end loop; + utl_file.fclose(f); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/Ch04_runstats.txt b/2174_MasteringPLSQL_CODE/Ch04/Ch04_runstats.txt new file mode 100755 index 0000000..4f10613 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/Ch04_runstats.txt @@ -0,0 +1,83 @@ +create or replace package rs as + procedure snap(reset boolean default false); + function display return run_stats_output ; + function the_stats return stats_array; + s stats_array := stats_array(); + v_snapid integer := 0; + end; + / + +create or replace package body rs as + + procedure snap(reset boolean default false) is + begin + if reset then + s := stats_array(); + v_snapid := 0; + end if; + v_snapid := v_snapid + 1; +for i in ( select * from stats) loop +s.extend; +s(s.count) := stats_line(v_snapid, i.name,i.value ); +end loop; +end; + +function display return run_stats_output is +output run_stats_line := +run_stats_line(null, +null,null,null,null, +null,null,null,null, +null,null,null,null, +null,null,null,null); +ret run_stats_output := run_stats_output(); +base_val number; +begin +for i in ( select hi.snapid, lo.name, lo.value, hi.value-lo.value amt +from ( select * from table(the_stats) ) lo, +( select * from table(the_stats) ) hi +where lo.name = hi.name +and lo.snapid = hi.snapid -1 +order by 2,1) loop +e i.snapid +when 2 then +if output.tag is not null then +ret.extend; +ret(ret.count) := output; +end if; +base_val := i.amt; +output.tag := i.name; +output.run1 := i.amt; +when 3 then +output.run2 := i.amt; +output.diff2 := i.amt - base_val; +output.pct2 := i.amt / greatest(base_val,1) * 100; +when 4 then +output.run3 := i.amt; +output.diff3 := i.amt - base_val; +output.pct3 := i.amt / greatest(base_val,1) * 100; +when 5 then +output.run4 := i.amt; +output.diff4 := i.amt - base_val; +output.pct4 := i.amt / greatest(base_val,1) * 100; +when 6 then +output.run5 := i.amt; +output.diff5 := i.amt - base_val; +output.pct5 := i.amt / greatest(base_val,1) * 100; +when 7 then +output.run6 := i.amt; +output.diff6 := i.amt - base_val; +output.pct6 := i.amt / greatest(base_val,1) * 100; +end case; +end loop; +ret.extend; +ret(ret.count) := output; +return ret; +end; + +function the_stats return stats_array is +begin +return s; +end; + +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_06.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_06.txt new file mode 100755 index 0000000..78d99b0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_06.txt @@ -0,0 +1,7 @@ +begin + for i in power(2,31) .. power(2,31)+10 loop + null; + end loop; + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_18.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_18.txt new file mode 100755 index 0000000..fe1614d --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_18.txt @@ -0,0 +1,34 @@ +create or replace + procedure report_sal_adjustment4_bulk is + f utl_file.file_type; + cursor c_template is + select e.empno, e.hiredate, e.sal, dept.dname, + case when sal > avg_sal then ‘Y’ + else ‘N’ + end status + from ( + select empno, hiredate, sal, deptno, + avg(sal) over ( partition by deptno ) as avg_sal, + min(sal) over ( partition by deptno ) as min_sal + from emp ) e, dept + where e.deptno = dept.deptno + and abs(e.sal - e.avg_sal)/e.avg_sal > 0.10; + type resultset is + table of c_template%rowtype; + r resultset; + begin + f := utl_file.fopen(‘REPORT_DIR’,’report.dat’,’W’); + open c_template; + fetch c_template + bulk collect into r; + close c_template; + for i in 1 .. r.count loop + utl_file.put_line(f,r(i).empno|| + r(i).hiredate|| + r(i).sal|| + r(i).dname|| + r(i).status); + end loop; + utl_file.fclose(f); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_19.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_19.txt new file mode 100755 index 0000000..414cee2 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_19.txt @@ -0,0 +1,51 @@ +create table BULK_BIND_TARGET ( + x number, + y date, + z varchar2(50) ); + +declare + type numlist is table of number; + type datelist is varray(50000) of date; + type charlist is table of varchar2(50) +index by binary_integer; + + n numlist := numlist(); + d datelist := datelist(); + c charlist; + begin + for i in 1 .. 50000 loop + n.extend; + n(i) := i; + d.extend; + d(i) := sysdate+i; + c(i) := rpad(i,50); + end loop; + + for i in 1 .. 50000 loop + insert into bulk_bind_target values (n(i), d(i), c(i)); + end loop; + end; +/ + +declare + type numlist is table of number; + type datelist is varray(50000) of date; + type charlist is table of varchar2(50) + index by binary_integer; + + n numlist := numlist(); + d datelist := datelist(); + c charlist; + begin + for i in 1 .. 50000 loop + n.extend; + n(i) := i; + d.extend; + d(i) := sysdate+i; + c(i) := rpad(i,50); + end loop; + + forall i in 1 .. 50000 + insert into bulk_bind_target values (n(i), d(i), c(i)); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_20.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_20.txt new file mode 100755 index 0000000..8a0429f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_20.txt @@ -0,0 +1,44 @@ +create table MANDATORY_COL ( + x number not null ); + +declare + type numlist is table of number + index by binary_integer; + n numlist; + begin + for i in 1 .. 50 loop + n(i) := i; + end loop; + + n(37) := null; — will cause a problem + + forall i in 1 .. 50 + insert into MANDATORY_COL values (n(i)); + end; +/ + +set serverout on +declare + type numlist is table of number + index by binary_integer; + n numlist; + begin + for i in 1 .. 50 loop + n(i) := i; + end loop; + + n(37) := null; — will cause a problem + + forall i in 1 .. 50 save exceptions + insert into MANDATORY_COL values (n(i)); + + exception when others then + dbms_output.put_line(‘Errors:’||sql%bulk_exceptions.count); + for i in 1 .. sql%bulk_exceptions.count loop + dbms_output.put_line(‘index:’||sql%bulk_exceptions(i).error_index); + dbms_output.put_line(‘code:’||sql%bulk_exceptions(i).error_code); + dbms_output.put_line(‘message:’); + dbms_output.put_line(sqlerrm(sql%bulk_exceptions(i).error_code)); + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_21.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_21.txt new file mode 100755 index 0000000..9173cc3 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_21.txt @@ -0,0 +1,22 @@ +create or replace + procedure BULK_TEST is + mem_used number; + t number; + type recs is + table of ALL_OBJECTS%rowtype; + r recs; + cursor c1 is select * from ALL_OBJECTS; + begin + t := dbms_utility.get_time; + open c1; + fetch c1 + bulk collect into r; + close c1; + select value + into mem_used + from v$mystats + where name = ‘session pga memory max’; + dbms_output.put_line(‘- Time: ‘||(dbms_utility.get_time-t)); + dbms_output.put_line(‘- Max Mem: ‘||mem_used); + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_22.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_22.txt new file mode 100755 index 0000000..c82f8cd --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_22.txt @@ -0,0 +1,29 @@ +create or replace + procedure LIMIT_TEST is + mem_used number; + t number; + type recs is + table of SRC%rowtype; + r recs; + cursor c1 is select * from SRC + begin + for i in 0 .. 7 loop + t := dbms_utility.get_time; + open c1; + loop + fetch c1 + bulk collect into r + limit power(2,i*2); + exit when c1%notfound; + end loop; + close c1; + select value + into mem_used + from v$mystats + where name = ‘session pga memory max’; + dbms_output.put_line(‘Rows:’||power(2,i*2)); + dbms_output.put_line(‘- Time: ‘||(dbms_utility.get_time-t)); + dbms_output.put_line(‘- Max Mem: ‘||mem_used); + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_23.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_23.txt new file mode 100755 index 0000000..3cbcc5e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_23.txt @@ -0,0 +1,27 @@ +create table TEN_BYTE_COLUMN ( + col varchar2(10)); + +create or replace + procedure ADD_ROW(p_col TEN_BYTE_COLUMN.COL%TYPE) is + begin + insert into TEN_BYTE_COLUMN + values (p_col); + end; +/ + +create or replace + procedure ADD_NUM_ROW(p_col TEN_SIG_DIGITS.COL%TYPE) is + begin + insert into TEN_SIG_DIGITS + values (p_col); + end; +/ + + +create or replace + procedure LOCAL_TYPE_VAR is + x ten_byte_column.col%type; + begin + x := ‘01234567890123456789’; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_24.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_24.txt new file mode 100755 index 0000000..67350b5 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_24.txt @@ -0,0 +1,25 @@ +create or replace + package PKG is + procedure ADD_ROW(p_col TEN_BYTE_COLUMN.COL%TYPE); + procedure ADD_NUM_ROW(p_col TEN_SIG_DIGITS.COL%TYPE); + end; +/ + +create or replace + package body PKG is + + procedure ADD_ROW(p_col TEN_BYTE_COLUMN.COL%TYPE) is + begin + insert into TEN_BYTE_COLUMN + values (p_col); + end; + + procedure ADD_NUM_ROW(p_col TEN_SIG_DIGITS.COL%TYPE) is + begin + insert into TEN_SIG_DIGITS + values (p_col); + end; + + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_25.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_25.txt new file mode 100755 index 0000000..f54eeb4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_25.txt @@ -0,0 +1,29 @@ +create or replace + package PKG is + procedure ADD_ROW(p_col varchar2); + procedure ADD_NUM_ROW(p_col number); + end; + / +create or replace + package body PKG is + procedure ADD_ROW(p_col varchar2) is + begin + insert into TEN_BYTE_COLUMN + values (p_col); + end; + + procedure ADD_NUM_ROW(p_col number) is + begin + insert into TEN_SIG_DIGITS + values (p_col); + end; + + end; +/ + +select name, type + from user_dependencies + where referenced_name in ( + ‘TEN_BYTE_COLUMN’, + ‘TEN_SIG_DIGITS’) + and name like ‘PKG%’; diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_26.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_26.txt new file mode 100755 index 0000000..889c29d --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_26.txt @@ -0,0 +1,25 @@ +create or replace + type rec is object + ( a number, + b number, + c varchar2(30)); +/ + +create or replace + type rec_list is + table of rec; +/ +create or replace + procedure SIMPLE_PARM(p number) is + x number; + begin + null; + end; +/ +create or replace + procedure BIG_PARM(p Rec_list) is + x number; + begin + null; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_27.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_27.txt new file mode 100755 index 0000000..5d36766 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_27.txt @@ -0,0 +1,22 @@ +declare + x rec_list := rec_list(); + t1 number; + t2 number; + begin + x.extend(50000); + for i in 1 .. 50000 loop + x(i) := rec(i,i,rpad(i,30)); + end loop; + t1 := dbms_utility.get_time; + for i in 1 .. 500000 loop + simple_parm(i); + end loop; + t2 := dbms_utility.get_time; + dbms_output.put_line(‘Simple: ‘||(t2-t1)); + for i in 1 .. 500000 loop + big_parm(x); + end loop; + t1 := dbms_utility.get_time; + dbms_output.put_line(‘Collection:’||(t1-t2)); + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_28.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_28.txt new file mode 100755 index 0000000..c0a3c5a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_28.txt @@ -0,0 +1,38 @@ +create or replace + procedure SIMPLE_PARM(p number) is + x number; + begin + x := p; + end; +/ +create or replace + procedure BIG_PARM(p Rec_list) is + x number; + begin + x := p(1).a; + end; +/ + +declare + x rec_list := rec_list(); + t1 number; + t2 number; + begin + for i in 1 .. 50000 loop + x.extend; + x(i) := rec(i,i,rpad(i,30)); + end loop; + t1 := dbms_utility.get_time; + for i in 1 .. 500000 loop + simple_parm(i); + end loop; + t2 := dbms_utility.get_time; + dbms_output.put_line(‘Simple: ‘||(t2-t1)); + for i in 1 .. 500000 loop + big_parm(x); + end loop; + t1 := dbms_utility.get_time; + dbms_output.put_line(‘Collection:’||(t1-t2)); +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_29.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_29.txt new file mode 100755 index 0000000..5189a1f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_29.txt @@ -0,0 +1,37 @@ +create or replace + procedure SIMPLE_PARM(p in out number) is + begin + null; + end; +/ +create or replace + procedure BIG_PARM(p in out Rec_list) is + begin + null; + end; +/ + +declare + x rec_list := rec_list(); + s number := 1; + t1 number; + t2 number; + begin + for i in 1 .. 50000 loop + x.extend; + x(i) := rec(i,i,rpad(i,30)); + end loop; + t1 := dbms_utility.get_time; + for i in 1 .. 50 loop + simple_parm(s); + end loop; + t2 := dbms_utility.get_time; + dbms_output.put_line(‘Simple: ‘||(t2-t1)); + for i in 1 .. 50 loop + big_parm(x); + end loop; + t1 := dbms_utility.get_time; + dbms_output.put_line(‘Collection:’||(t1-t2)); + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_30.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_30.txt new file mode 100755 index 0000000..b8afc41 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_30.txt @@ -0,0 +1,45 @@ +create or replace + procedure BIG_PARM(p in out Rec_list) is + l number; + begin + p(2).c := ‘z’; — change from ‘q’ to ‘z’ + l := 1/0; — will raise error (ie division by zero) + end; +/ +declare + x rec_list; + begin + x := rec_list( + rec(1,1,’p’), + rec(2,2,’q’), + rec(3,3,’r’)); + big_parm(x); + exception when others then + for i in 1 .. 3 loop + dbms_output.put_line(x(i).c); + end loop; + end; +/ + +create or replace + procedure BIG_PARM(p in out nocopy Rec_list) is + l number; + begin + p(2).c := ‘z’; + l := 1/0; + end; +/ +declare + x rec_list; + begin + x := rec_list( + rec(1,1,’p’), + rec(2,2,’q’), + rec(3,3,’r’)); + big_parm(x); + exception when others then + for i in 1 .. 3 loop + dbms_output.put_line(x(i).c); + end loop; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_31.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_31.txt new file mode 100755 index 0000000..348a4c9 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_31.txt @@ -0,0 +1,23 @@ +declare + x rec_list := rec_list(); + orig_x rec_list; + t1 number; + t2 number; +begin + for i in 1 .. 50000 loop + x.extend; + x(i) := rec(i,i,rpad(i,30)); + end loop; + t2 := dbms_utility.get_time; + for i in 1 .. 50 loop + orig_x := x; + begin + big_parm(x); + exception when others then + x := orig_x; + end; + end loop; + t1 := dbms_utility.get_time; + dbms_output.put_line(‘Collection:’||(t1-t2)); + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_32.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_32.txt new file mode 100755 index 0000000..cd7bd26 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_32.txt @@ -0,0 +1,42 @@ +@$ORACLE_HOME\sqlplus\demo\demobld +alter table dept add tot_sal number; +update dept + set tot_sal = ( select sum(sal) + from emp where deptno = dept.deptno ); +create table EMP_AUDIT ( + date_rec date, + empno number, + sal number(4)); +create table EMP_DELTAS + ( empno number, change_type varchar2(10)); +insert into emp_deltas + select empno, null from emp; +create or replace + procedure UPDATE_EMP(p_empno number, p_sal number) is + begin + update DEPT + set TOT_SAL = TOT_SAL + + ( select p_sal-sal + from EMP + where empno = p_empno ) + where deptno = ( select deptno + from EMP + where empno = p_empno); + + update EMP + set sal = p_sal + where empno = p_empno; + + update EMP_DELTAS + set change_type = ‘SAL’ + where empno = p_empno; + + insert into EMP_AUDIT + values (sysdate,p_empno,p_sal); + + exception + when others then + rollback; + raise; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_33.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_33.txt new file mode 100755 index 0000000..47f8901 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_33.txt @@ -0,0 +1,23 @@ +create table list_of_changes + ( tname varchar2(30), + cname varchar2(30), + changed date); +create or replace + procedure RUN_DDL(m varchar2) is + pragma autonomous_transaction; + begin + execute immediate m; + end; +/ +create or replace + procedure ADD_COLUMN(p_table varchar2, + p_column varchar2) is + v number; + begin + insert into LIST_OF_CHANGES + values (p_table, p_column, sysdate); + run_ddl( + ‘alter table ‘||p_table||’ add ‘||p_column); + v := 1/0; — raises an error, rolls back insert + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_34.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_34.txt new file mode 100755 index 0000000..c6d1cb6 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_34.txt @@ -0,0 +1,12 @@ +create or replace + procedure ADD_COLUMN(p_table varchar2, + p_column varchar2) is + v number; + j number; + begin + insert into LIST_OF_CHANGES + values (p_table, p_column, sysdate); + dbms_job.submit(j, + ‘run_ddl(‘’alter table ‘||p_table||’ add ‘||p_column||’’’);’); + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_35.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_35.txt new file mode 100755 index 0000000..e7a5a02 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_35.txt @@ -0,0 +1,23 @@ +drop table EMP_AUDIT; +create table EMP_AUDIT ( + empno number(10), + viewed date ); +create or replace + function AUDIT_ROW(p_empno number) return number is + begin + insert into EMP_AUDIT + values (p_empno, sysdate); + return 0; + end; +/ + +create or replace + function AUDIT_ROW(p_empno number) return number is + pragma autonomous_transaction; + begin + insert into EMP_AUDIT + values (p_empno, sysdate); + commit; + return 0; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_36.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_36.txt new file mode 100755 index 0000000..7315119 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_36.txt @@ -0,0 +1,10 @@ +begin + DBMS_FGA.ADD_POLICY + ( + object_schema => user, + object_name => 'EMP', + policy_name => 'AUDIT_EMP_RECORDS', + audit_column => 'salary' + ); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch04/ch4_37.txt b/2174_MasteringPLSQL_CODE/Ch04/ch4_37.txt new file mode 100755 index 0000000..8c197b7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch04/ch4_37.txt @@ -0,0 +1,43 @@ +create table ERRS + ( module varchar2(30), + errdate date, + errmsg varchar2(4000)); +create or replace + procedure err_logger(p_module varchar2, + p_msg varchar2) is + pragma autonomous_transaction; + begin + insert into errs + values (p_module,sysdate,substr(p_msg,1,4000)); + commit; + end; +/ +create or replace + procedure UPDATE_EMP(p_empno number, p_sal number) is + begin + update DEPT + set TOT_SAL = TOT_SAL + + ( select p_sal-sal + from EMP + where empno = p_empno ) + where deptno = ( select deptno + from EMP + where empno = p_empno); + + update EMP + set sal = p_sal + where empno = p_empno; + + update EMP_DELTAS + set change_type = ‘SAL’ + where empno = p_empno; + + insert into EMP_AUDIT + values (sysdate,p_empno,p_sal); + + exception + when others then + err_logger(‘UPDATE_EMP’,sqlerrm); + raise; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_01.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_01.txt new file mode 100755 index 0000000..9fa4119 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_01.txt @@ -0,0 +1,32 @@ +create table T (code number); +create table T_AUDIT ( + code number, + ins_date date ); +create or replace + trigger TRG + before insert on T + for each row + begin + insert into T_AUDIT + values (:new.code, sysdate); +end; +/ +alter session set sql_trace = true; +set feedback off +select * from v$mystats + where name like 'parse%'; + +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); + +select * from v$mystats + where name like 'parse%'; + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_02.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_02.txt new file mode 100755 index 0000000..1f07865 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_02.txt @@ -0,0 +1,29 @@ +create or replace + procedure T_AUDIT_PROC(p_code number) is + begin + insert into T_AUDIT + values (p_code, sysdate); + end; +/ +create or replace + trigger TRG + before insert on T + for each row + call t_audit_proc(:new.code) +/ +select * from v$mystats +where name like 'parse%'; +set feedback off +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +insert into T values (1); +select * from v$mystats +where name like 'parse%'; +alter session set sql_trace = false; diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_03.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_03.txt new file mode 100755 index 0000000..46d0921 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_03.txt @@ -0,0 +1,24 @@ +grant dba to confused identified by password; +conn CONFUSED/PASSWORD + +select count(*) from dba_users; +create or replace + procedure GET_ROW is + x number; + begin + execute immediate ' + select 1 + from dba_users + where rownum = 1' into x; +end; +/ +create or replace + procedure GET_ROW authid current_user is + x number; + begin + execute immediate ' + select 1 + from dba_users + where rownum = 1' into x; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_04.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_04.txt new file mode 100755 index 0000000..d68dd91 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_04.txt @@ -0,0 +1,78 @@ +begin + for i in 10 .. 20 loop + execute immediate + 'grant connect, resource to inv'||i|| + ' identified by xxx'; + execute immediate + 'create table inv'||i||'.lookup '|| + '( uno number primary key, '|| + ' data varchar2(20)) '|| + 'organization index'; + execute immediate + 'insert into inv'||i||'.lookup '|| + 'values ('||i||',''data'||i||''')'; + execute immediate + 'analyze table inv'||i||'.lookup estimate statistics'; + end loop; + end; +/ +select owner, table_name + from dba_tables + where owner like 'INV__'; + +grant connect, resource to definer identified by xxx; +create table definer.lookup + ( uno number primary key, + data varchar2(20)) + organization index; +insert into definer.lookup + select rownum+9, 'data'||rownum + from all_objects + where rownum <= 11; +create or replace + procedure definer.get(p_uno number) is + d varchar2(20); + begin + select data + into d + from lookup + where uno = p_uno; + end; +/ + +create or replace + procedure definer.invoker_proc authid current_user is + d varchar2(20); + begin + select data + into d + from lookup; +end; +/ + +begin + for i in 1 .. 100000 loop + definer.invoker_proc; — invokers right access to 1 row table + end loop; + end; +/ +begin + for i in 1 .. 100000 loop + definer.get(10); — definers rights to 1 row from 20 rows table + end loop; +end; +/ + + +select sql_text, executions + from v$sql + where sql_text like '%lookup%'; + + +select * from v$sql_shared_cursor + where KGLHDPAR = + ( select address from v$sql + where sql_text like 'SELECT data%' + and rownum = 1 ) +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_05.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_05.txt new file mode 100755 index 0000000..62f1ec7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_05.txt @@ -0,0 +1,57 @@ +create table EMP2 as + select empno, ename, hiredate,sal, deptno + from emp + where rownum = 0; +create or replace + package PKG is + type emp_list is + table of emp2%rowtype; + + function CONSUMER return sys_refcursor; + function MANIPULATOR(src_rows sys_refcursor) return emp_list; + procedure PRODUCER(changed_rows emp_list); + +end; +/ +create or replace + package body PKG is + + function CONSUMER return sys_refcursor is + src_rows sys_refcursor; + begin + open src_rows for + select empno, ename, hiredate,sal, deptno + from emp; + return src_rows; + end; + + function MANIPULATOR(src_rows sys_refcursor) return emp_list is + changed_rows emp_list; + begin + fetch src_rows + bulk collect into changed_rows; + close src_rows; + for i in 1 .. changed_rows.count loop + changed_rows(i).sal := changed_rows(i).sal+10; + changed_rows(i).hiredate := changed_rows(i).hiredate + 1; + end loop; + return changed_rows; + end; + + procedure PRODUCER(changed_rows emp_list) is + begin + forall i in 1 .. changed_rows.count + insert into emp2 values changed_rows(i); + commit; + end; + + end; +/ +set timing on +exec pkg.producer(pkg.manipulator(pkg.consumer)); +select count(*) from emp2; + +select * from v$mystats +where name like '%pga%' +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_06.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_06.txt new file mode 100755 index 0000000..c0915e0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_06.txt @@ -0,0 +1,57 @@ +create or replace + type emp2rec is object ( + empno number(10), + ename varchar2(20), + hiredate date, + sal number(10,2), + deptno number(6) ); +/ +create or replace + type emp2list as table of emp2rec; +/ +create or replace + package PKG2 is + function CONSUMER return sys_refcursor; + function MANIPULATOR(src_rows sys_refcursor) return emp2list pipelined; + procedure PRODUCER; + +end; +/ +create or replace + package body PKG2 is + + function CONSUMER return sys_refcursor is + src_rows sys_refcursor; + begin + open src_rows for + select empno, ename, hiredate,sal, deptno + from emp; + return src_rows; + end; + + function MANIPULATOR(src_rows sys_refcursor) + return emp2list pipelined is + r emp2rec; + e emp2%rowtype; + begin + loop + fetch src_rows into e; + exit when src_rows%notfound; + e.sal := e.sal+10; + e.hiredate := e.hiredate + 1; + pipe row (emp2rec(e.empno,e.ename,e.hiredate,e.sal,e.deptno )); + end loop; + close src_rows; + return; + end; + +procedure PRODUCER is + rc sys_refcursor := consumer; + begin + insert into emp2 + select * from table(cast(manipulator(rc) as emp2list )); + end; + +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_07.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_07.txt new file mode 100755 index 0000000..3a4f307 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_07.txt @@ -0,0 +1,47 @@ +declare + type varchar2_tab is table of number + index by varchar2(100); + vc varchar2_tab; + type num_tab is table of number + index by binary_integer; + n num_tab; + t number; + begin + t := dbms_utility.get_time; + for i in 1 .. 100000 loop + n(i) := i; + end loop; + dbms_output.put_line('Index by Number : '|| + (dbms_utility.get_time-t)); + t := dbms_utility.get_time; + for i in 1 .. 100000 loop + vc(i) := i; + end loop; + dbms_output.put_line('Index by Varchar2: '|| + (dbms_utility.get_time-t)); + end; +/ +declare + type varchar2_tab is table of number + index by varchar2(100); + vc varchar2_tab; + type num_tab is table of number + index by binary_integer; + n num_tab; + t number; + begin + t := dbms_utility.get_time; + for i in 1 .. 100000 loop + n(i*1000) := i; + end loop; + dbms_output.put_line('Index by Number : '|| + (dbms_utility.get_time-t)); + t := dbms_utility.get_time; + for i in 1 .. 100000 loop + vc(i*1000) := i; + end loop; + dbms_output.put_line('Index by Varchar2: '|| + (dbms_utility.get_time-t)); + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_08.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_08.txt new file mode 100755 index 0000000..819be61 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_08.txt @@ -0,0 +1,70 @@ +create or replace + package pkg is + procedure rec_of_array_test; + procedure array_of_rec_test; + end; +/ +create or replace + package body pkg is + type srec is record (a number, b number, c number, d number); + type srec_list is table of srec; + + type num_list is table of number; + type array_rec is record (a num_list, b num_list, + c num_list, d num_list ); + procedure rec_of_array_test is + s number := dbms_utility.get_time; + e number; + v1 srec_list; + q number; + begin + v1 := srec_list(); + v1.extend(500000); + for i in 1 .. 500000 loop + v1(i).a := i; + v1(i).b := i; + v1(i).c := i; + v1(i).d := i; + end loop; + e := dbms_utility.get_time; + dbms_output.put_line('Populate: '||(e-s)); + for i in 1 .. 250000 loop + q := v1(i*2-1).a; + q := v1(i*2).b; + q := v1(500000-i).c; + q := v1(500000-2*i+1).d; + end loop; + s := dbms_utility.get_time; + dbms_output.put_line('Retrieve From: '||(s-e)); + end; + + procedure array_of_rec_test is + s number := dbms_utility.get_time; + e number; + v1 array_rec; + q number; + begin + v1.a := num_list(); v1.a.extend(500000); + v1.b := num_list(); v1.b.extend(500000); + v1.c := num_list(); v1.c.extend(500000); + v1.d := num_list(); v1.d.extend(500000); + for i in 1 .. 500000 loop + v1.a(i) := i; + v1.b(i) := i; + v1.c(i) := i; + v1.d(i) := i; + end loop; + e := dbms_utility.get_time; + dbms_output.put_line('Populate: '||(e-s)); + for i in 1 .. 250000 loop + q := v1.a(i*2-1); + q := v1.b(i*2); + q := v1.c(500000-i); + q := v1.d(500000-2*i+1); + end loop; + s := dbms_utility.get_time; + dbms_output.put_line('Retrieve From: '||(s-e)); + end; + + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_09.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_09.txt new file mode 100755 index 0000000..422cd6e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_09.txt @@ -0,0 +1,14 @@ +create or replace + procedure WITH_ROWTYPE is + r T%ROWTYPE; + begin + select * + into r + from T + where rownum = 1; + + update T1 + set row = r + where rownum = 1; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_10.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_10.txt new file mode 100755 index 0000000..52ab374 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_10.txt @@ -0,0 +1,16 @@ +create table T ( c1, c2) as + select 1,2 from dual; +create table T1 ( c2 number, c1 number ); +create or replace +procedure COPY_ROW is + r T%ROWTYPE; + begin + select * + into r + from T + where rownum = 1; + + insert into T1 + values r; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_11.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_11.txt new file mode 100755 index 0000000..b53cad0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_11.txt @@ -0,0 +1,20 @@ +create table REDO_TEST + ( col char(100)); +insert into REDO_TEST + select 'x' + from all_Objects + where rownum < 100; +select value + from v$mystats + where name = 'redo size'; +update redo_test + set col = 'y'; +select value + from v$mystats + where name = 'redo size'; +update redo_test + set col = 'y'; + +select value + from v$mystats + where name = 'redo size'; diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_12.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_12.txt new file mode 100755 index 0000000..8bb6048 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_12.txt @@ -0,0 +1,53 @@ +create table REC_DML ( + x number, + y char(100), + z number ); +insert into rec_dml + select rownum, rownum, rownum + from sys.source$ + where rownum < 1000; +declare + redo_amount number; + p rec_dml%rowtype; + begin + select value + into redo_amount + from v$mystats + where name = 'redo size'; + for i in ( select * from rec_dml) loop + update rec_dml + set z = z + 1 + where x = i.x; + end loop; + select value-redo_amount + into redo_amount + from v$mystats + where name = 'redo size'; + dbms_output.put_line('Redo generated: '||redo_amount); + end; +/ + +declare —new record based DML + redo_amount number; + p rec_dml%rowtype; + begin + select value + into redo_amount + from v$mystats + where name = 'redo size'; + for i in ( select * from rec_dml) loop + p.x := i.x; + p.y := i.y; + p.z := i.z+1; + update rec_dml + set row = p + where x = i.x; + end loop; + select value-redo_amount + into redo_amount + from v$mystats + where name = 'redo size'; + dbms_output.put_line('Redo generated: '||redo_amount); + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_13.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_13.txt new file mode 100755 index 0000000..18ea78e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_13.txt @@ -0,0 +1,25 @@ +select + case when column_id = 1 then + 'create or replace trigger '||table_name|| + '_trg'||chr(10)|| + 'after update on '||table_name||chr(10)|| + 'for each row'||chr(10)|| + 'declare'||chr(10)|| + ' p_new '||table_name||'%rowtype;'||chr(10)|| + ' p_old '||table_name||'%rowtype;'||chr(10)|| + 'begin'||chr(10)|| + ' p_new.'||lower(column_name)||' := :new.'||lower(column_name)|| + ';'||chr(10)|| + ' p_old.'||lower(column_name)||' := :old.'||lower(column_name)||';' + else + ' p_new.'||lower(column_name)||' := :new.'||lower(column_name)|| + ';'||chr(10)|| + ' p_old.'||lower(column_name)||' := :old.'||lower(column_name)||';' + end trg + from user_tab_columns + where table_name = upper('&&table_name') + union all + select ' trgproc_&&table_name(p_new,p_old);' from dual + union all + select 'end;' from dual +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_14.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_14.txt new file mode 100755 index 0000000..096d6bb --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_14.txt @@ -0,0 +1,20 @@ +function get_gender_name(p_id sex.id%type) return sex.name%type is +v_name sex.name%type; +begin +select name +into v_name +from sex +where id = p_id; +return v_name; +end; + +select id, + first_name||' '||last_name full_name, + get_gender_name(sexid) gender + from persons; + +select p.id, + p.first_name||' '||p.last_name full_name, + sex.name + from persons p, sex +where sex.id = p.sexid; diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_15.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_15.txt new file mode 100755 index 0000000..96bb914 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_15.txt @@ -0,0 +1,38 @@ +create table T2 ( k number(5)) +create or replace package P is + v number := 0; + end; +/ +create or replace + trigger T2_TRG + before insert on T2 + for each row + begin + p.v := p.v + 1; + end; +/ +alter session set sql_trace = true; +insert into T2 /* no_select_in_trigger */ + select rownum + from all_objects + where rownum <= 20000; +alter session set sql_trace = false; +create or replace + trigger T2_TRG + before insert on T2 + for each row + declare + l number; + begin + select 1 into l from dual; + p.v := p.v + 1; +end; +/ +Trigger created. +truncate table T2; +alter session set sql_trace = true; +insert into T2 /* with_select_in_trigger */ + select rownum + from all_objects + where rownum <= 20000; +alter session set sql_trace = false; diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_16.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_16.txt new file mode 100755 index 0000000..314454a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_16.txt @@ -0,0 +1,25 @@ +create or replace + package counter is + procedure reset; + procedure inc; + procedure show; + end; +/ +create or replace + package body counter is + cnt pls_integer := 0; + procedure reset is + begin + cnt := 0; + end ; + procedure inc is + begin + cnt := cnt + 1; + end; + procedure show is + begin + dbms_output.put_line('Execution Count: '||cnt); + end; + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_17.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_17.txt new file mode 100755 index 0000000..954b02c --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_17.txt @@ -0,0 +1,86 @@ +create or replace + function do_something(p varchar2) return varchar2 is + begin + counter.inc; + + return p; + end; +/ + +exec counter.reset; +create table big_tab +as select owner, name, type, line +from dba_source; +analyze table big_tab estimate statistics; +select name, line, do_something(owner) +from big_tab; +exec counter.show; + + +exec counter.reset; +select name, line, do_something(owner) +from big_tab +where do_something(owner) is not null +order by do_something(owner) desc +/ +exec counter.show; + +exec counter.reset; +select name, line, function_result +from big_tab a, + ( select distinct owner, do_something(owner) function_result + from big_tab ) f + where a.owner = f.owner +/ +exec counter.show; + +exec counter.reset; +select name, line, function_result + from big_tab a, + ( select owner, do_something(owner) function_result + from ( select distinct owner + from big_tab ) ) f + where a.owner = f.owner +/ +exec counter.show; + +exec counter.reset; +select name, line, function_result + from big_tab a, + ( select owner, rownum, do_something(owner) function_result + from ( select distinct owner + from big_tab ) ) f + where a.owner = f.owner +/ +exec counter.show; + +create or replace + function do_something(p_owner varchar2) + return varchar2 deterministic is + begin + counter.inc; + return p_owner; + end; +/ +create index big_ix on +big_tab ( do_something(owner)); +analyze index big_ix estimate statistics; + +exec counter.reset; +select name, line, do_something(owner) +from big_tab; +exec counter.show; + + +exec counter.reset; +select name, line, do_something(owner) +from big_tab +where do_something(owner) is not null; +exec counter.show; + +exec counter.reset; +select /*+ INDEX(big_tab big_ix) */ name, + line, do_something(owner) + from big_tab + where do_something(owner) is not null; +exec counter.show; diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_18.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_18.txt new file mode 100755 index 0000000..2099826 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_18.txt @@ -0,0 +1,44 @@ +create or replace + procedure DO_WORK(x number) is + y number; + begin + y := x; + end; +/ +set timing on +begin + for i in 1 .. 10000 loop + execute immediate 'begin do_work(:x); end;' using i; + end loop; + end; +/ + +begin + for i in 1 .. 10000 loop + execute immediate 'begin do_work('||i||'); end;'; + end loop; + end; +/ + +create global temporary table parms + ( parm_val number ) + on commit preserve rows; +create or replace + procedure DO_WORK is + begin + for i in ( select * from parms ) loop + null; + end loop; +end; +/ +alter session set cursor_sharing = force; + +begin + for i in 1 .. 10000 loop + execute immediate 'insert into parms values ('||i||')'; + end loop; + execute immediate 'begin do_work; end;'; + execute immediate 'truncate table parms'; +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_19.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_19.txt new file mode 100755 index 0000000..e8289b1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_19.txt @@ -0,0 +1,22 @@ +create or replace + type num_list is table of number; +/ +create or replace + procedure DO_WORK(x num_list) is + begin + for i in 1 .. x.count loop + null; + end loop; + end; +/ +set timing on +declare + v varchar2(32767) := 'num_list('; + begin + for i in 1 .. 5000 loop + v := v || case when i = 1 then to_char(i) else ','||i end; + end loop; + v := v || ')'; + execute immediate 'begin do_work('||v||'); end;'; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_20.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_20.txt new file mode 100755 index 0000000..7bf7548 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_20.txt @@ -0,0 +1,80 @@ +create table AUDIT_EMP ( + empno number(10), + reason varchar2(30), + change_date date, + change_by varchar2(30)); +create or replace + trigger AUDIT_EMP_CHANGES + before insert or update or delete + on EMP + for each row + declare + v_change date := sysdate; + v_uid number := uid; + v_reason varchar2(30); + begin + if inserting then + v_reason := 'Addition'; + elsif deleting then + v_reason := 'Deletion'; + elsif updating then + v_reason := 'Pre-Modification'; + end if; + insert into audit_emp values + ( :new.empno, v_reason, v_change, v_uid); + end; +/ +alter session set sql_trace = true; +delete from emp; + + +create or replace + trigger AUDIT_EMP_CHANGES + before insert or update or delete + on EMP + for each row + declare + v_reason varchar2(30); + begin + if inserting then + v_reason := 'Addition'; + elsif deleting then + v_reason := 'Deletion'; + elsif updating then + v_reason := 'Pre-Modification'; + end if; + insert into audit_emp values + ( :new.empno, v_reason, sysdate, uid); + end; +/ + +create or replace + package U is + id number := uid; + end; +/ + +create or replace + trigger AUDIT_EMP_TO_FILE + before insert or update or delete + on EMP + for each row + declare + f utl_file.file_type; + v_reason varchar2(30); + begin + f := utl_file.fopen('/tmp','audit.dat','A'); + if inserting then + v_reason := 'Addition'; + elsif deleting then + v_reason := 'Deletion'; +elsif updating then + v_reason := 'Pre-Modification'; + end if; + utl_file.put_line(f,'EMPNO '||:new.empno); + utl_file.put_line(f,'REASON '||v_reason); + utl_file.put_line(f,'DATE '||sysdate); + utl_file.put_line(f,'UID '||u.id); + utl_file.fclose(f); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_22.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_22.txt new file mode 100755 index 0000000..e1da2df --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_22.txt @@ -0,0 +1,18 @@ +create or replace + procedure reset_password(p_empno varchar2) is + v_username varchar2(30); + begin + select ename + into v_username + from emp + where empno = p_empno + and mgr = ( select empno from emp where ename = user ); + execute immediate + 'alter user "'||v_username||'" '|| + ' identified by '||v_username; + exception + when no_data_found then + raise_application_error(-20000, + 'You are not authorised to alter employee '||p_empno); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_24.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_24.txt new file mode 100755 index 0000000..157d4ec --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_24.txt @@ -0,0 +1,25 @@ +create table PASSWORD_AUDIT ( + empno number, + date_change date ); +create or replace + procedure admin.reset_password(p_empno varchar2) is + v_username varchar2(30); + v_job number; + begin + select ename + into v_username + from emp + where empno = p_empno + and mgr = ( select empno from emp where ename = user ); + insert into password_audit values ( + p_empno, user, sysdate); + dbms_job.submit(v_job, + 'begin execute immediate ' || + '''alter user "'||v_username||'" '|| + ' identified by '||v_username||'''; end;'); + exception + when no_data_found then + raise_application_error(-20000, + 'You are not authorised to alter employee '||p_empno); + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_25.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_25.txt new file mode 100755 index 0000000..448304e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_25.txt @@ -0,0 +1,11 @@ +CREATE PROCEDURE delete_rows ( +table_name IN VARCHAR2, +condition IN VARCHAR2 DEFAULT NULL) AS +where_clause VARCHAR2(100) := ' WHERE ' || condition; +BEGIN +IF condition IS NULL THEN +where_clause := NULL; +END IF; +EXECUTE IMMEDIATE +'DELETE FROM ' || table_name || where_clause; +END; \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_26.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_26.txt new file mode 100755 index 0000000..2ef3a63 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_26.txt @@ -0,0 +1,67 @@ +create or replace +procedure STATIC_ADHOC ( +p_deptno number, +p_dname varchar2, +p_loc number, +p_option number ) is +cursor c1 is +select * from dept +where deptno = p_deptno; + cursor c2 is + select * from dept + where dname = p_dname; + cursor c3 is + select * from dept + where loc = p_loc; + cursor c7 is + select * from dept + where deptno = p_deptno or loc = p_loc; + cursor c8 is + select * from dept + where loc = p_loc and dname = p_dname; + cursor c9 is + select * from dept + where loc = p_loc or dname = p_dname; + cursor c13 is + select * from dept + where ( deptno = p_deptno or dname = p_dname) and loc = p_loc; + cursor c14 is + select * from dept + where deptno = p_deptno or ( dname = p_dname and loc = p_loc); + cursor c15 is + select * from dept + where deptno = p_deptno or dname = p_dname or loc = p_loc; + r dept%rowtype; + begin + if p_option = 1 then + open c1; fetch c1 into r; close c1; + elsif p_option = 2 then + open c2; fetch c2 into r; close c2; + elsif p_option = 3 then + open c3; fetch c3 into r; close c3; + elsif p_option = 7 then + open c7; fetch c7 into r; close c7; + elsif p_option = 8 then + open c8; fetch c8 into r; close c8; + elsif p_option = 9 then + open c9; fetch c9 into r; close c9; + elsif p_option = 13 then + open c13; fetch c13 into r; close c13; + elsif p_option = 14 then + open c14; fetch c14 into r; close c14; + elsif p_option = 15 then + open c15; fetch c15 into r; close c15; + end if; + end; +/ +create or replace +procedure DYN_ADHOC(p_where varchar2) is +type rc is ref cursor; +c rc; +r dept%rowtype; +begin +open c for 'select * from dept where '||p_where; +fetch c into r; +close c; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch05/ch5_27.txt b/2174_MasteringPLSQL_CODE/Ch05/ch5_27.txt new file mode 100755 index 0000000..f6371e8 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch05/ch5_27.txt @@ -0,0 +1,9 @@ +declare + options num_list := num_list(1,2,3,7,8,9,13,14,15); + v_where varchar2(500); + begin + for i in ( select dc.*, rownum r from dept_copy dc ) loop + STATIC_ADHOC(i.deptno, i.dname, i.loc, options(mod(i.r,9)+1)); + end loop; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql01.sql b/2174_MasteringPLSQL_CODE/Ch06/sql01.sql new file mode 100755 index 0000000..252ad58 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql01.sql @@ -0,0 +1,10 @@ +create or replace trigger save_the_database_from_alex +after logon on alex.schema +begin + if to_char(current_timestamp,'hh24') between 08 and 18 and + to_char(current_timestamp,'d') between 2 and 5 then + raise_application_error(-20000, + 'Do you realize that this is a production database?'); + end if; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql02.sql b/2174_MasteringPLSQL_CODE/Ch06/sql02.sql new file mode 100755 index 0000000..79af834 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql02.sql @@ -0,0 +1,77 @@ +-- create full set of triggers on dept and emp tables + +-- Create a Before Statement trigger +create or replace trigger deptbs + before insert or update or delete + on dept + begin + dbms_output.put_line('before statement (dept)'); + end; +/ +-- Create a Before Statement trigger +create or replace trigger empbs + before insert or update or delete + on emp + begin + dbms_output.put_line('before statement (emp)'); + end; +/ + +-- Create a Before Row Trigger + create or replace trigger emp_br + before insert or update or delete + on emp + for each row + begin + dbms_output.put_line('...before row (emp)'); + end; +/ + +-- Create an After Row Trigger +create or replace trigger emp_ar + after insert or update or delete + on emp + for each row + begin + dbms_output.put_line('...after row (emp)'); + end; +/ +-- Create a Before Row Trigger + create or replace trigger dept_br + before insert or update or delete + on dept + for each row + begin + dbms_output.put_line('...before row (dept)'); + end; +/ + +-- Create an After Row Trigger +create or replace trigger dept_ar + after insert or update or delete + on dept + for each row + begin + dbms_output.put_line('...after row (dept)'); + end; +/ + + + +-- Create an After Statement Trigger + create or replace trigger empas + after insert or update or delete + on emp + begin + dbms_output.put_line('after statement (emp)'); + end; +/ +-- Create an After Statement Trigger + create or replace trigger deptas + after insert or update or delete + on dept + begin + dbms_output.put_line('after statement (dept)'); + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql03.sql b/2174_MasteringPLSQL_CODE/Ch06/sql03.sql new file mode 100755 index 0000000..ccf6a42 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql03.sql @@ -0,0 +1,28 @@ +create or replace type outputLines as table of varchar2(4000); +/ + +-- Function to display trigger text by line number +-- Counts the chr(10) linefeed character +create or replace function +TriggerText (p_owner in varchar2, p_trigger in varchar2) return outputLines +authid current_user +pipelined +as + body long; + j number; -- position of linefeed character + begin + select trigger_body + into body + from all_triggers + where trigger_name = p_trigger and + owner = p_owner; + + body := body || chr(10); + while ( body is not null ) loop + j := instr( body, chr(10) ); + pipe row ( substr( body, 1, j-1 ) ); + body := substr( body, j+1 ); + end loop; + return; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql04.sql b/2174_MasteringPLSQL_CODE/Ch06/sql04.sql new file mode 100755 index 0000000..35f9533 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql04.sql @@ -0,0 +1,15 @@ +alter table dept +add +(last_update date, + last_user varchar2(30)); + +CREATE OR REPLACE TRIGGER deptBR + before update or insert + ON dept + FOR EACH ROW + DECLARE + begin + :new.last_update := sysdate; + :new.last_user := user; + end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql05.sql b/2174_MasteringPLSQL_CODE/Ch06/sql05.sql new file mode 100755 index 0000000..c6765ad --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql05.sql @@ -0,0 +1,41 @@ +create table scout + (id number, + rank varchar2(30) not null + constraint check_rank + check (rank in + ('Scout','Tenderfoot','Star Scout','Life Scout','Eagle Scout')) +); + + +create or replace trigger tbur_scout before update on scout + for each row + when (new.rank <> old.rank) + declare + type ranklist is varray(10) of varchar2(30); + ranks ranklist := ranklist('Scout','Tenderfoot','Star Scout', + 'Life Scout','Eagle Scout'); + function diff (p_new in varchar2,p_old in varchar2) + return number is + newRank number; + oldRank number; + begin + for i in 1..ranks.last loop + if p_new = ranks(i) then + newRank := i; + elsif + p_old = ranks(i) then + oldRank := i; + end if; + end loop; + return newRank - oldRank; + end; + + begin + + if diff(:new.rank,:old.rank) != 1 then + raise_application_error(-20001,'Rank is out of sequence'); + end if; + + end; +/ + diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql06.sql b/2174_MasteringPLSQL_CODE/Ch06/sql06.sql new file mode 100755 index 0000000..996b824 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql06.sql @@ -0,0 +1,16 @@ +create table work_orders + (wo_id number); + +create sequence wo_seq; + +create or replace trigger trg_wo_id +before insert +on work_orders +for each row +when (new.wo_id is null) +begin + select wo_seq.nextval + into :new.wo_id + from dual; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql07.sql b/2174_MasteringPLSQL_CODE/Ch06/sql07.sql new file mode 100755 index 0000000..2ec8860 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql07.sql @@ -0,0 +1,26 @@ +-- Create a view that displays average salary by department + create view dept_sal + as + select dname,round(avg(sal),2) avgSalary + from emp,dept + where emp.deptno = dept.deptno + group by dname +/ + +-- Instead of trigger to update emp and dept table +-- when updating the dept_sal view + create or replace trigger dept_sal_trg + instead of update on dept_sal + begin + if (nvl(:new.avgsalary,-1) <> nvl(:old.avgsalary,-1)) then + update emp + set sal = (:new.avgsalary/:old.avgsalary) * sal + where deptno = (select deptno + from dept + where dname = :new:old.dname); + end if; + update dept + set dname = :new.dname + where dname = :old.dname; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql08.sql b/2174_MasteringPLSQL_CODE/Ch06/sql08.sql new file mode 100755 index 0000000..4c4f2ac --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql08.sql @@ -0,0 +1,3 @@ +CREATE TABLE TRAIN_RIDES (TRAIN_NO NUMBER, TRAVEL_DATE + DATE, COACH_NO NUMBER, SEAT_NO NUMBER, RESERVATION_NO + NUMBER); \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql09.sql b/2174_MasteringPLSQL_CODE/Ch06/sql09.sql new file mode 100755 index 0000000..fe3de4f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql09.sql @@ -0,0 +1,60 @@ +CREATE OR REPLACE PACKAGE TRAIN_RIDE_PACKAGE is + procedure set_initial_state; + procedure save_train_no (trainid number,dateid date); + procedure check_free_space_on_train; +end; +/ + +CREATE OR REPLACE PACKAGE BODY TRAIN_RIDE_PACKAGE +is +-- This package body creates the procedures that the +-- triggers will execute + + type train_table is table of date index by pls_integer; + + position train_table; + empty train_table; + + +procedure set_initial_state is +-- initialize the associative array +begin + position := empty; +end; + +procedure save_train_no (trainid number, dateid date) is +-- save the trainId and travelDate +begin + position(trainid) := dateid; +end; + +procedure check_free_space_on_train +is +-- retrieve the trainId and travelDate +-- and query the train_ride table +-- Add a coach when necessary +trainid_in number; +free_seats number; + +begin + trainid_in := position.FIRST; + while trainid_in is not null loop + + select count(*) + into free_seats + from train_rides + where reservation_no is null and + train_no = trainid_in and + travel_date = position(trainid_in); + + if free_seats < 50 + then add_a_coach(trainid_in,position(trainid_in)); + end if; + + position.delete(trainid_in); + trainid_in := position.next(trainid_in); + end loop; +end; + +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql10.sql b/2174_MasteringPLSQL_CODE/Ch06/sql10.sql new file mode 100755 index 0000000..bcd68b0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql10.sql @@ -0,0 +1,18 @@ +CREATE OR REPLACE TRIGGER TRG_TR_AR AFTER +UPDATE ON TRAIN_RIDES FOR EACH ROW begin + train_ride_package.save_train_no + (:new.train_no,:new.travel_date); +end; +/ + +CREATE OR REPLACE TRIGGER TRG_TR_AS AFTER +UPDATE ON TRAIN_RIDES begin + train_ride_package.check_free_space_on_train; +end; +/ + +CREATE OR REPLACE TRIGGER TRG_TR_BS BEFORE +UPDATE ON TRAIN_RIDES begin + train_ride_package.set_initial_state; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql11.sql b/2174_MasteringPLSQL_CODE/Ch06/sql11.sql new file mode 100755 index 0000000..15a0813 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql11.sql @@ -0,0 +1,12 @@ +CREATE OR REPLACE PROCEDURE ADD_A_COACH (id in number, dt + in date) +as +begin + insert into train_rides + (train_no,travel_date,coach_no,seat_no) + select train_no,trunc(sysdate),coach_no + 1,rownum + from train_rides + where rownum < 101 + and train_no = 1; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql12.sql b/2174_MasteringPLSQL_CODE/Ch06/sql12.sql new file mode 100755 index 0000000..94237d4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql12.sql @@ -0,0 +1,24 @@ +-- After Row Autonomous Trigger +-- Reads from the triggered table +create or replace trigger check_free_space_on_train +after update of reservation_no +on train_rides +for each row +declare +free_seats number; +PRAGMA AUTONOMOUS_TRANSACTION; +begin + + select count(*) + into free_seats + from train_rides + where reservation_no is null and + train_no = :new.train_no and + travel_date = :new.travel_date; + + if free_seats < 50 + then add_a_coach(:new.train_no,:new.travel_date); + end if; + + commit; +end; diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql13.sql b/2174_MasteringPLSQL_CODE/Ch06/sql13.sql new file mode 100755 index 0000000..2d51458 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql13.sql @@ -0,0 +1,9 @@ +select name as "Trigger", + table_name as "Base Table", + referenced_name as "References TableName" +from user_dependencies,user_triggers +where type='TRIGGER' and + referenced_type = 'TABLE' and + table_name != referenced_name and + name = trigger_name +order by 1; diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql14.sql b/2174_MasteringPLSQL_CODE/Ch06/sql14.sql new file mode 100755 index 0000000..61382f6 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql14.sql @@ -0,0 +1,39 @@ +CREATE TABLE DEPT$AUDIT ( +DEPTNO NUMBER, +DNAME VARCHAR2(14 byte), +LOC VARCHAR2(13 byte), +CHANGE_TYPE VARCHAR2(1 byte), +CHANGED_BY VARCHAR2(30 byte), +CHANGED_TIME DATE); + +CREATE OR REPLACE TRIGGER auditDEPTAR AFTER +INSERT +OR UPDATE +OR DELETE ON DEPT FOR EACH ROW +declare +my DEPT$audit%ROWTYPE; +begin +if inserting then my.change_type := 'I'; +elsif updating then my.change_type :='U'; +else my.change_type := 'D'; +end if; + +my.changed_by := user; +my.changed_time := sysdate; + +case my.change_type +when 'I' then + my.DEPTNO := :new.DEPTNO; + my.DNAME := :new.DNAME; + my.LOC := :new.LOC; +else + my.DEPTNO := :old.DEPTNO; + my.DNAME := :old.DNAME; + my.LOC := :old.LOC; +end case; + +insert into DEPT$audit values my; +end; +/ + + \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql15.sql b/2174_MasteringPLSQL_CODE/Ch06/sql15.sql new file mode 100755 index 0000000..b773d7c --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql15.sql @@ -0,0 +1,55 @@ +-- Accepts a table name and creates a simple auditing trigger +-- A shadow table (called $audit) has to exist already +CREATE OR REPLACE PROCEDURE GENERATETRIGGER + generateTrigger(p_tableName in varchar2) +authid current_user +as +b varchar2(4000); +cursor c1 is +select column_name +from user_tab_columns +where table_name = p_tableName +order by column_id; + +procedure appendx (destination in out varchar2, + string_in varchar2) +is +begin +destination := destination||string_in||chr(10); +end; + +begin +-- build the create trigger command + appendx(b,'create or replace trigger '||p_tableName||'ar'); + appendx(b,'after update or insert or delete on '||p_tableName||' '); + appendx(b,'for each row'); + appendx(b,'declare'); + appendx(b,'my '||p_tableName||'$audit%ROWTYPE;'); + appendx(b,'begin '); + appendx(b,'if inserting then my.change_type := ''I'';'); + appendx(b,'elsif updating then my.change_type :=''U'';'); + appendx(b,'else my.change_type := ''D'';'); + appendx(b,'end if;'); + appendx(b,'my.changed_by := user;'); + appendx(b,'my.changed_time := sysdate;'); + appendx(b,'case my.change_type'); + appendx(b,'when ''I'' then'); + + for x in c1 loop + appendx(b,'my.'||x.column_name||' := :new.'||x.column_name||';'); + end loop; + appendx(b,'else'); + + for x in c1 loop + appendx(b,'my.'||x.column_name||' := :old.'||x.column_name||';'); + end loop; + appendx(b,'end case;'); + + appendx(b,'insert into '||p_tableName||'$audit values my;'); + appendx(b,'end;'); + +-- create the trigger + execute immediate b; + +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql16.sql b/2174_MasteringPLSQL_CODE/Ch06/sql16.sql new file mode 100755 index 0000000..d280a08 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql16.sql @@ -0,0 +1,12 @@ +create audit_trail_1 +(change_id number, + command_type varchar2(1), + table_name varchar2(30), + user_name varchar2(30), + change_date date); + +create table audit_trail_2 +(change_id number, + column_name varchar2(30), + actual_data_new sys.anydata, + actual_data_old sys.anydata); diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql17.sql b/2174_MasteringPLSQL_CODE/Ch06/sql17.sql new file mode 100755 index 0000000..d09ce42 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql17.sql @@ -0,0 +1,63 @@ +create or replace +PROCEDURE dml_handler(in_any IN SYS.ANYDATA) IS + lcr SYS.LCR$_ROW_RECORD; + rc PLS_INTEGER; + oldlist SYS.LCR$_ROW_LIST; + newlist SYS.LCR$_ROW_LIST; + command varchar2(32); + tname varchar2(30); + v_scn number; + v_user varchar2(30); + v_date date; + v_change_id number; + newdata sys.AnyData; + +BEGIN + + -- Access the LCR + rc := in_any.GETOBJECT(lcr); + command := lcr.GET_COMMAND_TYPE(); + tname := lcr.GET_OBJECT_NAME; + v_scn := lcr.GET_SCN; + oldlist := lcr.GET_VALUES('old'); + newlist := lcr.get_values('new'); + +-- lookup the info that we associated with this scn +-- and insert into audit_trail_1 + insert into audit_trail_1 + (change_id, command_type, table_name, user_name,change_date) + select data_audit_seq.nextval,substr(command,1,1), + tname,scn_user,scn_date + from audit_temp + where scn = v_scn; + +-- write audit_trail_2 + IF command = 'DELETE' then + FOR i IN 1..oldlist.COUNT LOOP + insert into audit_trail_2 + (change_id, column_name,actual_data_old) + values (data_audit_seq.currval, + oldlist(i).column_name,oldlist(i).data); + END LOOP; + ELSIF command = 'INSERT' then + FOR i IN 1..newlist.COUNT LOOP + insert into audit_trail_2 + (change_id, column_name,actual_data_new) + values (data_audit_seq.currval, + newlist(i).column_name,newlist(i).data); + END LOOP; + ELSIF command = 'UPDATE' then + FOR i IN 1..oldlist.COUNT LOOP + newdata := lcr.get_value('new',oldlist(i).column_name); + if newdata is null then + newdata := oldlist(i).data; + end if; + insert into audit_trail_2 + (change_id, column_name,actual_data_new,actual_data_old) + values (data_audit_seq.currval, + oldlist(i).column_name,newdata,oldlist(i).data); + END LOOP; +END IF; + +END; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql18.sql b/2174_MasteringPLSQL_CODE/Ch06/sql18.sql new file mode 100755 index 0000000..fc27c8c --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql18.sql @@ -0,0 +1,34 @@ +-- Display values stored in a sys.anydata column +create or replace +function disp_any(data IN SYS.AnyData) +return varchar2 IS + str VARCHAR2(4000); + return_value varchar2(4000); + chr CHAR(255); + num NUMBER; + dat DATE; + res number; +begin + if data is null then + return_value := null; + else + case data.gettypename + when 'SYS.VARCHAR2' then + res := data.GETVARCHAR2(str); + return_value := str; + when 'SYS.CHAR' then + res := data.GETCHAR(chr); + return_value := chr; + when 'SYS.NUMBER' THEN + res := data.GETNUMBER(num); + return_value := num; + when 'SYS.DATE' THEN + res := data.GETDATE(dat); + return_value := dat; + else + return_value := data.gettypename()||' ????'; + end case; + end if; + return return_value; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql19.sql b/2174_MasteringPLSQL_CODE/Ch06/sql19.sql new file mode 100755 index 0000000..0ae326e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql19.sql @@ -0,0 +1,30 @@ +create table work_orders +(woid number, + recipient varchar2(80), + email_jobno number); + +create or replace trigger +worknotbr before insert +on work_orders for each row +declare +jobno number; +begin + dbms_job.submit(job => jobno, what => 'email( job );'); + :new.email_jobNo:= jobno; +end; +/ +procedure email (job in number) +is +lv_recipient work_orders.recipient%type; +begin + select recipient + into lv_recipient + from work_orders + where email_jobNo = job; + + send_email(lv_recipient); +end; +/ + + + diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql20.sql b/2174_MasteringPLSQL_CODE/Ch06/sql20.sql new file mode 100755 index 0000000..7190ded --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql20.sql @@ -0,0 +1,18 @@ +create or replace +procedure AlterUser (usernameIn in varchar2) is +begin + execute immediate ( 'alter user ' ||usernameIn|| +' default tablespace users'); +end; +/ +create or replace +trigger SystemAlterUser + after create on database + declare + jobno number; + begin + if ora_dict_obj_type = 'USER' then + dbms_job.submit(job => jobno, what => 'alteruser('''||ora_dict_obj_name||''');'); + end if; + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql21.sql b/2174_MasteringPLSQL_CODE/Ch06/sql21.sql new file mode 100755 index 0000000..e9f415d --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql21.sql @@ -0,0 +1,6 @@ +create or replace trigger prevent_drop +before drop on alex.schema +begin + raise_application_error(-20000,'Invalid command: DROP '); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql22.sql b/2174_MasteringPLSQL_CODE/Ch06/sql22.sql new file mode 100755 index 0000000..2138bb3 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql22.sql @@ -0,0 +1,37 @@ +create table old_source_header +(username varchar2(30), + change_id number, + change_date date); + + +create table old_source_detail +(change_id number, + owner varchar2(30), + name varchar2(30), + type varchar2(12), + line number, + text varchar2(4000)); + +create sequence source_seq; + + +-- Save the code before any changes are made to it +create or replace trigger save_old_code +before create on database +begin + if ora_dict_obj_type in + ( 'PACKAGE','PACKAGE BODY','PROCEDURE','FUNCTION' ) then + + insert into old_source_header + (username,change_id,change_date) + values (ora_login_user,source_seq.nextval,sysdate); + + insert into old_source_detail + select source_seq.currval,dba_source.* + from dba_source + where owner = ora_dict_obj_owner and + name = ora_dict_obj_name and + type = ora_dict_obj_type; + end if; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql23.sql b/2174_MasteringPLSQL_CODE/Ch06/sql23.sql new file mode 100755 index 0000000..35ac0c9 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql23.sql @@ -0,0 +1,14 @@ +Create or replace trigger loginCheckTrg after logon on database +declare + m_count number; +begin + select count(*) + into m_count + from v$session + where audsid=sys_context('userenv','sessionid') + and program like '%MSQRY32.EXE%'; + if m_count > 0 then + raise_application_error(-20000,'Please try again later'); + end if; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql24.sql b/2174_MasteringPLSQL_CODE/Ch06/sql24.sql new file mode 100755 index 0000000..312541a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql24.sql @@ -0,0 +1,6 @@ +CREATE OR REPLACE TRIGGER change_schema +AFTER logon ON DATABASE +begin + execute immediate('alter session set current_schema=app_master'); +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql25.sql b/2174_MasteringPLSQL_CODE/Ch06/sql25.sql new file mode 100755 index 0000000..08a6306 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql25.sql @@ -0,0 +1,25 @@ +create table our_user_errors +(error_date date, + username varchar2(30), + error_msg varchar2(2000), + error_sql varchar2(2000)); + +-- Save information about all errors +create or replace trigger log_errors + after servererror on database +declare + sql_text ora_name_list_t; + msg varchar2(2000) := null; + stmt varchar2(2000):= null; +begin + for i in 1 .. ora_server_error_depth loop + msg := msg||ora_server_error_msg(i); + end loop; + for i in 1..ora_sql_txt(sql_text) loop + stmt := stmt||sql_text(i); + end loop; + insert into our_user_errors + (error_date,username,error_msg,error_sql) + values (sysdate,ora_login_user,msg,stmt); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch06/sql26.sql b/2174_MasteringPLSQL_CODE/Ch06/sql26.sql new file mode 100755 index 0000000..db0751f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch06/sql26.sql @@ -0,0 +1,34 @@ +create table usage_log +(user_id varchar2(30), + audsid varchar2(30), + log_on date, + log_off date, + cpu_used number); + +-- database login trigger +create or replace trigger usage_start +after logon on database +begin + insert into system.usage_log + (user_id,audid,log_on,log_off,cpu_used) + values (sys_context('userenv','session_user'), + sys_context('userenv','sessionid'), + sysdate, null, null); +end; +/ + +-- database logoff trigger +create or replace trigger usage_stop +before logoff on database +begin + update system.usage_log + set log_off = sysdate, + cpu_used = (select value + from v$mystat s,v$statname n + where s.statistic# = n.statistic# and + n.name like 'CPU used by this session') + where sys_context('USERENV', 'SESSIONID') = audid and + sys_context('userenv','session_user') = user_id and + log_off is null; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_body.sql b/2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_body.sql new file mode 100755 index 0000000..a6217f5 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_body.sql @@ -0,0 +1,72 @@ +-- Get the size of the database by summing the size of all the db objects +procedure databaseSize (p_instance_name_in in varchar2) +is + +notes notification.msgs; + +begin +-- Get the size of the database (Mb) text message +select to_char(sysdate,'Dy Mon dd hh24:mi:ss yyyy')||chr(10)|| + 'DB Size(Mb) '|| + to_char(round(sum(bytes)/(1024*1024),2)) +bulk collect into notes +from dba_segments; + +-- Extract the size from the above message and save it as the result_in +notification.notify(instance_name_in => p_instance_name_in, + msgs_in => notes, + subject_in => 'GROWTH', + result_in => substr(notes(1),37), + email_p => false, + db_p => true); +end; + + +-- Get the number of user sessions logged in right now +procedure databaseSessions (p_instance_name_in in varchar2) +is + +notes notification.msgs; + +begin +-- Get the number of sessions +select to_char(sysdate,'Dy Mon dd hh24:mi:ss yyyy')||chr(10)|| + 'Sessions '||count(*) +bulk collect into notes +from v$session +where type = 'USER'; + +-- extract the number of sessions from the above text and save as result_in +notification.notify(instance_name_in => p_instance_name_in, + msgs_in => notes, + subject_in => 'SESSIONS', + result_in => substr(notes(1),34), + email_p => false, + db_p => true); + +end; + + +procedure resourceLimit (p_instance_name_in in varchar2) +is + +notes notification.msgs; + +begin +select to_char(sysdate,'Dy Mon dd hh24:mi:ss yyyy')||chr(10)|| + rpad(resource_name,30)||' Max: '||lpad(max_utilization,10) +bulk collect into notes +from v$resource_limit +where trim(limit_value) != 'UNLIMITED'; + +-- save the elapsed time as result_in +notification.notify(instance_name_in => p_instance_name_in, + msgs_in => notes, + subject_in => 'RESOURCE _LIMIT', + result_in => -1, + email_p => false, + db_p => true); +end; + +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_spec.sql b/2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_spec.sql new file mode 100755 index 0000000..3c54185 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/Db_history_pkg_spec.sql @@ -0,0 +1,17 @@ +create or replace +package history +is +/** +* ========================================================================< +* Project: Database monitoring +* Description: Contains procedures that collect history of the database +* DB impact: minimal +* Commit inside: no +* Rollback inside: no +* ------------------------------------------------------------------------ +*/ +procedure databaseSize (p_instance_name_in in varchar2); +procedure databaseSessions (p_instance_name_in in varchar2); +procedure resourceLimit (p_instance_name_in in varchar2); +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_body.sql b/2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_body.sql new file mode 100755 index 0000000..5adf09a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_body.sql @@ -0,0 +1,180 @@ +CREATE OR REPLACE PACKAGE BODY "ALERT_FILE" is +-- extracts error messages from the alert file +-- renames the alert file +-- extracts all messages from the alert file +-- calls notification package to send emails + +procedure rename_alert_file (l_instance_name in varchar2) +as +-- It assumes that the alert log is named alert_INSTANCE.log +-- and renames it to alert_INSTANCEDay.log +alert_file_does_not_exist EXCEPTION; +PRAGMA exception_init(alert_file_does_not_exist, -29283); +begin +-- rename the alert file + utl_file.frename ( + src_location => 'ALERT_DIR', + src_filename => 'alert_'||l_instance_name||'.log', + dest_location => 'ALERT_DIR', + dest_filename => 'alert_'||l_instance_name|| + to_char(sysdate - 1,'Dy')||'.log', + overwrite => true); + +exception + when alert_file_does_not_exist then + null; +end; + + + +procedure read_alert_file (error_msg_arry out notification.msgs, + linecount out integer) +as +-- reads the alert file +-- Save any error messages in an associative array + +cursor c1 is + select msg_line + from alert_file_ext; + +l_buffer varchar2(1000); +l_msg_text varchar2(32767); +error_count binary_integer :=0; +begin +-- open the cursor + open c1; + +-- read ahead (probably the date line) + fetch c1 into l_buffer; + + while c1%FOUND loop +-- save the date line + l_msg_text := l_buffer; + +-- read the first msg body line + fetch c1 into l_buffer; + while (l_buffer not like '___ ___ __ __:__:__ ____' and c1%FOUND) loop + l_msg_text := l_msg_text||chr(10)||l_buffer; + fetch c1 into l_buffer; + end loop; + +-- check for error + if (instr(l_msg_text,'ORA-') > 0) then + error_count := error_count + 1; + error_msg_arry(error_count) := l_msg_text; + end if; + + end loop; + linecount := c1%ROWCOUNT; + close c1; +end; + + +procedure update_skip_count(p_count in number default 0, + reset boolean default false) +as +-- update access parameters of external table +i number; +j number; +adj number := p_count; +begin + for x in (select replace(access_parameters,chr(10)) param + from user_external_tables + where table_name = 'ALERT_FILE_EXT') loop + + i := owa_pattern.amatch(x.param,1,'.*skip',i); + j := owa_pattern.amatch(x.param,1,'.*skip \d*'); + +-- to reset the count (to zero) + if reset then + adj := -1 * to_number(substr(x.param,i,j-i)); + end if; + + execute immediate 'alter table alert_file_ext access parameters ('|| + substr(x.param,1,i)|| + (to_number(substr(x.param,i,j-i))+ adj)|| + substr(x.param,j)||')'; + + end loop; +end; + + +procedure review_alert_file ( p_instance_name_in in varchar2) +is +alert_msg_arry notification.msgs; +begin + select msg_line + bulk collect + into alert_msg_arry + from alert_file_ext; + + notification.notify(instance_name_in => p_instance_name_in, + msgs_in => alert_msg_arry, + subject_in => 'Review Alert File', + email_p => true, + db_p => false); +end; + + +procedure monitor_alert_file +as +error_msg_arry notification.msgs; +lcount integer; +l_instance_name varchar2(16); +exists_p boolean; +flength number; +bsize number; +alert_file_does_not_exist exception; +PRAGMA EXCEPTION_INIT(alert_file_does_not_exist, -29913); + +begin +-- check location of alert file + select instance_name + into l_instance_name + from v$parameter,v$instance,dba_directories + where directory_name = 'ALERT_DIR' and + name='background_dump_dest' and + value = directory_path; + +-- monitor the alert file and save errors + read_alert_file(error_msg_arry,lcount); + +-- update the external tables's access parameters + update_skip_count(lcount); + +-- send any any error messages + if error_msg_arry.last > 0 then + notification.notify(instance_name_in => l_instance_name, + msgs_in => error_msg_arry, + subject_in => 'ALERT FILE', + email_p => true, + db_p => false); + end if; + +-- rollover the alert file based on time and filesize + if to_char(sysdate,'hh24')= '06' and + to_char(sysdate,'mi') < '20' then + utl_file.fgetattr ( + location => 'ALERT_DIR', + filename => 'alert_'||l_instance_name||'.log', + fexists => exists_p, + file_length => flength, + block_size => bsize); + + if flength > 3000 then + update_skip_count(reset=>true); + review_alert_file(l_instance_name); + rename_alert_file(l_instance_name); + end if; + end if; + + +exception + when alert_file_does_not_exist then + null; + when no_data_found then + raise_application_error(-20000,'ALERT_DIR is not current'); + when others then + raise_application_error(-20000,dbms_utility.format_error_stack); +end; +end; \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_spec.sql b/2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_spec.sql new file mode 100755 index 0000000..fc52da4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/alert_file_pkg_spec.sql @@ -0,0 +1,13 @@ +CREATE OR REPLACE PACKAGE "ALERT_FILE" is +/** +* ========================================================================
+* Project: Alert file
+* Description: Monitor and manage the alert file
+* DB impact: reads exernal table
+* Commit inside: no
+* Rollback inside: no
+* ------------------------------------------------------------------------
+*/ + procedure monitor_alert_file; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/alert_file_view.sql b/2174_MasteringPLSQL_CODE/Ch07/alert_file_view.sql new file mode 100755 index 0000000..e9ebdb0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/alert_file_view.sql @@ -0,0 +1,33 @@ +-- View that displays the alert file's error messages +create or replace view alert_log_errors +as +select * + from ( +select * + from ( +select lineno, + msg_line, + thedate, + max( case when ora_error like 'ORA-%' + then rtrim(substr(ora_error,1,instr(ora_error,' ')-1),':') + else null + end ) over (partition by thedate) ora_error + from ( +select lineno, + msg_line, + max(thedate) over (order by lineno) thedate, + lead(msg_line) over (order by lineno) ora_error + from ( +select rownum lineno, + substr( msg_line, 1, 132 ) msg_line, + case when msg_line like '___ ___ __ __:__:__ ____' + then to_date( msg_line, 'Dy Mon DD hh24:mi:ss yyyy' ) + else null + end thedate + from alert_file_ext + ) + ) + ) + ) + where ora_error is not null + order by thedate diff --git a/2174_MasteringPLSQL_CODE/Ch07/create_alert_file_external_table.sql b/2174_MasteringPLSQL_CODE/Ch07/create_alert_file_external_table.sql new file mode 100755 index 0000000..885b7ea --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/create_alert_file_external_table.sql @@ -0,0 +1,26 @@ +Create or replace directory alert_dir +as 'c:\oracle\admin\rep9\bdump'; + +CREATE TABLE "ALERT_FILE_EXT" + ( "MSG_LINE" VARCHAR2(1000) + ) + ORGANIZATION EXTERNAL + ( TYPE ORACLE_LOADER + DEFAULT DIRECTORY "ALERT_DIR" + ACCESS PARAMETERS + ( RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII + nobadfile nologfile nodiscardfile + skip 0 + READSIZE 1048576 + FIELDS LDRTRIM + REJECT ROWS WITH ALL NULL FIELDS + ( + MSG_LINE (1:1000) CHAR(1000) + ) + ) + LOCATION + ( 'alert_rep9.log' + ) + ) + REJECT LIMIT UNLIMITED +/ diff --git a/2174_MasteringPLSQL_CODE/Ch07/create_notifications_alerts_table.sql b/2174_MasteringPLSQL_CODE/Ch07/create_notifications_alerts_table.sql new file mode 100755 index 0000000..87785ec --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/create_notifications_alerts_table.sql @@ -0,0 +1,11 @@ + CREATE TABLE ALERTS + ( EVENT_DATE DATE, + EVENT_TYPE VARCHAR2(16) NOT NULL ENABLE, + RESULT NUMBER, + RESULT_TEXT VARCHAR2(4000), + INSTANCE_NAME VARCHAR2(16), + CONSTRAINT EVENT_TYPE_IN CHECK (event_type in ('ALERT FILE', + 'BACKUPS','STORAGE','ARCHIVE','GROWTH','SESSIONS', + 'RESOURCE LIMIT')) ENABLE + ) +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/notification_pkg_body.sql b/2174_MasteringPLSQL_CODE/Ch07/notification_pkg_body.sql new file mode 100755 index 0000000..d98b5df --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/notification_pkg_body.sql @@ -0,0 +1,119 @@ +CREATE OR REPLACE PACKAGE BODY "NOTIFICATION" as + +procedure send_email (instance_name_in varchar2, msgs_in msgs, + subject_in varchar2, + recip recipients) is + +sender constant varchar2(60) := 'dba1@foo.com'; + +smtp_server constant varchar2(255) := 'SERVER100'; +local_domain constant varchar2(255) := 'foo.com'; + +lvDate varchar2(30) := to_char(sysdate,'mm/dd/yyyy hh24:mi'); +lvBody varchar2(32000); +c utl_smtp.connection; + +recipient_list varchar2(1000) := sender; +-- local procedure to reduce redundancy +procedure write_header (name in varchar2, header in varchar2) +is + begin + utl_smtp.write_data(c, name || ': ' || header || utl_tcp.CRLF); + end; + +begin + + for i in 1 .. recip.count loop + recipient_list = ','||recip(i); + end loop; + + -- Open SMTP connection + c := utl_smtp.open_connection(smtp_server); + + -- Perform initial handshaking with the SMTP server after connecting + utl_smtp.helo(c, local_domain ); + -- Initiate a mail transacation + utl_smtp.mail(c, sender); + -- Specify the recipients + utl_smtp.rcpt(c, sender); + for i in 1 .. recip.count loop + utl_smtp.rcpt(c, recip(i)); + end loop; + -- Send the data command to the SMTP server + utl_smtp.open_data(c); + -- Write the header part of the email body + write_header('Date',lvDate); + write_header('From',sender); + write_header('Subject',instance_name_in||' '||subject_in); + write_header('To',recipient_list); + write_header('Content-Type', 'text/html;'); + + -- format the message body in HTML + lvbody := '

'; + + -- the body of the email consists of the input message array + for i in 1.. msgs_in.last loop + lvbody := lvbody||'
'|| + replace(msgs_in(i),chr(10),'
'); + end loop; + + lvbody := lvbody||''; + -- write less than 1000 characters at a time + for x in 1 .. (length(lvbody)/800 + 1) loop + utl_smtp.write_data(c, utl_tcp.CRLF || + substr(lvBody,(x-1)*800 +1,800)); + end loop; + + -- end the email message + utl_smtp.close_data(c); + + -- disconnect from the smtp server + utl_smtp.quit(c); + +exception + when others then + utl_smtp.quit(c); + raise; +end; + +procedure save_in_db(instance_in varchar2, msgs_in msgs, + subject_in varchar2, result_in number) is +-- this program saves messages to a database table +-- it assumes that each message passed in begins with a string +-- that evaluates to a date in a specific format +run_time date; +begin + forall i in 1.. msgs_in.last + + insert into alerts (event_date, instance_name, + event_type, result, result_text) + values (to_date(substr(msgs_in(i),1,24), + 'Dy Mon dd hh24:mi:ss yyyy'), + instance_in,subject_in, + result_in,msgs_in(i)); + +end; + + +procedure notify (instance_name_in in varchar2, msgs_in in msgs, + subject_in in varchar2 default null, + result_in in number default null, + email_p in boolean, db_p in boolean, + recip recipients default null) is +begin +-- send email +if email_p = true then + send_email (instance_name_in, msgs_in, + subject_in, recip); +end if; + +if db_p = true then + save_in_db ( instance_name_in, msgs_in, + subject_in, result_in); +end if; +end; + +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/notification_pkg_spec.sql b/2174_MasteringPLSQL_CODE/Ch07/notification_pkg_spec.sql new file mode 100755 index 0000000..16b373b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/notification_pkg_spec.sql @@ -0,0 +1,21 @@ +CREATE OR REPLACE PACKAGE "NOTIFICATION" is +/** +* ========================================================================
+* Project: Database monitoring
+* Description: Send email message andor save message in database
+* DB impact: minimal
+* Commit inside: the save_in_db procedure commits
+* Rollback inside: no
+* ------------------------------------------------------------------------
+*/ + + type msgs is table of varchar2(4000) index by binary_integer; + type recipients is table of varchar2(255); + + procedure notify (instance_name_in in varchar2, msgs_in in msgs, + subject_in in varchar2 default null, + result_in in number default null, + email_p in boolean, db_p in boolean, + recip recipients default null); +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_body.sql b/2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_body.sql new file mode 100755 index 0000000..cbfbacb --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_body.sql @@ -0,0 +1,104 @@ +Procedure checkStatusOfLastBackup (p_instance_name_in in varchar2) +is +-- Check that there was an RMAN full database online backup +-- sometime within the last day (threshold = 1) +notes notification.msgs; +THRESHOLD number(4,2) := 1; +Begin + -- build a message containing the date of the last full RMAN backup + select to_char(sysdate,'Dy Mon dd hh24:mi:ss yyyy')||chr(10)|| + 'Most recent full backup was '|| + extract(day from (systimestamp - completion_time))|| ' Days and '|| + extract(hour from (systimestamp - completion_time))|| ' hours ago.' +bulk collect into notes +from v$backup_set a +where completion_time= + (select max(completion_time) + from v$backup_set + where nvl(incremental_level,10) = + nvl(a.incremental_level,10) and + backup_type = a.backup_type) and + backup_type='D' and + incremental_level is null and + sysdate - completion_time > THRESHOLD; + +-- If there is a message to send, then send it. +if notes.last > 0 then + notification.notify(instance_name_in => p_instance_name_in, + msgs_in => notes, + subject_in => 'BACKUPS', + email_p => false, + db_p => true); +end if; +end; + + +-- Check free space in archive destination +procedure checkArchiveDestination (p_instance_name_in in varchar2) +is +-- check the space used in the archive1 destination +-- (threshold 80%) +THRESHOLD number(4,2):= 80.0; +notes notification.msgs; +begin +-- build a message identifying the destination(s) that is atleast 80% full +select to_char(sysdate,'Dy Mon dd hh24:mi:ss yyyy')||chr(10)|| + 'Archive: '||dest_name||' '||destination|| + ' is '|| + to_char(round(1 - (quota_size-quota_used)/(quota_size),4)*100 )|| + '% full.' +bulk collect into notes +from v$archive_dest +where round(1 - (quota_size-quota_used)/(quota_size),4)*100 > THRESHOLD + and schedule = 'ACTIVE'; + +-- if the previous query found any rows, the messages will be contained +-- in the notes array. If the array is not empty send an email +if notes.last > 0 then + notification.notify(instance_name_in => p_instance_name_in, + msgs_in => notes, + subject_in => 'ARCHIVE', + email_p => true, + db_p => true); +end if; +end; + +procedure checkFreeSpace (p_instance_name_in in varchar2) +is + +-- Check spaced used by tablespaces +THRESHOLD number(4,2):= 80.0; +notes notification.msgs; +begin +-- build a message after checking the free space and the used +-- space if the used space is greater than the threshold + select to_char(sysdate,'Dy Mon dd hh24:mi:ss yyyy')||chr(10)|| + 'Tablespace '||a.tablespace_name|| + ' is '|| + to_char(round(1 - (free+potential)/(allocated+potential),4)*100)|| + '% full.' +bulk collect into notes +from + (select tablespace_name,sum(bytes) free + from dba_free_space + group by tablespace_name) f, + (select tablespace_name,sum(bytes) allocated, + sum(maxbytes) potential + from dba_data_files + group by tablespace_name) a +where a.tablespace_name = f.tablespace_name (+) and + round(1 - (free+potential)/(allocated+potential),4)*100 + > THRESHOLD; + +-- If there are any rows retrieved by the above query then +-- send a notification +if notes.last > 0 then + notification.notify(instance_name_in => p_instance_name_in, + msgs_in => notes, + subject_in => 'STORAGE', + email_p => false, + db_p => true); +end if; +end; +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_spec.sql b/2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_spec.sql new file mode 100755 index 0000000..a3770d7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch07/proactive_db_pkg_spec.sql @@ -0,0 +1,19 @@ +create or replace +package proactive +is +/** +* ======================================================================== +* Project: Database monitoring +* Description: This is the package for procedures the proactivly +* monitor the database. If there is a problem then we can +* email a notification and or save message in database +* DB impact: minimal +* Commit inside: no +* Rollback inside: no +* ------------------------------------------------------------------------ +*/ +procedure checkStatusOfLastBackup (p_instance_name_in in varchar2); +procedure checkArchiveDestination (p_instance_name_in in varchar2); +procedure checkFreeSpace (p_instance_name_in in varchar2); +end; +/ \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch08/my_proc_wrap_demo.sql b/2174_MasteringPLSQL_CODE/Ch08/my_proc_wrap_demo.sql new file mode 100755 index 0000000..23bdd4f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/my_proc_wrap_demo.sql @@ -0,0 +1,9 @@ +create or replace procedure MY_PROC + as + v_local_var varchar2(30) := 'This is a secret string'; + begin + -- here is the source code. it is + -- beneficial if users can’t see the source code. + null; -- this is the sensitive part + end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch08/page417.sql b/2174_MasteringPLSQL_CODE/Ch08/page417.sql new file mode 100755 index 0000000..eef4d60 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page417.sql @@ -0,0 +1,25 @@ +conn system/manager +set serveroutput on +declare + l_module varchar2(48); +begin + select b.module into l_module + from v$session b + where b.audsid = sys_context('userenv','sessionid'); + dbms_output.put_line('Current Program is ' || l_module); +end; +/ + +create or replace function get_my_program + return varchar2 +as + l_module varchar2(48); +begin + select b.module into l_module + from v$session b + where b.audsid = sys_context('userenv','sessionid'); + return l_module; +end; +/ +drop function get_my_program; +show errors diff --git a/2174_MasteringPLSQL_CODE/Ch08/page418.sql b/2174_MasteringPLSQL_CODE/Ch08/page418.sql new file mode 100755 index 0000000..b4ad7cd --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page418.sql @@ -0,0 +1,17 @@ +conn system/manager +-- show roles +select * from session_roles; +-- show roles in a procedure +create or replace procedure show_privs +as +begin + dbms_output.put_line('ROLES:'); + for rec in (select * from session_roles) + loop + dbms_output.put_line(rec.role); + end loop; +end; +/ +set serveroutput on +exec show_privs +drop procedure show_privs; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page419.sql b/2174_MasteringPLSQL_CODE/Ch08/page419.sql new file mode 100755 index 0000000..73cebe0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page419.sql @@ -0,0 +1,17 @@ +conn system/manager +create or replace function get_my_program +return varchar2 +authid current_user +as + l_module varchar2(48); + l_query varchar2(500); +begin + l_query := 'select b.module ' || + 'from v$session b ' || + 'where b.audsid = sys_context(''userenv'',''sessionid'')'; + execute immediate l_query into l_module; + return l_module; +end; +/ +select get_my_program from dual; +drop function get_my_program; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page421.sql b/2174_MasteringPLSQL_CODE/Ch08/page421.sql new file mode 100755 index 0000000..9e20f1e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page421.sql @@ -0,0 +1,26 @@ +conn system/manager +create user blake identified by blake + default tablespace users temporary tablespace temp; +grant create session, create procedure, + create table, unlimited tablespace to blake; + +conn scott/tiger +CREATE PROCEDURE update_sal (p_empno in number, + p_sal in number) +AS +BEGIN + /* + * Could have done data and/or security checking: + * Examples: + * p_sal > sal; + * updating during "normal" operating hours; + * user executing procedure is updating just + * their salary; + */ + update EMP set sal = p_sal where empno = p_empno; +END; +/ + +grant execute on update_sal to blake; +-- let user see the data +grant select on EMP to blake; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page423.sql b/2174_MasteringPLSQL_CODE/Ch08/page423.sql new file mode 100755 index 0000000..6f76e5b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page423.sql @@ -0,0 +1,13 @@ +-- test as blake (recreated for this example) +connect blake/blake +-- show data +select ename, empno, sal from SCOTT.EMP where ename = USER; +-- show direct updates don't work +update SCOTT.emp set sal = sal * 1.1; +-- show procedure invocation works +execute SCOTT.update_sal(p_empno => 7698, p_sal => 3000) +-- show data +select ename, empno, sal from SCOTT.EMP where ename = USER; + +conn scott/tiger +drop procedure update_sal; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page424.sql b/2174_MasteringPLSQL_CODE/Ch08/page424.sql new file mode 100755 index 0000000..1f41eda --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page424.sql @@ -0,0 +1,3 @@ +connect blake/blake +select ename from emp where ename like 'B%'; +select ename from SCOTT.EMP where ename like 'B%'; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page426.sql b/2174_MasteringPLSQL_CODE/Ch08/page426.sql new file mode 100755 index 0000000..753678b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page426.sql @@ -0,0 +1,14 @@ +conn scott/tiger +create or replace procedure show_privs + authid current_user + as + begin + dbms_output.put_line('ROLES:'); + for rec in (select * from session_roles) + loop + dbms_output.put_line(rec.role); + end loop; + end; + / +execute show_privs +drop procedure show_privs; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page427.sql b/2174_MasteringPLSQL_CODE/Ch08/page427.sql new file mode 100755 index 0000000..efdd4e7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page427.sql @@ -0,0 +1,31 @@ +conn system/manager +create role emp_update; +grant update on SCOTT.EMP to emp_update; +grant emp_update to blake; + +conn blake/blake +CREATE or replace PROCEDURE update_sal (p_empno in number, p_sal in number) + authid current_user + AS + BEGIN + update SCOTT.EMP set sal = p_sal where empno = p_empno; + END; + / +sho errors +CREATE OR REPLACE procedure update_sal +( +p_empno in number, +p_sal in number +) +authid current_user +as +begin + execute immediate 'update SCOTT.EMP set ' || + 'sal = :x ' || + 'where empno = :y' using p_sal, p_empno; +end; +/ + +exec update_sal (7698,5000); +select ename, empno, sal from SCOTT.EMP where ename = USER; +drop procedure update_sal; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page428.sql b/2174_MasteringPLSQL_CODE/Ch08/page428.sql new file mode 100755 index 0000000..1cdb86e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page428.sql @@ -0,0 +1,16 @@ +connect blake/blake +-- create template EMP table +create table EMP as select * from SCOTT.EMP where 1=2; +CREATE OR REPLACE PROCEDURE update_sal +( +p_empno in number, +p_sal in number +) +authid current_user +AS +BEGIN +update EMP set sal = p_sal where empno = p_empno; + END; + / + +drop procedure update_sal; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page432.sql b/2174_MasteringPLSQL_CODE/Ch08/page432.sql new file mode 100755 index 0000000..965bdb9 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page432.sql @@ -0,0 +1,15 @@ +conn scott/tiger +CREATE OR REPLACE package sample_package +as + pv_this_is_public varchar2(6) := 'Hello'; + function a_function return varchar2; + procedure a_procedure; +end; +/ + +describe sample_package + +col text format a70 +select text from user_source + where name = 'SAMPLE_PACKAGE'; +drop package sample_package; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page434.sql b/2174_MasteringPLSQL_CODE/Ch08/page434.sql new file mode 100755 index 0000000..9897dc2 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page434.sql @@ -0,0 +1,96 @@ +connect system/manager +create user alpha identified by a; +create user beta identified by b; + +conn scott/tiger +create or replace package alpha_package +as + PROCEDURE P1; + PROCEDURE P2; + PROCEDURE P3; + FUNCTION F1 return number; + FUNCTION F2 return number; +end; +/ +grant execute on alpha_package to alpha; + +create or replace package beta_package +as + PROCEDURE P3; + PROCEDURE P4; + PROCEDURE P5; + FUNCTION F1 return number; + FUNCTION F3 return number; +end; +/ +grant execute on beta_package to beta; + +create or replace package body beta_package +as + PROCEDURE P3 + as + begin + ALPHA_PACKAGE.P3; + end; + + FUNCTION F1 return number + as + begin + return ALPHA_PACKAGE.F1; + end; + + PROCEDURE P4 + as + begin + null; + end; + + PROCEDURE P5 + as + begin + null; + end; + + FUNCTION F3 return number + as + begin + return 1; + end; +end; +/ + +create or replace package body alpha_package +as + PROCEDURE P1 + as + begin + null; + end; + + PROCEDURE P2 + as + begin + null; + end; + + PROCEDURE P3 + as + begin + null; + end; + + FUNCTION F1 return number + as + begin + return 1; + end; + + FUNCTION F2 return number + as + begin + return 1; + end; +end; +/ + +-- clean up on page436.sql diff --git a/2174_MasteringPLSQL_CODE/Ch08/page436.sql b/2174_MasteringPLSQL_CODE/Ch08/page436.sql new file mode 100755 index 0000000..a232f3a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page436.sql @@ -0,0 +1,8 @@ +conn system/manager +audit execute on scott.beta_package by access; + +noaudit execute on scott.beta_package; +drop package scott.alpha_package; +drop package scott.beta_package; +drop user alpha; +drop user beta; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page441.sql b/2174_MasteringPLSQL_CODE/Ch08/page441.sql new file mode 100755 index 0000000..702e28a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page441.sql @@ -0,0 +1,9 @@ + + +

+ + + +
+ + \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch08/page442.sql b/2174_MasteringPLSQL_CODE/Ch08/page442.sql new file mode 100755 index 0000000..bdd2116 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page442.sql @@ -0,0 +1,31 @@ +conn scott/tiger +create table user_info +( +username varchar2(30) constraint user_info_pk primary key, +image_url varchar2(2000) +) +/ +insert into user_info values +('SCOTT','http://imageserver.company.com/img/scott.gif'); +insert into user_info values +('BLAKE','http://imageserver.company.com/img/blake.gif'); +commit; + +CREATE OR REPLACE TRIGGER user_img_update_check +BEFORE UPDATE OF image_url +ON user_info +FOR EACH ROW +DECLARE +BEGIN +IF (sys_context('USERENV','SESSION_USER') != :new.username) +then +raise_application_error(-20001,'Unauthorized update!'); +END IF; +END; +/ + +update user_info + set image_url = 'http://funnypictures.com/img/tomCrusie.jpg' + where username = 'SCOTT'; +commit; + \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch08/page443.sql b/2174_MasteringPLSQL_CODE/Ch08/page443.sql new file mode 100755 index 0000000..015aa11 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page443.sql @@ -0,0 +1,79 @@ +conn scott/tiger +-- trigger raises errors for session user SCOTT +update user_info + set image_url = 'http://funnypictures.com/img/chewbacca.lg.jpg' + where username = 'BLAKE'; + +-- support procedure for notifications by email +create or replace +PROCEDURE send_mail ( + p_to IN VARCHAR2, + p_from IN VARCHAR2 default 'DB Alert', + p_cc IN VARCHAR2 DEFAULT NULL, + p_bcc IN VARCHAR2 DEFAULT NULL, + p_subject IN VARCHAR2 default 'DB Notification', + p_message IN VARCHAR2 + ) + IS + v_mailhost VARCHAR2(30) := '^2'; + v_mail_conn utl_smtp.connection; + BEGIN + v_mail_conn := utl_smtp.open_connection (v_mailhost, 25); + utl_smtp.helo (v_mail_conn, v_mailhost); + utl_smtp.mail (v_mail_conn, p_from); + utl_smtp.rcpt (v_mail_conn, p_to); + utl_smtp.data ( + v_mail_conn, + 'bcc: ' || + p_bcc || + utl_tcp.crlf || + 'Subject: ' || + p_subject || + utl_tcp.crlf || + 'To: ' || + p_to || + utl_tcp.crlf || + 'cc: ' || + p_cc || + utl_tcp.crlf || + p_message + ); + utl_smtp.quit (v_mail_conn); + EXCEPTION + WHEN utl_smtp.transient_error OR utl_smtp.permanent_error + THEN + utl_smtp.quit (v_mail_conn); + raise_application_error ( + -20000, + 'Failed to send mail due to the following error: ' || SQLERRM + ); + WHEN OTHERS + THEN + utl_smtp.quit (v_mail_conn); + raise_application_error ( + -20000, + 'Failed to send mail due to the following error: ' || SQLERRM + ); + END; +/ + +CREATE OR REPLACE TRIGGER user_img_update_check +BEFORE UPDATE OF image_url +ON user_info +FOR EACH ROW +DECLARE + v_notification_msg varchar2(1000); +BEGIN + IF (sys_context('USERENV','SESSION_USER') != :new.username) + then + v_notification_msg := 'Unauthorized update to image URL from ' || + sys_context('USERENV','SESSION_USER') || + ' on ' || :new.username; + send_mail(p_to=>'securityAdmin.yourCompany.com', + p_message=>v_notification_msg); + raise_application_error(-20001,'Unauthorized update!'); + END IF; +END; +/ + +drop table user_info; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page444.sql b/2174_MasteringPLSQL_CODE/Ch08/page444.sql new file mode 100755 index 0000000..af14354 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page444.sql @@ -0,0 +1,52 @@ +conn blake/blake +update scott.emp set sal = 0 + where sal > + (select sal from scott.emp + where ename = 'BLAKE'); +-- cover trail +rollback; + +conn scott/tiger +create table aud_emp_tab ( + username varchar2(30), + action varchar2(6), + column_name varchar2(255), + empno number(4), + old_value number, + new_value number, + action_date date + ) +/ + +CREATE OR REPLACE TRIGGER aud_emp + BEFORE UPDATE OF SAL + ON EMP + FOR EACH ROW + +DECLARE +PRAGMA AUTONOMOUS_TRANSACTION; + +BEGIN + INSERT into aud_emp_tab + values (sys_context('USERENV','SESSION_USER'), + 'UPDATE', + 'SAL', + :old.empno, + :old.sal, + :new.sal, + SYSDATE ); + COMMIT; +END; +/ +grant update(sal) on emp to blake; +conn blake/blake +update SCOTT.EMP set sal = 5000 where empno=7698; +-- cover trail +rollback; + +conn scott/tiger +col username format a8 +col column_name format a12 +select username, empno, old_value, new_value, + to_char(action_date, 'Mon-DD-YYYY HH24:MI:SS') Time + from aud_emp_tab; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page447.sql b/2174_MasteringPLSQL_CODE/Ch08/page447.sql new file mode 100755 index 0000000..92dfbe3 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page447.sql @@ -0,0 +1,32 @@ +conn system/manager +begin + DBMS_FGA.ADD_POLICY(object_schema => 'SCOTT', + object_name=>'EMP', + policy_name => 'EMP_INS_UPD', + audit_condition => '1=1', + audit_column =>'SAL', + handler_schema => NULL, + handler_module => NULL, + enable => TRUE, + statement_types=> 'INSERT,UPDATE'); +end; +/ + +conn blake/blake +update SCOTT.EMP set sal = 5000 where empno=7698; +-- cover trail +rollback; + +conn system/manager +col db_user format a6 +col schema format a6 +col object format a4 +col SQL_TEXT format a50 + +select db_user, statement_type action, + object_schema schema, object_name object, + to_char(timestamp, 'Mon-DD-YYYY HH24:MI:SS') Time, + SQL_TEXT + FROM sys.dba_fga_audit_trail; + +drop table scott.aud_emp_tab; diff --git a/2174_MasteringPLSQL_CODE/Ch08/page449.sql b/2174_MasteringPLSQL_CODE/Ch08/page449.sql new file mode 100755 index 0000000..5539aa9 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page449.sql @@ -0,0 +1,14 @@ +conn sys/oracle as sysdba +create or replace trigger set_client_id +after logon on database +DECLARE + l_module v$session.module%type; +BEGIN + select upper(module) into l_module + from v$session b + where b.audsid = userenv('sessionid'); + dbms_session.set_identifier(sys_context('userenv','ip_address') + ||':' || + nvl(l_module,'No Module Specified')); + END; + / \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch08/page450.sql b/2174_MasteringPLSQL_CODE/Ch08/page450.sql new file mode 100755 index 0000000..27739c0 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page450.sql @@ -0,0 +1,15 @@ +conn system/manager + +begin + DBMS_FGA.ADD_POLICY(object_schema => 'SCOTT', + object_name => 'EMP', + policy_name => 'EMP_TRIG_AUD', + audit_condition => '1=1', + audit_column => NULL, + handler_schema => NULL, + handler_module => NULL, + enable => TRUE, + statement_types => 'SELECT,INSERT,UPDATE,DELETE'); + end; + / + \ No newline at end of file diff --git a/2174_MasteringPLSQL_CODE/Ch08/page451.sql b/2174_MasteringPLSQL_CODE/Ch08/page451.sql new file mode 100755 index 0000000..d7e9ef7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page451.sql @@ -0,0 +1,14 @@ +conn system/manager +set serveroutput on +declare +l_aud_str varchar2(256); +begin + l_aud_str := 'select db_user, client_id, ' || + 'userhost, substr(sql_text,1,50) SQL, '|| + 'timestamp day, to_char(timestamp,''HH24:MI:SS'') time ' || + 'from sys.dba_fga_audit_trail ' || + 'where object_schema = ''SCOTT'' and ' || + 'object_name = ''EMP'''; + print_table(l_aud_str); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch08/page452.sql b/2174_MasteringPLSQL_CODE/Ch08/page452.sql new file mode 100755 index 0000000..cef455a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page452.sql @@ -0,0 +1,15 @@ +connect sys/oracle as sysdba + +create or replace trigger user_logon_module_check + after logon on database +DECLARE + l_module v$session.module%type; +BEGIN + select upper(module) into l_module from v$session b + where b.audsid = userenv('sessionid'); + IF ( l_module = 'EXCEL.EXE' OR + l_module = 'MSQRY32.EXE') THEN + raise_application_error(-20001,'Unauthorized Application'); + END IF; +END; +/ diff --git a/2174_MasteringPLSQL_CODE/Ch08/page455.sql b/2174_MasteringPLSQL_CODE/Ch08/page455.sql new file mode 100755 index 0000000..3b5a70e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/page455.sql @@ -0,0 +1,27 @@ +conn scott/tiger +create or replace procedure MY_SECRET_PROC + as + v_local_var varchar2(30) := 'This is a secret string'; + begin + -- here is the source code. it is + -- beneficial if users can’t see the source code. + null; -- this is the sensitive part + end; +/ + +create or replace procedure MY_PROC + as + begin + MY_SECRET_PROC; -- call the real code + end; +/ +grant execute on my_proc to blake; +conn blake/blake +exec scott.my_proc +col text format a65 +select text from all_source where name='MY_PROC' order by line; +select text from all_source where name='MY_SECRET_PROC' order by line; + +conn scott/tiger +drop procedure MY_PROC; +drop procedure MY_SECRET_PROC; diff --git a/2174_MasteringPLSQL_CODE/Ch08/pgae454.sql b/2174_MasteringPLSQL_CODE/Ch08/pgae454.sql new file mode 100755 index 0000000..fef447a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch08/pgae454.sql @@ -0,0 +1,19 @@ +conn scott/tiger +create or replace procedure MY_PROC + as + v_local_var varchar2(30) := 'This is a secret string'; + begin + -- here is the source code. it is + -- beneficial if users can’t see the source code. + null; -- this is the sensitive part + end; +/ +grant execute on my_proc to blake; + +conn blake/blake +exec scott.my_proc +col text format a65 +select text from all_source where name='MY_PROC' order by line; + +conn scott/tiger +drop procedure my_proc; diff --git a/2174_MasteringPLSQL_CODE/Ch10/debug.pkh b/2174_MasteringPLSQL_CODE/Ch10/debug.pkh new file mode 100755 index 0000000..a771282 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch10/debug.pkh @@ -0,0 +1,56 @@ +create or replace +package debug as + + -- + -- Type Definitions + -- + + type Argv is table of varchar2(4000); + emptyDebugArgv Argv; + + -- + -- Initializes the debuging for specified p_modules and will dump the + -- output to the p_dir directory on the server for the user p_user. + -- + procedure init( + p_modules in varchar2 default 'ALL', + p_dir in varchar2 default 'TEMP', + p_file in varchar2 default user || '.dbg', + p_user in varchar2 default user, + p_show_date in varchar2 default 'YES', + p_date_format in varchar2 default 'MMDDYYYY HH24MISS', + p_name_len in number default 30, + p_show_sesid in varchar2 default 'NO' ); + + procedure status( + p_user in varchar2 default user, + p_dir in varchar2 default null, + p_file in varchar2 default null ); + + procedure f( + p_message in varchar2, + p_arg1 in varchar2 default null, + p_arg2 in varchar2 default null, + p_arg3 in varchar2 default null, + p_arg4 in varchar2 default null, + p_arg5 in varchar2 default null, + p_arg6 in varchar2 default null, + p_arg7 in varchar2 default null, + p_arg8 in varchar2 default null, + p_arg9 in varchar2 default null, + p_arg10 in varchar2 default null ); + + procedure fa( + p_message in varchar2, + p_args in Argv default emptyDebugArgv ); + + procedure clear( + p_user in varchar2 default user, + p_dir in varchar2 default null, + p_file in varchar2 default null ); + +end debug; +/ + +show error + diff --git a/2174_MasteringPLSQL_CODE/Ch10/debug.sql b/2174_MasteringPLSQL_CODE/Ch10/debug.sql new file mode 100755 index 0000000..0f75d68 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch10/debug.sql @@ -0,0 +1,417 @@ +create or replace +package body debug as + + g_session_id varchar2(2000); + + procedure who_called_me( + o_owner in out varchar2, + o_object out varchar2, + o_lineno out number ) is + -- + l_call_stack long default dbms_utility.format_call_stack; + l_line varchar2(4000); + begin + + /* + ----- PL/SQL Call Stack ----- + object line object + handle number name + 86c60290 17 package body OPS$CLBECK.DEBUG + 86c60290 212 package body OPS$CLBECK.DEBUG + 86c60290 251 package body OPS$CLBECK.DEBUG + 86aa28f0 1 procedure OPS$CLBECK.A + 86a9e940 1 anonymous block + */ + + -- skip three header lines and first levels in the stack + for i in 1 .. 6 loop + l_call_stack := substr( l_call_stack, instr( l_call_stack, chr(10) )+1 ); + end loop; + + -- set l_line to the current line + l_line := substr( l_call_stack, 1, instr( l_call_stack, chr(10) ) - 1 ); + + -- strip object handle + l_line := ltrim( substr( l_line, instr( l_line, ' ' ))); + + -- assign line number + o_lineno := to_number(substr( l_line, 1, instr( l_line, ' ' ))); + l_line := ltrim( substr( l_line, instr( l_line, ' ' ))); + + -- strip out object type + l_line := ltrim( substr( l_line, instr( l_line, ' ' ))); + + -- if 'package body' or 'anonymous block', strip out second piece + if l_line like 'block%' or + l_line like 'body%' then + l_line := ltrim( substr( l_line, instr( l_line, ' ' ))); + end if; + + -- assign owner and object name + o_owner := ltrim(rtrim(substr( l_line, 1, instr( l_line, '.' )-1 ))); + o_object := ltrim(rtrim(substr( l_line, instr( l_line, '.' )+1 ))); + + if o_owner is null then + o_owner := user; + o_object := 'ANONYMOUS BLOCK'; + end if; + + end who_called_me; + + function parse_it( + p_message in varchar2, + p_argv in argv, + p_header_length in number ) return varchar2 is + -- + l_message long := null; + l_str long := p_message; + l_idx number := 1; + l_ptr number := 1; + begin + + if nvl( instr( p_message, '%' ), 0 ) = 0 and + nvl( instr( p_message, '\' ), 0 ) = 0 then + return p_message; + end if; + + loop + + l_ptr := instr( l_str, '%' ); + exit when l_ptr = 0 or l_ptr is null; + l_message := l_message || substr( l_str, 1, l_ptr-1 ); + l_str := substr( l_str, l_ptr+1 ); + + if substr( l_str, 1, 1 ) = 's' then + l_message := l_message || p_argv(l_idx); + l_idx := l_idx + 1; + l_str := substr( l_str, 2 ); + + elsif substr( l_str,1,1 ) = '%' then + l_message := l_message || '%'; + l_str := substr( l_str, 2 ); + + else + l_message := l_message || '%'; + end if; + + end loop; + + l_str := l_message || l_str; + l_message := null; + + loop + + l_ptr := instr( l_str, '\' ); + exit when l_ptr = 0 or l_ptr is null; + l_message := l_message || substr( l_str, 1, l_ptr-1 ); + l_str := substr( l_str, l_ptr+1 ); + + if substr( l_str, 1, 1 ) = 'n' then + l_message := l_message || chr(10) || + rpad( ' ', p_header_length, ' ' ); + l_str := substr( l_str, 2 ); + + elsif substr( l_str, 1, 1 ) = 't' then + l_message := l_message || chr(9); + l_str := substr( l_str, 2 ); + + elsif substr( l_str, 1, 1 ) = '\' then + l_message := l_message || '\'; + l_str := substr( l_str, 2 ); + + else + l_message := l_message || '\'; + end if; + + end loop; + + return l_message || l_str; + + end parse_it; + + + function build_it( + p_debug_row in debugTab%rowtype, + p_owner in varchar2, + p_object in varchar2, + p_lineno number ) return varchar2 is + -- + l_header long := null; + begin + + if p_debug_row.show_session_id = 'YES' then + l_header := g_session_id || ' - '; + end if; + + if p_debug_row.show_date = 'YES' then + l_header := l_header || + to_char( sysdate, + nvl( p_debug_row.date_format, + 'MMDDYYYY HH24MISS' ) ); + end if; + + l_header := + l_header || + '(' || + lpad( substr( p_owner || '.' || p_object, + greatest( 1, length( p_owner || '.' || p_object ) - + least( p_debug_row.name_length, 61 ) + 1 ) ), + least( p_debug_row.name_length, 61 ) ) || + lpad( p_lineno,5 ) || + ') '; + + return l_header; + + end build_it; + + + function file_it( + p_dir in debugtab.dir%type, + p_file in debugtab.filename%type, + p_message in varchar2 ) return boolean is + -- + l_handle utl_file.file_type; + --l_file long; + --l_location long; + begin + + --l_file := substr( p_file, + --instr( replace( p_file, '\', '/' ), + --'/', -1 )+1 ); + + --l_location := substr( p_file, + --1, + --instr( replace( p_file, '\', '/' ), + --'/', -1 )-1 ); + + l_handle := utl_file.fopen( + location => p_dir, + filename => p_file, + open_mode => 'a', + max_linesize => 32767 ); + + utl_file.put( l_handle, '' ); + utl_file.put_line( l_handle, p_message ); + utl_file.fclose( l_handle ); + + return true; + + exception + when others then + if utl_file.is_open( l_handle ) then + utl_file.fclose( l_handle ); + end if; + + return false; + + end file_it; + + + procedure debug_it( + p_message in varchar2, + p_argv in argv ) is + -- + l_message long := null; + l_header long := null; + call_who_called_me boolean := true; + l_owner varchar2(255); + l_object varchar2(255); + l_lineno number; + l_dummy boolean; + begin + + for c in ( select * + from debugtab + where userid = user ) + loop + + if call_who_called_me then + who_called_me( l_owner, l_object, l_lineno ); + call_who_called_me := false; + end if; + + if instr( ',' || c.modules || ',', + ',' || l_object || ',' ) <> 0 or + c.modules = 'ALL' + then + + l_header := build_it( c, l_owner, l_object, l_lineno ); + l_message := parse_it( p_message, p_argv, length(l_header) ); + l_dummy := file_it( c.dir, c.filename, l_header || l_message ); + + end if; + end loop; + + end debug_it; + + + -- + -- Public Procedures/Functions + -- + + procedure fa( + p_message in varchar2, + p_args in Argv default emptyDebugArgv ) is + begin + debug_it( p_message, p_args ); + end fa; + + procedure f( + p_message in varchar2, + p_arg1 in varchar2 default null, + p_arg2 in varchar2 default null, + p_arg3 in varchar2 default null, + p_arg4 in varchar2 default null, + p_arg5 in varchar2 default null, + p_arg6 in varchar2 default null, + p_arg7 in varchar2 default null, + p_arg8 in varchar2 default null, + p_arg9 in varchar2 default null, + p_arg10 in varchar2 default null ) is + begin + debug_it( p_message, + argv( substr( p_arg1, 1, 4000 ), + substr( p_arg2, 1, 4000 ), + substr( p_arg3, 1, 4000 ), + substr( p_arg4, 1, 4000 ), + substr( p_arg5, 1, 4000 ), + substr( p_arg6, 1, 4000 ), + substr( p_arg7, 1, 4000 ), + substr( p_arg8, 1, 4000 ), + substr( p_arg9, 1, 4000 ), + substr( p_arg10, 1, 4000 ) ) ); + end f; + + + procedure status( + p_user in varchar2 default user, + p_dir in varchar2 default null, + p_file in varchar2 default null ) is + -- + l_found boolean := false; + begin + + dbms_output.put_line( chr(10) ); + dbms_output.put_line( 'Debug info for ' || + p_user ); + for c in ( select * + from debugtab + where userid = p_user + and nvl( p_file, filename ) = filename + and nvl( p_dir, dir ) = dir ) + loop + dbms_output.put_line( '---------------' || + rpad( '-', length( p_user ), '-' ) ); + l_found := true; + dbms_output.put_line( 'USER: ' || + c.userid ); + dbms_output.put_line( 'MODULES: ' || + c.modules ); + dbms_output.put_line( 'DIRECTORY: ' || + c.dir ); + dbms_output.put_line( 'FILENAME: ' || + c.filename ); + dbms_output.put_line( 'SHOW DATE: ' || + c.show_date ); + dbms_output.put_line( 'DATE FORMAT: ' || + c.date_format ); + dbms_output.put_line( 'NAME LENGTH: ' || + c.name_length ); + dbms_output.put_line( 'SHOW SESSION ID: ' || + c.show_session_id ); + dbms_output.put_line( ' ' ); + end loop; + + if not l_found then + dbms_output.put_line( 'No debug setup.' ); + end if; + + end status; + + + procedure clear( p_user in varchar2 default user, + p_dir in varchar2 default null, + p_file in varchar2 default null ) is + pragma autonomous_transaction; + begin + delete from debugTab + where userid = p_user + and filename = nvl( p_file, filename ) + and dir = nvl( p_dir, dir ); + commit; + end clear; + + + procedure init( + p_modules in varchar2 default 'ALL', + p_dir in varchar2 default 'TEMP', + p_file in varchar2 default user || '.dbg', + p_user in varchar2 default user, + p_show_date in varchar2 default 'YES', + p_date_format in varchar2 default 'MMDDYYYY HH24MISS', + p_name_len in number default 30, + p_show_sesid in varchar2 default 'NO' ) is + -- + pragma autonomous_transaction; + debugTab_rec debugTab%rowtype; + l_message long; + begin + + delete from debugTab + where userid = p_user + and filename = p_file; + + insert into debugTab( + userid, modules, dir, filename, show_date, + date_format, name_length, show_session_id ) + values ( + p_user, p_modules, p_dir, p_file, p_show_date, + p_date_format, p_name_len, p_show_sesid ) + returning + userid, modules, dir, filename, show_date, + date_format, name_length, show_session_id + into + debugTab_rec.userid, debugTab_rec.modules, debugTab_rec.dir, + debugTab_rec.filename, debugTab_rec.show_date, + debugTab_rec.date_format, debugTab_rec.name_length, + debugTab_rec.show_session_id; + + l_message := chr(10) || 'Debug parameters initialized on ' || + to_char( sysdate, 'dd-MON-yyyy hh24:mi:ss' ) || chr(10); + l_message := l_message || ' USER: ' || + debugTab_rec.userid || chr(10); + l_message := l_message || ' MODULES: ' || + debugTab_rec.modules || chr(10); + l_message := l_message || ' DIRECTORY: ' || + debugTab_rec.dir || chr(10); + l_message := l_message || ' FILENAME: ' || + debugTab_rec.filename || chr(10); + l_message := l_message || ' SHOW DATE: ' || + debugTab_rec.show_date || chr(10); + l_message := l_message || ' DATE FORMAT: ' || + debugTab_rec.date_format || chr(10); + l_message := l_message || ' NAME LENGTH: ' || + debugTab_rec.name_length || chr(10); + l_message := l_message || 'SHOW SESSION ID: ' || + debugTab_rec.show_session_id || chr(10); + + if not file_it( debugTab_rec.dir, debugTab_rec.filename, l_message ) then + rollback; + raise_application_error( + -20001, + 'Can not open directory - file: ' || + debugTab_rec.dir || ' - ' || debugTab_rec.filename ); + end if; + + commit; + + end init; + +begin + g_session_id := userenv('SESSIONID'); +end debug; +/ + +show error + + diff --git a/2174_MasteringPLSQL_CODE/Ch10/debug_ddl.sql b/2174_MasteringPLSQL_CODE/Ch10/debug_ddl.sql new file mode 100755 index 0000000..437c239 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/Ch10/debug_ddl.sql @@ -0,0 +1,77 @@ +drop table debugTab +/ + +create table debugTab( + userid varchar2(30), + dir varchar2(32), + filename varchar2(1024), + modules varchar2(4000), + show_date varchar2(3), + date_format varchar2(255), + name_length number, + show_session_id varchar2(3), + -- + -- Constraints + -- + constraint debugtab_pk + primary key ( userid, filename ), + constraint debugtab_show_date_ck + check ( show_date in ( 'YES', 'NO' ) ), + constraint debugtab_show_session_id_ck + check ( show_session_id in ( 'YES', 'NO' ) ) +) +/ + +create or replace +trigger biu_fer_debugtab +before insert or update on debugtab for each row +begin + + :new.modules := upper( :new.modules ); + :new.show_date := upper( :new.show_date ); + :new.show_session_id := upper( :new.show_session_id ); + :new.userid := upper( :new.userid ); + + declare + l_date varchar2(100); + begin + l_date := to_char( sysdate, :new.date_format ); + exception + when others then + raise_application_error( + -20001, + 'Invalid date format "' || + :new.date_format || '"' ); + end; + + declare + l_handle utl_file.file_type; + --l_file varchar2(32767); + --l_location varchar2(23767); + begin + --l_file := substr( :new.filename, + --instr( replace( :new.filename, '\', '/' ), + --'/', -1 )+1 ); + --l_location := substr( :new.filename, + --1, + --instr( replace( :new.filename, '\', '/' ), + --'/', -1 )-1 ); + l_handle := utl_file.fopen( + location => :new.dir, + filename => :new.filename, + open_mode => 'a', + max_linesize => 32767 ); + utl_file.fclose( l_handle ); + exception + when others then + raise_application_error( + -20001, + 'Cannot open debug dir/file ' || + :new.dir || '/' || + :new.filename ); + end; + +end; +/ + + diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-1.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-1.sql new file mode 100755 index 0000000..692f8e2 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-1.sql @@ -0,0 +1,14 @@ +create or replace procedure owainit +as + l_cgivar_name owa.vc_arr; + l_cgivar_val owa.vc_arr; +begin + htp.init; + l_cgivar_name(1) := 'REQUEST_PROTOCOL'; + l_cgivar_val(1) := 'HTTP'; + owa.init_cgi_env( + num_params => 1, + param_name => l_cgivar_name, + param_val => l_cgivar_val ); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-10.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-10.sql new file mode 100755 index 0000000..98f96fb --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-10.sql @@ -0,0 +1,29 @@ +create or replace procedure my_doc_listing( p_name in varchar2 default null ) +as +begin + htp.htmlOpen; + htp.bodyOpen; + if p_name is not null then + htp.bold('Document ' || p_name || ' successfully uploaded!'); + end if; + htp.tableOpen; + htp.tableRowOpen; + htp.tableHeader('Name'); + htp.tableHeader('Size'); + htp.tableRowClose; + -- + for c1 in (select id, name, doc_size + from mydocs + order by name) loop + htp.tableRowOpen; + htp.tableData( c1.name ); + htp.tableData( c1.doc_size ); + htp.tableRowClose; + end loop; + -- + htp.tableClose; + htp.anchor('upload_doc','Upload a new document'); + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-11.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-11.sql new file mode 100755 index 0000000..2410c54 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-11.sql @@ -0,0 +1,16 @@ +create or replace procedure upload_doc +as +begin + htp.htmlOpen; + htp.bodyOpen; + htp.formOpen(curl => 'my_doc_listing', + cmethod => 'POST', + cenctype => 'multipart/form-data'); + -- No procedure provided in toolkit for file + htp.p(''); htp.formSubmit; + htp.formClose; + htp.anchor('my_doc_listing','Document listing'); + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-12.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-12.sql new file mode 100755 index 0000000..c2a5b21 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-12.sql @@ -0,0 +1,20 @@ +create or replace procedure get_file( p_id in number ) +as +begin + for c1 in (select mime_type, blob_content, name + from mydocs + where id = p_id) loop + -- + -- Setup the HTTP headers + -- + owa_util.mime_header( c1.mime_type, FALSE ); + htp.p('Content-length: ' || dbms_lob.getlength( c1.blob_content )); + htp.p('Content-Disposition: inline ' ); + owa_util.http_header_close; + -- Then give mod_plsql the BLOB content + wpg_docload.download_file( c1.blob_content ); + -- + exit; + end loop; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-13.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-13.sql new file mode 100755 index 0000000..d8bd68a --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-13.sql @@ -0,0 +1,29 @@ +create or replace procedure my_doc_listing( p_name in varchar2 default null ) +as +begin + htp.htmlOpen; + htp.bodyOpen; + if p_name is not null then + htp.bold('Document ' || p_name || ' successfully uploaded!'); + end if; + htp.tableOpen; + htp.tableRowOpen; + htp.tableHeader('Name'); + htp.tableHeader('Size'); + htp.tableRowClose; + -- + for c1 in (select id, name, doc_size + from mydocs + order by name) loop + htp.tableRowOpen; + htp.tableData( htf.anchor( 'get_file?p_id=' || c1.id, c1.name)); + htp.tableData( c1.doc_size ); + htp.tableRowClose; + end loop; + -- + htp.tableClose; + htp.anchor('upload_doc','Upload a new document'); + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-14.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-14.sql new file mode 100755 index 0000000..7111ace --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-14.sql @@ -0,0 +1,4 @@ +create table my_investments( + ticker varchar2(10) primary key, + name varchar2(4000) not null, + type varchar2(20) not null ); diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-15.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-15.sql new file mode 100755 index 0000000..0e6eab1 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-15.sql @@ -0,0 +1,32 @@ +create or replace procedure investment_rpt +as + l_count number := 0; +begin + htp.htmlOpen; + htp.bodyOpen; + htp.tableOpen; + htp.tableRowOpen; + htp.tableHeader('Ticker'); + htp.tableHeader('Name'); + htp.tableHeader('Type'); + htp.tableRowClose; + -- +-- Display information about each row in the my_investments table +-- + for c1 in (select ticker, name, type + from my_investments + order by ticker) loop + htp.tableRowOpen; + htp.tableData( c1.ticker ); + htp.tableData( c1.name ); + htp.tableData( c1.type ); + htp.tableRowClose; + l_count := l_count + 1; + end loop; + -- + htp.tableClose; + htp.p( l_count || ' rows found'); + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-16.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-16.sql new file mode 100755 index 0000000..b495efc --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-16.sql @@ -0,0 +1,45 @@ +create or replace procedure investment_modify +as + l_count number := 0; +begin + htp.htmlOpen; + htp.bodyOpen; + -- + -- Open an HTML form which will POST to our main reporting procedure + -- + htp.formOpen( curl => 'investment_rpt', cmethod => 'POST' ); + + htp.tableOpen; + -- + -- Generate a text field and label for each column in the table + -- + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Ticker:'); + htp.tableData( calign => 'LEFT', + cvalue => htf.formText( cname => 'p_ticker' )); + htp.tableRowClose; + + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Name:'); + htp.tableData( calign => 'LEFT', cvalue => htf.formText( cname => 'p_name' )); + htp.tableRowClose; + + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Type:'); + htp.tableData( calign => 'LEFT', cvalue => htf.formText( cname => 'p_type' )); + htp.tableRowClose; + + -- + -- Generate and HTML form submission button + -- + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', + cattributes => 'colspan="2"', + cvalue => htf.formSubmit(cvalue => 'Submit' )); + htp.tableRowClose; + + htp.formClose; + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-17.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-17.sql new file mode 100755 index 0000000..2f8850b --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-17.sql @@ -0,0 +1,92 @@ +create or replace procedure investment_rpt( + p_ticker in varchar2 default null, + p_name in varchar2 default null, + p_type in varchar2 default null, + p_action in varchar2 default 'DISPLAY' ) +as + l_count number := 0; +begin + if p_action = 'INSERT' then + insert into my_investments( ticker, name, type ) + values( p_ticker, p_name, p_type ); + commit; + end if; + + htp.htmlOpen; + htp.bodyOpen; + htp.tableOpen; + htp.tableRowOpen; + htp.tableHeader('Ticker'); + htp.tableHeader('Name'); + htp.tableHeader('Type'); + htp.tableRowClose; + -- + for c1 in (select ticker, name, type + from my_investments + order by ticker) loop + htp.tableRowOpen; + htp.tableData( c1.ticker ); + htp.tableData( c1.name ); + htp.tableData( c1.type ); + htp.tableRowClose; + l_count := l_count + 1; + end loop; + -- + htp.tableClose; + htp.p( l_count || ' rows found'); + htp.bodyClose; + htp.htmlClose; +end; +/ + +create or replace procedure investment_modify( + p_action in varchar2 default 'INSERT' ) +as + l_count number := 0; +begin + htp.htmlOpen; + htp.bodyOpen; + -- + -- Open an HTML form which will POST to our main reporting procedure + -- + htp.formOpen( curl => 'investment_rpt', cmethod => 'POST' ); + + -- + -- Include a hidden field to indicate our action when POSTed + -- + htp.formHidden ( cname=> 'p_action', cvalue=> p_action ); + + htp.tableOpen; + -- + -- Generate a text field and label for each column in the table + -- + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Ticker:'); + htp.tableData( calign => 'LEFT', + cvalue => htf.formText( cname => 'p_ticker' )); + htp.tableRowClose; + + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Name:'); + htp.tableData( calign => 'LEFT', cvalue => htf.formText( cname => 'p_name' )); + htp.tableRowClose; + + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Type:'); + htp.tableData( calign => 'LEFT', cvalue => htf.formText( cname => 'p_type' )); + htp.tableRowClose; + + -- + -- Generate and HTML form submission button + -- + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', + cattributes => 'colspan="2"', + cvalue => htf.formSubmit(cvalue => 'Submit' )); + htp.tableRowClose; + + htp.formClose; + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-18.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-18.sql new file mode 100755 index 0000000..b4e1226 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-18.sql @@ -0,0 +1,123 @@ +set define off +create or replace procedure investment_rpt( + p_ticker in varchar2 default null, + p_name in varchar2 default null, + p_type in varchar2 default null, + p_action in varchar2 default 'DISPLAY' ) +as + l_count number := 0; +begin + if p_action = 'INSERT' then + insert into my_investments( ticker, name, type ) + values( p_ticker, p_name, p_type ); + commit; + elsif p_action = 'UPDATE' then + update my_investments + set name = p_name, + type = p_type + where ticker = p_ticker; + commit; + end if; + + htp.htmlOpen; + htp.bodyOpen; + htp.tableOpen; + htp.tableRowOpen; + htp.tableHeader('Ticker'); + htp.tableHeader('Name'); + htp.tableHeader('Type'); + htp.tableRowClose; + -- + for c1 in (select ticker, name, type + from my_investments + order by ticker) loop + htp.tableRowOpen; + htp.tableData( + htf.anchor( + curl => 'investment_modify?p_action=UPDATE&p_ticker=' || c1.ticker, + ctext => c1.ticker) ); + htp.tableData( c1.name ); + htp.tableData( c1.type ); + htp.tableRowClose; + l_count := l_count + 1; + end loop; + -- + htp.tableClose; + htp.p( l_count || ' rows found'); + htp.br; + htp.anchor( curl => 'investment_modify?p_action=INSERT', + ctext => 'Create New' ); + htp.bodyClose; + htp.htmlClose; +end; +/ + +create or replace procedure investment_modify( + p_ticker in varchar2 default null, + p_action in varchar2 default 'INSERT' ) +as + l_count number := 0; + l_row my_investments%rowtype; +begin + -- + -- If the action is update, query the values to be + -- updated from the table + -- + if p_action = 'UPDATE' then + select * into l_row + from my_investments + where ticker = p_ticker; + end if; + htp.htmlOpen; + htp.bodyOpen; + + -- + -- Open an HTML form which will POST to our main reporting procedure + -- + htp.formOpen( curl => 'investment_rpt', cmethod => 'POST' ); + + -- + -- Include a hidden field to indicate our action when POSTed + -- + htp.formHidden ( cname=> 'p_action', cvalue=> p_action ); + + htp.tableOpen; + -- + -- Generate a text field and label for each column in the table + -- + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Ticker:'); + htp.tableData( + calign => 'LEFT', + cvalue => htf.formText( cname => 'p_ticker', + cvalue => l_row.ticker )); + htp.tableRowClose; + + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Name:'); + htp.tableData( + calign => 'LEFT', + cvalue => htf.formText( cname => 'p_name', cvalue => l_row.name )); + htp.tableRowClose; + + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', cvalue => 'Type:'); + htp.tableData( + calign => 'LEFT', + cvalue => htf.formText( cname => 'p_type', cvalue => l_row.type )); + htp.tableRowClose; + + -- + -- Generate and HTML form submission button + -- + htp.tableRowOpen; + htp.tableData( calign => 'RIGHT', + cattributes => 'colspan="2"', + cvalue => htf.formSubmit(cvalue => 'Submit' )); + htp.tableRowClose; + + htp.formClose; + htp.bodyClose; + htp.htmlClose; +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-19.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-19.sql new file mode 100755 index 0000000..5b8b006 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-19.sql @@ -0,0 +1,53 @@ +create or replace procedure temp_from_zip( p_zip in varchar2) +as + l_soap_envelope varchar2(4000); + l_http_request utl_http.req; + l_http_response utl_http.resp; + l_piece utl_http.html_pieces; + l_response varchar2(4000); + +begin + -- + -- Create a SOAP envelope containing the supplied ZIP parameter + -- + l_soap_envelope := ' + + + + '; + l_soap_envelope := l_soap_envelope || p_zip; + l_soap_envelope := l_soap_envelope || ' + + '; + + -- + -- Start a new request to the target SOAP server, and POSTing our request + -- + l_http_request := utl_http.begin_request( + url => 'http://services.xmethods.net:80/soap/servlet/rpcrouter', + method => 'POST' ); + utl_http.set_header(l_http_request, 'Content-Type', 'text/xml'); + utl_http.set_header(l_http_request, 'Content-Length', length(l_soap_envelope)); + utl_http.set_header(l_http_request, 'SOAPAction', 'getTempRequest'); + + -- + -- Write the envelope as part of the request + -- + utl_http.write_text(l_http_request, l_soap_envelope); + + -- + -- Immediately get the response from our request + -- + l_http_response := utl_http.get_response(l_http_request); + utl_http.read_text( l_http_response, l_response ); + utl_http.end_response(l_http_response); + htp.p( l_response ); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-2.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-2.sql new file mode 100755 index 0000000..9b46c0f --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-2.sql @@ -0,0 +1,10 @@ +set serveroutput on +exec owainit; + +begin + htp.p('Ohio State'); + htp.p('Buckeyes'); + end; +/ + +exec owa_util.showpage; diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-20.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-20.sql new file mode 100755 index 0000000..4115427 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-20.sql @@ -0,0 +1,62 @@ +drop procedure temp_from_zip +/ +create or replace function temp_from_zip( p_zip in varchar2) +return varchar2 +as + l_soap_envelope varchar2(4000); + l_http_request utl_http.req; + l_http_response utl_http.resp; + l_piece utl_http.html_pieces; + l_response varchar2(4000); + l_xml xmltype; +begin + -- + -- Create a SOAP envelope containing the supplied ZIP parameter + -- + l_soap_envelope := ' + + + + '; + l_soap_envelope := l_soap_envelope || p_zip; + l_soap_envelope := l_soap_envelope || ' + + '; + + -- + -- Start a new request to the target SOAP server, and POSTing our request + -- + l_http_request := utl_http.begin_request( + url => 'http://services.xmethods.net:80/soap/servlet/rpcrouter', + method => 'POST' ); + utl_http.set_header(l_http_request, 'Content-Type', 'text/xml'); + utl_http.set_header(l_http_request, 'Content-Length', length(l_soap_envelope)); + utl_http.set_header(l_http_request, 'SOAPAction', 'getTempRequest'); + + -- + -- Write the envelope as part of the request + -- + utl_http.write_text(l_http_request, l_soap_envelope); + + -- + -- Immediately get the response from our request + -- + l_http_response := utl_http.get_response(l_http_request); + utl_http.read_text( l_http_response, l_response ); + utl_http.end_response(l_http_response); + + -- + -- Parse the response into a variable of XMLType and then + -- extract just the return value using XPath syntax + -- + l_xml := xmltype.createxml( l_response ); + return l_xml.extract('//return/child::text()').getStringVal(); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-3.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-3.sql new file mode 100755 index 0000000..b678fe5 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-3.sql @@ -0,0 +1,38 @@ +-- Example 1 +begin + htp.tableOpen; + htp.tableRowOpen; + htp.tableHeader( cvalue => 'TheHeader', calign => 'left' ); + htp.tableRowClose; + htp.tableRowOpen; + htp.tableData( cvalue => 'DataVal' ); + htp.tableRowClose; + htp.tableClose; +end; +/ +exec owa_util.showpage; + +-- Example 2 +declare + l_str varchar2(32000); +begin + l_str := ''; + l_str := l_str || ''; + l_str := l_str || ''; + l_str := l_str || ''; + l_str := l_str || ''; + l_str := l_str || ''; + l_str := l_str || ''; + l_str := l_str || '
TheHeader
DataVal
'; + htp.p( l_str ); +end; +/ +exec owa_util.showpage; + +-- Example 3 +begin + htp.p(''); + htp.p('
TheHeader
DataVal
'); +end; +/ +exec owa_util.showpage; diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-4.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-4.sql new file mode 100755 index 0000000..e7f46c7 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-4.sql @@ -0,0 +1,7 @@ +create or replace procedure printenv +as +begin + owa_util.print_cgi_env; +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-5.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-5.sql new file mode 100755 index 0000000..a9cfe2e --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-5.sql @@ -0,0 +1,30 @@ +create table web_log( + log_date date, + ip_address varchar2(255), + user_agent varchar2(4000), + script_name varchar2(4000), + path_info varchar2(4000), + http_referer varchar2(4000)) +/ + +create or replace procedure log_it +as +begin + insert into web_log( + log_date, + ip_address, + user_agent, + script_name, + path_info, + http_referer ) + values( + sysdate, + owa_util.get_cgi_env( 'REMOTE_ADDR' ), + owa_util.get_cgi_env( 'HTTP_USER_AGENT' ), + owa_util.get_cgi_env( 'SCRIPT_NAME' ), + owa_util.get_cgi_env( 'PATH_INFO' ), + owa_util.get_cgi_env( 'HTTP_REFERER' ) ); +end; +/ + + diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-6.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-6.sql new file mode 100755 index 0000000..d7d91c4 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-6.sql @@ -0,0 +1,11 @@ +exec owainit; + +exec log_it; + +column ip_address format a15 +column user_agent format a10 word_wrapped +column script_name format a10 word_wrapped +column path_info format a10 word_wrapped +column http_referer format a10 word_wrapped +set linesize 120 +select * from web_log; diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-7.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-7.sql new file mode 100755 index 0000000..a8e8309 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-7.sql @@ -0,0 +1,7 @@ +create or replace procedure printenv as +begin + owa_util.print_cgi_env; + log_it; +end; +/ + diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-8.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-8.sql new file mode 100755 index 0000000..a8e3a78 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-8.sql @@ -0,0 +1,8 @@ +exec owainit; +begin + owa_util.mime_header('text/html', FALSE); + owa_cookie.send('NAME','Brutus.Buckeye',sysdate+1); + owa_util.http_header_close; + htp.p('Hello world'); +end; +/ diff --git a/2174_MasteringPLSQL_CODE/ch09/ch9-9.sql b/2174_MasteringPLSQL_CODE/ch09/ch9-9.sql new file mode 100755 index 0000000..14e08e3 --- /dev/null +++ b/2174_MasteringPLSQL_CODE/ch09/ch9-9.sql @@ -0,0 +1,24 @@ +create table mydocs( + id number primary key, + name varchar2(256) not null, + mime_type varchar2(128), + doc_size number, + dad_charset varchar2(128), + last_updated date, + content_type varchar2(128), + blob_content blob +) +/ + +create sequence mydocs_seq +/ + +create or replace trigger biu_mydocs + before insert or update on mydocs + for each row +begin + if :new.id is null then + select mydocs_seq.nextval into :new.id from dual; + end if; +end; +/ diff --git a/9781590592175.jpg b/9781590592175.jpg new file mode 100755 index 0000000000000000000000000000000000000000..cbf2b380220f92ed573e4580f5bba3755dd04101 GIT binary patch literal 9028 zcmchc1yEeizUK!90>RzgH3WBecXtU15FkKsCrC2D;7)K2?k>S4xHAMB+!FoUu)`&j@!yLhx zql|FZWVly_4mE0E&$n0Gn*4GjWz>XF_{S z22+~Fkwcm{68^o!*8>7TP{?6l%8fK)h--njO(lRT_~-TEd=OVUGk#;eTE(8u7v*d3 z8?HN?ZLu@hxc=e3QQ4+)K}Y(5fTeySgXHi}vp+tu3XGGpU-}8D9cPVY8<)OFp?1oN zx4T^g@W6pAlZ>sUshl#DumV|R!E$JN{1*A_VT{1p`8=<1n5d-F43V5In1L>o?X7|c ziC+MHt8#+NR*%gc@_@w34}Ch|xFj7ojR!7iOLfOPKqbr8<7m+>Tg7METWcdG@m9^? zNStF~x)IXv8J|zrczsfd0fW<{3*kcE^N1HHdBeNgT%QGWAh|mLoz!xQQ&Icu);xZ| zj+4dH0_1@-=Y!adq-`TH8jqm*Pcz&jghcg>fLJpQYi0aRvj}DJ^sBusW$`rN z{&!L{t6$bVlpv=F%^Ch;7FKi;X=mcFJvODwhLXmaIz7=a91$3^{3Sto2k-B zv!n^G5P6hM8jk!3^Xs=+rv{S!aVRo~rw><9&m^x2H*tHc(YD(=WVL!lV}1qtr0?8d z$!5IW5w+DYbz-@!?CvE}TQZH=HmDvr4*DH`LMo^MDS zfK;@`6oKOHG*!BCLrW&_Gz7D*T=gm3vLXHrY3}ITpX7C!+Qb9sKtt|Pz_fGJ6u?H( zX-Ps(PEKHGC)bo!)7R?_u6pYSCsG?OWP|dG2^5#%^~+1%#YL|+wWbIu`K)zPASe-D^MvJaFRE< zBzAXTCRl=`CBTfjv#_h}0*p6~xos`p`5^=T`)tt!{8hh~F-73z)bW#B)e6oaDy{BI z;6s{MSbX%|6QhG7z?tbb{I@ohVLKBMlP}>u1b$Z z%nO!lS|4>3glpLKcE_16h}O;Jd8C-Tre&{I7^8U zqCO$-R2to?>vqgme5}a5P&w=6Ov8_IVJmC#j1@CuEt!1O%{30R8TEAIQng72ZEScG z-dIWWU&4iLBDf_>7RL6-&)Wn6O;2)dB5VOoB0#suv6u}Bk~N*m%u9Wxo^{TmM> zQ432$Xi64fx8FpeGon}}Kh@wVBN3HP?q;Tqdu+dd8F^(!1f8y}P}PY}D-?vaW%XK? znjGkX6(qN_3~(o^@dxc^CeTOg7lh-CKdHc0=g5pMYnDiT4J18?=+#Z00W6y2$ezN*%iD2j)F6g)elaD;&mCjdi*)4^ zBBShyqY9sY??r>sf`GpcYQmfTlWuUlhVl&X7 z5bGp%SAqJ*5F6BA?)6r?zHksiKF7zXho>aAg>>8lcJ}huC`81bq^^6Utl^7pbJF17 z@@fsnO7kB-KLDM@GM&=4FDQNA%mfGJ(^6q6Fjf^BQZR*!N}fu(awcD!N~D=1-B^e+C4;LQ=kWM;L=PXDoHDNsQ0E_)slzMVIhLzK&&*iYS&ajCrxh?GL@2?K#uKBk#* zXJ^ogpyvgVzw_K^c=)K#_lte?9V{rSE))<*Nau>-O|AyFuW2&8QTmY~WR^!CZDev} zWQzfAh3sbHBiiQ)Uh=FC=MOiz6?Dzu6B!R~fj4|xahYyyR1|{5 zu$}dCE#S+j6IU;=6LW@P z@NS@_tI6I>r>n~Mq0*6xsKA_ji8=pk#MvU$PqoI6m=oos~Ymeg;U*74NJ;buAa~a6tE` zPx#`&;(JE*kB~<@@eS=;+^4WI^|7vjNW_@94^@@VfPczM_@}}jstxW4{y*1`xz%|> zcn0L!&s;d4=l!(aQer*q`scj-e`(-<4Om_&hJK5&q43mW@a+^2#_=>}GGF!}>J_k| zZ0Ga+PvkWYHdlZ=(p8~F%|#OaUI6Va$L4Q1vk&ahIY<5YYwtHm?eDWkd3Vdp!9xeS zvl~g_$YP-$IZ~RkctL-e?4c3FRK~!dg@K7#$;uhj7G?nWVeInIzD{PN>ndzAvox|GjKUgCA;iyGG-g*keC-=q z#iAb<8{28<7sZdpIV2K=y@1bN6;oa%!|G`5%~m&3Gf480E?jDT*8>T~l{*eBOBQ7| zZVGM$L67|0Q01KxAnL4w>Rcb7x-vLQQ$>K1V(_fr zgGU2tV3q5PuWmhB#@JpHsVO$Q?)QMWC(~2(LGcyY0>8P_p$|j$COLyYw@#ySq+vL* zaf#?x(XU6cereD(;OZ@*8J~6nZ|0J(a%Nz;y7XRe^F75CJM#92Jdl*waUO_eg!A-~ zyVzd;8St^iki>Md5$KYdmgaR|Gf`ocjp=1HaDbnn3$qCwd?;?$9hT}>JdJC92HYQX z^`i&uDon07)WzjxU5yaqZ6pEis(o=|#f6}c9A`66IOG6(w>92272{z^A`1zDQQQN` zio6a;lXVfcU*>dD++Ok%`m~B2i;1bqfK95JEn zz0rj_k$2$9uQfp|_f;BCGntyuSNxm;X>2mU{YMt{w9R~AEzUjTEI=?=k_kmfHNhF zz|p?0@y05@_ZwqE+Z87bzMs=Dh;@>e{V^t8q$4|G3tts%Hq^Aq>dagTlj|*-ESk!? zy%ty_eUCJGPtv3%t%t&t7xWM9inwf$nv-~0L6tLE#$vdZtpq`uH|jGr*9@&fOu&uE zHswgvrK6KgP7}z`lrr%_c`<^fS=ISXuX3?h`hr<7UvDYHaJ9fiEJh&y;2+qBQo4I7 z5YrDPn0VC3!20^6BkI_vGSjtS2@0gC^JjqA`ZGXi^NAC}cT95xY`TfV-SeWoBRLeK zFq3s#cNBJr>JDcXd?-{rytR1Zt?vp4mp%jF8IxB6PB%yKkIOOt5V5F#dzUh}z?OzV z8(K=y=2cQoWd97nr%hhl1)Hjj6nN@dEj@-QpR+#6Kg8TnKS?#3<6H_^KgzU&AwACk zjP1!Pt9klaBS#6j?Yu=k=Xc`$voN1|hR8FRg1g{pyET2+(vot*b-8nFmNJFF;cADt zcAKNPY-GQWJt+d1;776uu)?EP@E` zkGpCmcrY9C7G<9^EIg37UfTtHLk%C_qJ!sNah31*_^3a-+jh<)WK@F%kt<-dro9ml zN7^;iC(vtk?z{b1p5j01r zA4LayaDmr|ZY?d}PEPH5w(4yDL{)fD%kF%%b9G%27t6~vjb$zO@etxL>PM4>=1eF{ z5aU>iy64vuuXGm!z*0BMJin^aD*w?ow9_X%e*NP0+PD8O{EPWT9-wNmyz1d8FvMSt zY$=%VgSa>s2RegifVVx2pib9AAmV!a^W_xtC>**698{^PqpI{{yMae0sX zyIVWoEtZ!x&>~f?xgF~GX`k)v_KDFZ=)`D+Be+Y@eu%`bx307=?wufCvrmt?7OS92 zmzSDUuYX17s$26D8tY$1LWy%2v1znOuC=usXiwDsz1L}M%kkbSQa!Eh0EJgq?zAGt zGHX>hLy^76bZR7=pCTuU1lIgS;LsY7b6V&S2kCLm(-@EcDEie5bJwg+_8oEaktIre z_+V;rPg(_Uh66;^P)U-`b@Rip?K`R(I*KjI@m5TdTN)1h0`7i+rp_>>vf6Faz}B@G z>8na@_1UUN`Ez@j@cZr04|ax8E+aot2Kb_)pvi-~hWBfc?UI{;xO_>uD~brO^gwuF zjl`Upb^Iou)T=8T`R0q|+4bp8YdK=VR;kx^5xoV)g1GY6it@O#e4K3ObsYJQL%cD?s!(;Z-z$m^rOG7zArH21`_lGuIPR{>NEjop zUcx80iFQWEeRbXR*eVHp7Zg51O(w3G&BdeizM@JRr36Pa{+cUZtlc$UI-~BQ-OZgz z9t65Q10A2b%mlA12il>VSq-K8=!Jpr%~c(C?%E#nqZc7jPqwXr2xca0xBRNDZD~7M zGFC9b?M^FJL52n4x0&yle#HBJN5s=KObx@+lz2(}FQPC#PxvDj{q)#1Y#)g1H6uAC zf@z2N8}{c1zN_P$qN{QZut;#IM2su2WU6Z|<&ItcWfYHCW@y^T5LLQ3mb3G8e$6+x z@pV5&(zw#xwgo&ld_*YjmU-*$$a@pRenKmSL&@chyq6OKcw9uWp@iwBJoO?y1LR1q zD<~yrcu=*SiS_Hn*-mZk zbQl4~|X&tNYoR2!GE#S z!ts>?rQvKE@_SL4x}n*PI9$6q-&%wM`enYLwY6n70KI#rPVrh*LWUTu){RV=e59>u zq$G@&OFHn$$K>D%YaqXu&=u~27YZK$Y8dd-mB`{ria@New!Yd5R66R!8mZVQ8w$RQ zKZ+Oo(Ok*BS@uoDj*EF%`NM2Xfch04^il7nD_4oD&eh~n)Xr9-Tql4vV%u76F%exb z>V5O8v93$LO3KXwNA!pY8t3-d*6fnkrh~m}cUYHI_d9F%q&mvCA3)jNW?egsTze?607_N`$av|bun?I(w?_e>MNJ!o?!Bv-iPZCj5PI#oK0j!wE{VEuY?DkV8! z5;p|REo)j{@gUTanx7fo?qi6{2conLc#F+BJSdGKWHieWx{L+~51OmxUz9n*7MnDi znLOC_zuB*%o*R4RJ!sTa$GLf2NV2E|#iYi{i|E&qOAT9r_1Z$^se1%tEn{kaR8&Cx zi;TT~deg+wTDHiqo^W{&`cN~HN2rw*U5ZpaaBl{PFW6Jw;$=g%S3d|nbwSa|dD+EI zkLIT&@h*nAia-3Op73jw_37@c=U_oiRhHtWS`|~TDwJ|}&}Pq**|c;$0-aY=VR5H|F@O}|6&4{WY(LKHDpn&{rjJ>6A=YtU#(hBbY6Q~7OkZJ}g=9*p=I*8W0-IWB- z5tUUVdiqcLkLfqfA6FI`tRvR3%BXDwHjE2boS_24uLoviMgfleyjRxZBAn$Ra&W~tTgRcuNG3;>z zUMLHF*S#9gfY9g@QWtgF@g(yHNX?f)`=hqLw;tq;uY1{60-dE`RajPZnw#8E_O^EZJpqU!vu#ykzIZFhbeXY- zZ(1%pptm7XN~axtgiLpDUCClspE1#-q&4T)n7%A=&U0%W>m-s`K%lKsMPGpO!p zo+U9hR#Cy1A#_o$uDbaW1rtXJu8+L_K63=!PWNvA)4Piiig?oJG4;CTu8G3Zt}8z#fVIvjrFfo%x{>8DN$v6Jht5eTO0 z-zA> z5`XRP|6l2XlJs_9SK?gJpt2}R5?)AduZNIMY+J;1qUsYDBM`V$3$(-$bRENe2Qw1BE&ti37U6IY32bVk2 zo~uVLvnp5_IOm7cDfEQuMtuerxuugPcPFx~wvu+D&Th^5aX7f}Bq*~aM;E4ZMKjD( z@gbATVJhu0<&}?}=Db+-Z^60$*t5;%IFANrr{N9BQ%lYqS9rwns6>7}neUO}#s#~_ z0G>Mf_#4^Z?vX$hyu=^FesS%erR{`ozOASR4pGI*<8@*Bxw}Beg#0D!C@mX6=5*X9 z&Tl+ITwvfdJh==71$&H*3HivZDa)RA1b|Jv|lCT*kHiCIkIgj``dXCiB z9;9>4!w--odF@%SFe^G=5_s;UV$)rb@f$J3s!RYeW779Qk1sm!8Sw5l!KBl;WR+b_ zVcS6BE-ucaDZtmCH8Yqe(pZr;ML)B~;+IWObyOH_%*VGA8=8>)dy@*ZPX{+#3WidN z!HJzaL~L#oYAuwW%aQPo6rl;dtV3}l;PXtOGI*Vbd+ntpygDpAw0L#+X5qOhM$pMK z;J699E8TBkF~FR2V0GPbBL*qfD8D{MA@cLIeM0R7>VReP?+nuJjTXTxvCifq+D^sI zc>FYaxo_dpW$?x4#S2;OJ|=HT(;9r6Oa=mv z6$=fmkrCqF?)kvft1fad=0RiC3v3O7eR@Um!l=niI&iVVe*&eAbpAtlX~C-G7hVmJ z3gZg)XeK;+_1jk`TVwwHWPz*)2%$qMtdkZ$c@g9NiCTmXGUyC=}#u=r6^z;dpVW8HV(Yo zAk+$2Kb;SD1W89ExXU^;SrD97^{SA5G_=~`J zVA{*zag literal 0 HcmV?d00001 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100755 index 0000000..6fe46cd --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2004 Christopher Beck, Joel Kallman, Chaim Katz, David C. Knox, and Connor McDonald + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/README.md b/README.md new file mode 100755 index 0000000..f037be9 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Mastering Oracle PL/SQL*](http://www.apress.com/9781590592175) by Christopher Beck, Joel Kallman, Chaim Katz, David C. Knox, and Connor McDonald (Apress, 2004). + +![Cover image](9781590592175.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/contributing.md b/contributing.md new file mode 100755 index 0000000..905ff61 --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file