├── 9781484207383.jpg ├── LICENSE.txt ├── README.md ├── contributing.md └── source_20150125 ├── AppendixA ├── SYSTEM on ORCL.lnk ├── create_users.sql ├── create_users.sub ├── create_users.txt ├── drop_users.sql ├── pe.sql ├── pl.prc └── pl.sql ├── Chapter01 ├── README.txt ├── RPS on ORCL.lnk ├── author_names.sql ├── author_names_before_1940.sql ├── author_publications.tab ├── author_publications.upd ├── author_publications_100.ins ├── author_publications_200.ins ├── author_publications_300.del ├── author_publications_300.ins ├── author_publications_fk1.fkc ├── author_publications_k1.ndx ├── author_publications_pk.pkc ├── authors.tab ├── authors.upd ├── authors_100.ins ├── authors_200.ins ├── authors_300.del ├── authors_300.ins ├── authors_bir.trg ├── authors_pk.pkc ├── authors_publications.vw ├── authors_publications_from_join.sql ├── authors_publications_where_join.sql ├── authors_uk1.ndx ├── authors_uk1.ukc ├── be.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── coauthor_publications.sql ├── coauthors.sql ├── create_all.sql ├── create_all.txt ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── fe.sql ├── gender_types.ins ├── gender_types.tab ├── hazard_level_types.ins ├── hazard_level_types.tab ├── logical_assignments.tab ├── logical_workplaces.ins ├── logical_workplaces.tab ├── login.sql ├── pe.sql ├── physical_assignments.tab ├── physical_workplaces.tab ├── pl.prc ├── pl.sql ├── se.sql ├── substances.ins ├── substances.tab ├── task_substances.tab ├── tasks.tab ├── work_assignments.tab ├── work_tasks.tab ├── worker_types.ins ├── worker_types.sql ├── worker_types.tab ├── workers.tab ├── workplace_types.ins ├── workplace_types.tab └── works.tab ├── Chapter02 ├── README.txt ├── RPS on ORCL.lnk ├── anonymous.sql ├── be.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── create_all.sql ├── create_all.txt ├── date_.pkb ├── date_.pks ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── fe.sql ├── login.sql ├── number_.pkb ├── number_.pks ├── pe.sql ├── pl.prc ├── pl.sql ├── pl2.sql ├── se.sql ├── to_mmsddsyyyy_or_null.fun ├── to_mmsddsyyyy_or_null.sql ├── to_number_or_null.fun └── wait.prc ├── Chapter03 ├── README.txt ├── RPS on ORCL.lnk ├── be.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── create_all.sql ├── create_all.txt ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── fe.sql ├── login.sql ├── multidimensional.sql ├── parameter.pkb ├── parameter.pks ├── parameter.sql ├── pe.sql ├── pl.prc ├── pl.sql ├── record.sql ├── row.sql ├── scope.pkb ├── scope.pks ├── scope.sql ├── se.sql ├── table.sql └── workers_variables.sql ├── Chapter04 ├── README.txt ├── RPS on ORCL.lnk ├── be.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── create_all.sql ├── create_all.txt ├── ddl_.pkb ├── ddl_.pks ├── delete.sql ├── desc.sql ├── drop_all.sql ├── fe.sql ├── insert.sql ├── insert_the_doe_family.sql ├── insert_with_handled_exception.sql ├── insert_with_plsql_detection.sql ├── insert_with_plsql_detection_for_update.sql ├── insert_with_sql_detection.sql ├── login.sql ├── multidimensional.sql ├── pe.sql ├── pl.prc ├── pl.sql ├── se.sql ├── select_no_data_found.sql ├── select_the_doe_family.sql ├── select_too_many_rows.sql ├── table.sql └── update_multiple.sql ├── Chapter05 ├── README.txt ├── RPS on ORCL.lnk ├── a_thru_z.ins ├── a_thru_z.tab ├── be.sql ├── bulk_collect_the_doe_family.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── create_all.sql ├── create_all.txt ├── cursor_bulk_collect_the_doe_family.sql ├── cursor_for_loop_the_doe_family.sql ├── cursor_the_doe_family.sql ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── fe.sql ├── gender_type.pkb ├── gender_type.pks ├── insert_with_modularity.sql ├── insert_with_plsql_cursor_detection_for_update.sql ├── insert_with_plsql_detection.sql ├── login.sql ├── pe.sql ├── pl.prc ├── pl.sql ├── se.sql ├── top_100_first_names.ins ├── top_100_first_names.tab ├── top_100_last_names.ins ├── top_100_last_names.tab ├── worker.pkb ├── worker.pks ├── worker_type.pkb ├── worker_type.pks ├── workers.ins ├── workers_bulk_collect.ins ├── workers_cursor_for_loop.ins └── workers_forall.ins ├── Chapter06 ├── OPS on ORCL.lnk ├── README.txt ├── be.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── create_all.sql ├── create_all.txt ├── date_.pkb ├── date_.pks ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── fe.sql ├── gender_type.pkb ├── gender_type.pks ├── gender_type.tpb ├── gender_type.tps ├── gender_types.ins ├── gender_types.tab ├── gender_typez.sql ├── gender_typez.vw ├── login.sql ├── pe.sql ├── pl.prc ├── pl.sql ├── se.sql ├── worker.tpb ├── worker.tps ├── worker_type.pkb ├── worker_type.pks ├── worker_type.sql ├── worker_type.tpb ├── worker_type.tps ├── worker_types.ins ├── worker_types.sql ├── worker_types.tab ├── worker_typez.vw ├── workers.ins └── workers.tab ├── Chapter07 ├── I needed this to enable debugging in SqlDeveloper.txt ├── OPS on ORCL.lnk ├── README.txt ├── RPS on ORCL.lnk ├── avg_profile.sql ├── avg_profile_2.txt ├── avg_profile_3.txt ├── avg_profile_4.txt ├── avg_profile_ops.debug.sql.txt ├── be.sql ├── ci.sql ├── ci.txt ├── cmd.exe.lnk ├── date_.pkb ├── date_.pks ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── failure.sql ├── fe.sql ├── is_profiler.sql ├── login.sql ├── ops.create_all.sql ├── ops.create_all.txt ├── ops.debug.sql ├── ops.debug.tpb ├── ops.debug.tpb.original ├── ops.debug.tpb.with_wasted_sequence_problem.txt ├── ops.debug.tps ├── ops.debug.tps.original ├── ops.debug.tps.with_wasted_sequence_problem.txt ├── ops.debug_a_session.sql ├── ops.debugger.pkb ├── ops.debugger.pks ├── ops.debugger.sql ├── ops.debugs.tab ├── ord_profile.sql ├── ord_profile_3.txt ├── ord_profile_4.txt ├── pe.sql ├── pl.prc ├── pl.sql ├── profile.sql ├── rps.create_all.sql ├── rps.create_all.txt ├── rps.debug.pkb ├── rps.debug.pks ├── rps.debug.sql ├── rps.debug_a_session.sql ├── rps.debugs.tab ├── rps.workers_ins_insert_w_codes.sql ├── rps.workers_ins_insert_w_codes.sql.pln ├── rps.workers_ins_insert_w_codes_timing.sql ├── rps.workers_ins_insert_w_constants_timing.sql ├── rps.workers_ins_insert_with_constants.sql ├── rps.workers_ins_insert_with_constants.sql.pln ├── run_profile.sql ├── se.sql ├── select_workers_equalto.sql ├── select_workers_equalto.sql.pln ├── select_workers_likepct.sql ├── select_workers_likepct.sql.pln ├── select_workers_pctlikepct.sql ├── select_workers_pctlikepct.sql.pln ├── select_workers_pctlikepct2.sql ├── select_workers_pctlikepct2.sql.pln ├── select_workers_pctlikepcts.sql.pln ├── select_workers_pctlikepcts2.sql.pln ├── success.sql ├── usi.sql └── xp.sql └── MyTools ├── be.sql ├── ci.sql ├── ci.txt ├── ddl_.pkb ├── ddl_.pks ├── desc.sql ├── drop_all.sql ├── fe.sql ├── login.sql ├── pe.sql ├── pl.prc ├── pl.sql └── se.sql /9781484207383.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/9781484207383.jpg -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/LICENSE.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Beginning Oracle PL/SQL*](http://www.apress.com/9781484207383) by Donald Bales (Apress, 2015). 4 | 5 | ![Cover image](9781484207383.jpg) 6 | 7 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 8 | 9 | ## Releases 10 | 11 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 12 | 13 | ## Contributions 14 | 15 | See the file Contributing.md for more information on how you can contribute to this repository. 16 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | 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. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 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. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /source_20150125/AppendixA/SYSTEM on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/AppendixA/SYSTEM on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/AppendixA/drop_users.sql: -------------------------------------------------------------------------------- 1 | rem create_users.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Drop user RPS and OPS 4 | prompt Reply with the password for SYS you specified when you created the database... 5 | connect sys as sysdba; 6 | drop user rps cascade; 7 | drop user ops cascade; 8 | -------------------------------------------------------------------------------- /source_20150125/AppendixA/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/AppendixA/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/AppendixA/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/RPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter01/RPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_names.sql: -------------------------------------------------------------------------------- 1 | SELECT name 2 | FROM authors 3 | ORDER BY name; 4 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_names_before_1940.sql: -------------------------------------------------------------------------------- 1 | SELECT name 2 | FROM authors 3 | WHERE birth_date < to_date('19400101', 'YYYYMMDD') 4 | ORDER BY name; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications.tab: -------------------------------------------------------------------------------- 1 | CREATE TABLE author_publications ( 2 | id number(38), 3 | author_id number(38), 4 | title varchar2(100), 5 | written_date date ); -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications.upd: -------------------------------------------------------------------------------- 1 | UPDATE author_publications 2 | SET title = upper(title) 3 | where title <> upper(title); 4 | 5 | COMMIT; 6 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_100.ins: -------------------------------------------------------------------------------- 1 | INSERT INTO author_publications ( 2 | id, 3 | author_id, 4 | title, 5 | written_date ) 6 | VALUES ( 7 | 10, 8 | 100, 9 | 'A Relation Model of Data for Large Shared Data Banks', 10 | to_date('19700101', 'YYYYMMDD') ); 11 | 12 | INSERT INTO author_publications ( 13 | id, 14 | author_id, 15 | title, 16 | written_date ) 17 | VALUES ( 18 | 20, 19 | 100, 20 | 'The Relational Model for Database Management', 21 | to_date('19900101', 'YYYYMMDD') ); 22 | 23 | COMMIT; 24 | 25 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'AUTHOR_PUBLICATIONS'); 26 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_200.ins: -------------------------------------------------------------------------------- 1 | INSERT INTO author_publications ( 2 | id, 3 | author_id, 4 | title, 5 | written_date ) 6 | VALUES ( 7 | 30, 8 | 200, 9 | 'An introduction to Database Systems', 10 | to_date('20030101', 'YYYYMMDD') ); 11 | 12 | INSERT INTO author_publications ( 13 | id, 14 | author_id, 15 | title, 16 | written_date ) 17 | VALUES ( 18 | 40, 19 | 200, 20 | 'The Third Manifesto', 21 | to_date('20000101', 'YYYYMMDD') ); 22 | 23 | INSERT INTO author_publications ( 24 | id, 25 | author_id, 26 | title, 27 | written_date ) 28 | VALUES ( 29 | 50, 30 | 200, 31 | 'Temporal Data and the Relational Model', 32 | to_date('20020101', 'YYYYMMDD') ); 33 | 34 | INSERT INTO author_publications ( 35 | id, 36 | author_id, 37 | title, 38 | written_date ) 39 | VALUES ( 40 | 60, 41 | 200, 42 | 'Database in Depth: Relational Theory for Practitioners', 43 | to_date('20050101', 'YYYYMMDD') ); 44 | 45 | COMMIT; 46 | 47 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'AUTHOR_PUBLICATIONS'); 48 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_300.del: -------------------------------------------------------------------------------- 1 | DELETE FROM author_publications 2 | WHERE author_id = 300; 3 | 4 | ROLLBACK; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_300.ins: -------------------------------------------------------------------------------- 1 | INSERT INTO author_publications ( 2 | id, 3 | author_id, 4 | title, 5 | written_date ) 6 | SELECT 70, 7 | 300, 8 | 'The Third Manifesto', 9 | to_date('20000101', 'YYYYMMDD') 10 | FROM dual 11 | where not exists ( 12 | SELECT 1 13 | FROM author_publications x 14 | WHERE x.author_id = '300' 15 | AND x.title = 'The Third Manifesto' ); 16 | 17 | INSERT INTO author_publications ( 18 | id, 19 | author_id, 20 | title, 21 | written_date ) 22 | SELECT 80, 23 | 300, 24 | 'Temporal Data and the Relational Model', 25 | to_date('20020101', 'YYYYMMDD') 26 | FROM dual 27 | where not exists ( 28 | SELECT 1 29 | FROM author_publications x 30 | WHERE x.author_id = '300' 31 | AND x.title = 'Temporal Data and the Relational Model' ); 32 | 33 | COMMIT; 34 | 35 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'AUTHOR_PUBLICATIONS'); 36 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_fk1.fkc: -------------------------------------------------------------------------------- 1 | ALTER TABLE author_publications ADD 2 | CONSTRAINT author_publications_fk1 3 | FOREIGN KEY (author_id) 4 | REFERENCES authors (id); 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_k1.ndx: -------------------------------------------------------------------------------- 1 | CREATE INDEX author_publications_k1 2 | on author_publications ( 3 | title ); 4 | 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/author_publications_pk.pkc: -------------------------------------------------------------------------------- 1 | ALTER TABLE author_publications ADD 2 | CONSTRAINT author_publications_pk 3 | PRIMARY KEY ( 4 | id); 5 | 6 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors.tab: -------------------------------------------------------------------------------- 1 | CREATE TABLE authors ( 2 | id number(38) not null, 3 | name varchar(100) not null, 4 | birth_date date, 5 | gender varchar2(30) ); 6 | 7 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors.upd: -------------------------------------------------------------------------------- 1 | UPDATE authors 2 | set name = upper(name); 3 | 4 | COMMIT; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_100.ins: -------------------------------------------------------------------------------- 1 | INSERT INTO authors ( 2 | id, 3 | name, 4 | birth_date, 5 | gender ) 6 | VALUES ( 7 | 100, 8 | 'Edgar F Codd', 9 | to_date('19230823', 'YYYYMMDD'), 10 | 'MALE' ); 11 | COMMIT; 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_200.ins: -------------------------------------------------------------------------------- 1 | INSERT INTO authors ( 2 | id, 3 | name, 4 | birth_date, 5 | gender ) 6 | SELECT 200, 7 | 'Chris J Date', 8 | to_date('19410101', 'YYYYMMDD'), 9 | 'MALE' 10 | from DUAL; 11 | 12 | COMMIT; 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_300.del: -------------------------------------------------------------------------------- 1 | DELETE FROM authors 2 | WHERE id = 300; 3 | 4 | ROLLBACK; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_300.ins: -------------------------------------------------------------------------------- 1 | INSERT INTO authors ( 2 | id, 3 | name, 4 | birth_date, 5 | gender ) 6 | SELECT 300, 7 | 'Hugh Darwen', 8 | to_date('19430101', 'YYYYMMDD'), 9 | 'MALE' 10 | from dual d 11 | where not exists ( 12 | SELECT 1 13 | FROM authors x 14 | WHERE x.id = '300' ); 15 | 16 | COMMIT; 17 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_bir.trg: -------------------------------------------------------------------------------- 1 | CREATE TRIGGER authors_bir 2 | BEFORE INSERT ON authors 3 | FOR EACH ROW 4 | 5 | begin 6 | if upper(:new.name) = 'JONATHAN GENNICK' then 7 | raise_application_error(20000, 'Sorry, that genius is not allowed.'); 8 | end if; 9 | end; 10 | / 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_pk.pkc: -------------------------------------------------------------------------------- 1 | ALTER TABLE authors ADD 2 | CONSTRAINT authors_pk 3 | primary key ( 4 | id ); 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_publications.vw: -------------------------------------------------------------------------------- 1 | CREATE OR REPLACE VIEW authors_publications as 2 | SELECT authors.id, 3 | authors.name, 4 | author_publications.title, 5 | author_publications.written_date 6 | FROM authors, 7 | author_publications 8 | WHERE authors.id = author_publications.author_id; 9 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_publications_from_join.sql: -------------------------------------------------------------------------------- 1 | SELECT a.id, 2 | a.name, 3 | p.title, 4 | p.written_date 5 | FROM authors a JOIN 6 | author_publications p 7 | ON a.id = p.author_id 8 | ORDER BY a.name, 9 | p.written_date, 10 | p.title; 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_publications_where_join.sql: -------------------------------------------------------------------------------- 1 | SELECT a.id, 2 | a.name, 3 | p.title, 4 | p.written_date 5 | FROM authors a, 6 | author_publications p 7 | WHERE a.id = p.author_id 8 | ORDER BY a.name, 9 | p.written_date, 10 | p.title; 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_uk1.ndx: -------------------------------------------------------------------------------- 1 | CREATE UNIQUE INDEX authors_uk1 2 | on authors ( 3 | name, 4 | birth_date, 5 | gender ); -------------------------------------------------------------------------------- /source_20150125/Chapter01/authors_uk1.ukc: -------------------------------------------------------------------------------- 1 | ALTER TABLE authors ADD 2 | CONSTRAINT authors_uk1 3 | UNIQUE ( 4 | name, 5 | birth_date, 6 | gender ); 7 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter01/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter01/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter01/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter01/coauthor_publications.sql: -------------------------------------------------------------------------------- 1 | SELECT p.title, 2 | a.name 3 | FROM authors a, 4 | author_publications p 5 | WHERE a.id = p.id 6 | AND EXISTS ( 7 | SELECT 1 8 | FROM author_publications x 9 | WHERE x.title = p.title 10 | AND x.id <> p.id ) 11 | ORDER BY p.title, 12 | a.name; 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/coauthors.sql: -------------------------------------------------------------------------------- 1 | SELECT a.name 2 | FROM authors a 3 | WHERE EXISTS ( 4 | SELECT 1 5 | FROM author_publications x1, 6 | author_publications x2 7 | WHERE x1.id = a.id 8 | and x1.title = x2.title 9 | and x2.id <> a.id ) 10 | ORDER BY a.name; 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool create_all.txt; 7 | 8 | @pl.prc 9 | @drop_all.sql 10 | 11 | @authors.tab 12 | @authors_pk.pkc 13 | @authors_uk1.ukc 14 | @authors_bir.trg 15 | @authors_100.ins 16 | @authors_200.ins 17 | @authors_300.ins 18 | @authors_300.del 19 | @authors.upd 20 | 21 | @author_publications.tab 22 | @author_publications_pk.pkc 23 | @author_publications_k1.ndx 24 | @author_publications_fk1.fkc 25 | @author_publications_100.ins 26 | @author_publications_200.ins 27 | @author_publications_300.ins 28 | @author_publications_300.del 29 | @author_publications.upd 30 | 31 | @authors_publications.vw 32 | 33 | -- code tables 34 | @gender_types.tab 35 | @hazard_level_types.tab 36 | @worker_types.tab 37 | @workplace_types.tab 38 | 39 | @gender_types.ins 40 | @hazard_level_types.ins 41 | @worker_types.ins 42 | @workplace_types.ins 43 | 44 | -- content tables 45 | @logical_workplaces.tab 46 | @physical_workplaces.tab 47 | @substances.tab 48 | @tasks.tab 49 | @workers.tab 50 | @works.tab 51 | 52 | @logical_workplaces.ins 53 | @substances.ins 54 | 55 | -- intersetion tables 56 | @logical_assignments.tab 57 | @physical_assignments.tab 58 | @task_substances.tab 59 | @work_assignments.tab 60 | @work_tasks.tab 61 | 62 | spool off; 63 | set echo off; 64 | @ci.sql 65 | @ci.sql 66 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/create_all.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter01/create_all.txt -------------------------------------------------------------------------------- /source_20150125/Chapter01/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter01/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/gender_types.ins: -------------------------------------------------------------------------------- 1 | rem gender_types.ins 2 | rem by Donald J. Bales on 2010-10-20 3 | rem Add code values to the genders table 4 | 5 | insert into GENDER_TYPES ( id, code, description ) values ( GENDER_TYPES_ID.nextval, 'F', 'Female' ); 6 | insert into GENDER_TYPES ( id, code, description ) values ( GENDER_TYPES_ID.nextval, 'M', 'Male' ); 7 | insert into GENDER_TYPES ( id, code, description ) values ( GENDER_TYPES_ID.nextval, 'U', 'Unknown' ); 8 | commit; 9 | 10 | SYS.DBMS_STATS.gather_table_stats(USER, 'GENDER_TYPES'); 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/gender_types.tab: -------------------------------------------------------------------------------- 1 | rem gender_types.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold gender code values 4 | 5 | --drop table GENDER_TYPES; 6 | create table GENDER_TYPES ( 7 | id number(38) not null, 8 | code varchar2(30) not null, 9 | description varchar2(80) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null); 12 | 13 | --drop sequence GENDER_TYPES_ID; 14 | create sequence GENDER_TYPES_ID 15 | start with 1; 16 | 17 | alter table GENDER_TYPES add 18 | constraint GENDER_TYPES_PK 19 | primary key ( id ) 20 | using index; 21 | 22 | alter table GENDER_TYPES add 23 | constraint GENDER_TYPES_UK 24 | unique ( code ) 25 | using index; 26 | 27 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'GENDER_TYPES'); 28 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/hazard_level_types.ins: -------------------------------------------------------------------------------- 1 | rem hazard_level_types.ins 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Add code values to hazard levels 4 | 5 | insert into HAZARD_LEVEL_TYPES ( id, magnitude, code, description ) values ( HAZARD_LEVEL_TYPES_ID.nextval, 0, 'N', 'None' ); 6 | insert into HAZARD_LEVEL_TYPES ( id, magnitude, code, description ) values ( HAZARD_LEVEL_TYPES_ID.nextval, 2, 'M', 'May Be Bad' ); 7 | insert into HAZARD_LEVEL_TYPES ( id, magnitude, code, description ) values ( HAZARD_LEVEL_TYPES_ID.nextval, 4, 'B', 'Bad' ); 8 | insert into HAZARD_LEVEL_TYPES ( id, magnitude, code, description ) values ( HAZARD_LEVEL_TYPES_ID.nextval, 6, 'U', 'Unknown' ); 9 | insert into HAZARD_LEVEL_TYPES ( id, magnitude, code, description ) values ( HAZARD_LEVEL_TYPES_ID.nextval, 8, 'R', 'Really Bad' ); 10 | insert into HAZARD_LEVEL_TYPES ( id, magnitude, code, description ) values ( HAZARD_LEVEL_TYPES_ID.nextval, 10, 'W', 'Wholly Crap (as not to offend anyone)' ); 11 | commit; 12 | 13 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'HAZARD_LEVEL_TYPES'); 14 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/hazard_level_types.tab: -------------------------------------------------------------------------------- 1 | rem hazard_level_types.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a hazard level code table 4 | 5 | --drop table HAZARD_LEVEL_TYPES; 6 | create table HAZARD_LEVEL_TYPES ( 7 | id number(38) not null, 8 | magnitude number(38) not null, 9 | code varchar2(30) not null, 10 | description varchar2(80) not null, 11 | active_date date default SYSDATE not null, 12 | inactive_date date default '31-DEC-9999' not null); 13 | 14 | --drop sequence HAZARD_LEVEL_TYPES_ID; 15 | create sequence HAZARD_LEVEL_TYPES_ID 16 | start with 1; 17 | 18 | alter table HAZARD_LEVEL_TYPES add 19 | constraint HAZARD_LEVEL_TYPES_PK 20 | primary key ( id ) 21 | using index; 22 | 23 | alter table HAZARD_LEVEL_TYPES add 24 | constraint HAZARD_LEVEL_TYPES_UK 25 | unique ( code ) 26 | using index; 27 | 28 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'HAZARD_LEVEL_TYPES'); 29 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/logical_assignments.tab: -------------------------------------------------------------------------------- 1 | rem logical_assignments.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | --drop table LOGICAL_ASSIGNMENTS; 6 | create table LOGICAL_ASSIGNMENTS ( 7 | id number(38) not null, 8 | worker_id number(38) not null, 9 | logical_workplace_id number(38) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null ); 12 | 13 | --drop sequence LOGICAL_ASSIGNMENTS_ID; 14 | create sequence LOGICAL_ASSIGNMENTS_ID 15 | start with 1; 16 | 17 | alter table LOGICAL_ASSIGNMENTS add 18 | constraint LOGICAL_ASSIGNMENTS_PK 19 | primary key ( id ) 20 | using index; 21 | 22 | alter table LOGICAL_ASSIGNMENTS add 23 | constraint LOGICAL_ASSIGNMENTS_UK 24 | unique ( 25 | worker_id, 26 | active_date ) 27 | using index; 28 | 29 | alter table LOGICAL_ASSIGNMENTS add 30 | constraint LOGICAL_ASSIGNMENTS_FK1 31 | foreign key ( worker_id ) 32 | references WORKERS ( id ); 33 | 34 | alter table LOGICAL_ASSIGNMENTS add 35 | constraint LOGICAL_ASSIGNMENTS_FK2 36 | foreign key ( logical_workplace_id ) 37 | references LOGICAL_WORKPLACES ( id ); 38 | 39 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'LOGICAL_ASSIGNMENTS'); 40 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/logical_workplaces.tab: -------------------------------------------------------------------------------- 1 | rem logical_workplaces.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | --drop table LOGICAL_WORKPLACES; 6 | create table LOGICAL_WORKPLACES ( 7 | id number(38) not null, 8 | parent_id number(38), 9 | id_context varchar2(100) not null, 10 | workplace_type_id number not null, 11 | code varchar2(30) not null, 12 | name varchar2(80) not null, 13 | active_date date default SYSDATE not null, 14 | inactive_date date default '31-DEC-9999' not null ); 15 | 16 | --drop sequence LOGICAL_WORKPLACES_ID; 17 | create sequence LOGICAL_WORKPLACES_ID 18 | start with 1; 19 | 20 | alter table LOGICAL_WORKPLACES add 21 | constraint LOGICAL_WORKPLACES_PK 22 | primary key ( 23 | id ) 24 | using index; 25 | 26 | alter table LOGICAL_WORKPLACES add 27 | constraint LOGICAL_WORKPLACES_UK1 28 | unique ( 29 | id_context ) 30 | using index; 31 | 32 | alter table LOGICAL_WORKPLACES add 33 | constraint LOGICAL_WORKPLACES_UK2 34 | unique ( 35 | code, 36 | name, 37 | active_date ) 38 | using index; 39 | 40 | alter table LOGICAL_WORKPLACES add 41 | constraint LOGICAL_WORKPLACES_FK1 42 | foreign key ( parent_id ) 43 | references LOGICAL_WORKPLACES ( id ); 44 | 45 | alter table LOGICAL_WORKPLACES add 46 | constraint LOGICAL_WORKPLACES_FK2 47 | foreign key ( workplace_type_id ) 48 | references WORKPLACE_TYPES ( id ); 49 | 50 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'LOGICAL_WORKPLACES'); 51 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/physical_assignments.tab: -------------------------------------------------------------------------------- 1 | rem physical_assignments.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold physical workplace assignments 4 | 5 | --drop table PHYSICAL_ASSIGNMENTS; 6 | create table PHYSICAL_ASSIGNMENTS ( 7 | id number(38) not null, 8 | worker_id number(38) not null, 9 | physical_workplace_id number(38) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null); 12 | 13 | --drop sequence PHYSICAL_ASSIGNMENTS_ID; 14 | create sequence PHYSICAL_ASSIGNMENTS_ID 15 | start with 1; 16 | 17 | alter table PHYSICAL_ASSIGNMENTS add 18 | constraint PHYSICAL_ASSIGNMENTS_PK 19 | primary key ( id ) 20 | using index; 21 | 22 | alter table PHYSICAL_ASSIGNMENTS add 23 | constraint PHYSICAL_ASSIGNMENTS_UK 24 | unique ( 25 | worker_id, 26 | active_date ) 27 | using index; 28 | 29 | alter table PHYSICAL_ASSIGNMENTS add 30 | constraint PHYSICAL_ASSIGNMENTS_FK1 31 | foreign key ( worker_id ) 32 | references WORKERS ( id ); 33 | 34 | alter table PHYSICAL_ASSIGNMENTS add 35 | constraint PHYSICAL_ASSIGNMENTS_FK2 36 | foreign key ( physical_workplace_id ) 37 | references PHYSICAL_WORKPLACES ( id ); 38 | 39 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'PHYSICAL_ASSIGNMENTS'); 40 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/physical_workplaces.tab: -------------------------------------------------------------------------------- 1 | rem physical_workplaces.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold physical workplaces 4 | 5 | --drop table PHYSICAL_WORKPLACES; 6 | create table PHYSICAL_WORKPLACES ( 7 | id number(38) not null, 8 | workplace_type_id number(38) not null, 9 | id_context varchar2(100) not null, 10 | parent_id number(38), 11 | code varchar2(30) not null, 12 | name varchar2(80) not null, 13 | active_date date default SYSDATE not null, 14 | inactive_date date default '31-DEC-9999' not null); 15 | 16 | --drop sequence PHYSICAL_WORKPLACES_ID; 17 | create sequence PHYSICAL_WORKPLACES_ID 18 | start with 1; 19 | 20 | alter table PHYSICAL_WORKPLACES add 21 | constraint PHYSICAL_WORKPLACES_PK 22 | primary key ( id ) 23 | using index; 24 | 25 | alter table PHYSICAL_WORKPLACES add 26 | constraint PHYSICAL_WORKPLACES_UK 27 | unique ( id_context ) 28 | using index; 29 | 30 | alter table PHYSICAL_WORKPLACES add 31 | constraint PHYSICAL_WORKPLACES_FK1 32 | foreign key ( parent_id ) 33 | references PHYSICAL_WORKPLACES ( id ); 34 | 35 | alter table PHYSICAL_WORKPLACES add 36 | constraint PHYSICAL_WORKPLACES_FK2 37 | foreign key ( workplace_type_id ) 38 | references WORKPLACE_TYPES ( id ); 39 | 40 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'PHYSICAL_WORKPLACES'); 41 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/substances.ins: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter01/substances.ins -------------------------------------------------------------------------------- /source_20150125/Chapter01/substances.tab: -------------------------------------------------------------------------------- 1 | rem substances.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold substances 4 | 5 | -- drop table SUBSTANCES; 6 | create table SUBSTANCES ( 7 | id number(38) not null, 8 | cas_number varchar2(30) not null, 9 | name varchar2(80) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null); 12 | 13 | -- drop sequence SUBSTANCES_ID; 14 | create sequence SUBSTANCES_ID 15 | start with 1; 16 | 17 | alter table SUBSTANCES add 18 | constraint SUBSTANCES_PK 19 | primary key ( id ) 20 | using index; 21 | 22 | alter table SUBSTANCES add 23 | constraint SUBSTANCES_UK 24 | unique ( 25 | cas_number, 26 | name ) 27 | using index; 28 | 29 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'SUBSTANCES'); 30 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/task_substances.tab: -------------------------------------------------------------------------------- 1 | rem task_substances.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold the substances assicated with a task 4 | 5 | -- drop table TASK_SUBSTANCES; 6 | create table TASK_SUBSTANCES ( 7 | id number(38) not null, 8 | task_id number(38) not null, 9 | substance_id number(38) not null, 10 | hazard_level_type_id number(38) not null, 11 | active_date date default SYSDATE not null, 12 | inactive_date date default '31-DEC-9999' not null); 13 | 14 | -- drop sequence TASK_SUBSTANCES_ID; 15 | create sequence TASK_SUBSTANCES_ID 16 | start with 1; 17 | 18 | alter table TASK_SUBSTANCES add 19 | constraint TASK_SUBSTANCES_PK 20 | primary key ( id ) 21 | using index; 22 | 23 | alter table TASK_SUBSTANCES add 24 | constraint TASK_SUBSTANCES_UK 25 | unique ( 26 | task_id, 27 | substance_id, 28 | active_date ) 29 | using index; 30 | 31 | alter table TASK_SUBSTANCES add 32 | constraint TASK_SUBSTANCES_FK1 33 | foreign key ( task_id ) 34 | references TASKS ( id ); 35 | 36 | alter table TASK_SUBSTANCES add 37 | constraint TASK_SUBSTANCES_FK2 38 | foreign key ( substance_id ) 39 | references SUBSTANCES ( id ); 40 | 41 | alter table TASK_SUBSTANCES add 42 | constraint TASK_SUBSTANCES_FK3 43 | foreign key ( hazard_level_type_id ) 44 | references HAZARD_LEVEL_TYPES ( id ); 45 | 46 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'TASK_SUBSTANCES'); 47 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/tasks.tab: -------------------------------------------------------------------------------- 1 | rem tasks.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold task definitions 4 | 5 | -- drop table TASKS; 6 | create table TASKS ( 7 | id number(38) not null, 8 | name varchar2(80) not null, 9 | narrative varchar2(2000) not null, 10 | hazard_level_type_id number(38) not null, 11 | active_date date default SYSDATE not null, 12 | inactive_date date default '31-DEC-9999' not null); 13 | 14 | -- drop sequence TASKS_ID; 15 | create sequence TASKS_ID 16 | start with 1; 17 | 18 | alter table TASKS add 19 | constraint TASKS_PK 20 | primary key ( id ) 21 | using index; 22 | 23 | alter table TASKS add 24 | constraint TASKS_UK 25 | unique ( name ) 26 | using index; 27 | 28 | alter table TASKS add 29 | constraint TASKS_FK1 30 | foreign key ( hazard_level_type_id ) 31 | references HAZARD_LEVEL_TYPES ( id ); 32 | 33 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'TASKS'); 34 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/work_assignments.tab: -------------------------------------------------------------------------------- 1 | rem work_assignments.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold work assignments 4 | 5 | --drop table WORK_ASSIGNMENTS; 6 | create table WORK_ASSIGNMENTS ( 7 | id number(38) not null, 8 | worker_id number(38) not null, 9 | work_id number(38) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null); 12 | 13 | --drop sequence WORK_ASSIGNMENTS_ID; 14 | create sequence WORK_ASSIGNMENTS_ID 15 | start with 1; 16 | 17 | alter table WORK_ASSIGNMENTS add 18 | constraint WORK_ASSIGNMENTS_PK 19 | primary key ( 20 | id ) 21 | using index; 22 | 23 | alter table WORK_ASSIGNMENTS add 24 | constraint WORK_ASSIGNMENTS_UK 25 | unique ( 26 | worker_id, 27 | active_date ) 28 | using index; 29 | 30 | alter table WORK_ASSIGNMENTS add 31 | constraint WORK_ASSIGNMENTS_FK1 32 | foreign key ( worker_id ) 33 | references WORKERS ( id ); 34 | 35 | alter table WORK_ASSIGNMENTS add 36 | constraint WORK_ASSIGNMENTS_FK2 37 | foreign key ( work_id ) 38 | references WORKS ( id ); 39 | 40 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORK_ASSIGNMENTS'); 41 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/work_tasks.tab: -------------------------------------------------------------------------------- 1 | rem work_tasks.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold the tasks associated with a work definition 4 | 5 | -- drop table WORK_TASKS; 6 | create table WORK_TASKS ( 7 | id number(38) not null, 8 | work_id number(38) not null, 9 | task_id number(38) not null, 10 | hazard_level_type_id number(38) not null, 11 | active_date date default SYSDATE not null, 12 | inactive_date date default '31-DEC-9999' not null); 13 | 14 | -- drop sequence WORK_TASKS_ID; 15 | create sequence WORK_TASKS_ID 16 | start with 1; 17 | 18 | alter table WORK_TASKS add 19 | constraint WORK_TASKS_PK 20 | primary key ( id ) 21 | using index; 22 | 23 | alter table WORK_TASKS add 24 | constraint WORK_TASKS_UK 25 | unique ( 26 | work_id, 27 | task_id, 28 | active_date ) 29 | using index; 30 | 31 | alter table WORK_TASKS add 32 | constraint WORK_TASKS_FK1 33 | foreign key ( work_id ) 34 | references WORKS ( id ); 35 | 36 | alter table WORK_TASKS add 37 | constraint WORK_TASKS_FK2 38 | foreign key ( task_id ) 39 | references TASKS ( id ); 40 | 41 | alter table WORK_TASKS add 42 | constraint WORK_TASKS_FK3 43 | foreign key ( hazard_level_type_id ) 44 | references HAZARD_LEVEL_TYPES ( id ); 45 | 46 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORK_TASKS'); 47 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/worker_types.ins: -------------------------------------------------------------------------------- 1 | rem worker_types.ins 2 | rem by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | insert into WORKER_TYPES ( 6 | id, 7 | code, 8 | description ) 9 | values ( 10 | WORKER_TYPES_ID.nextval, 11 | 'C', 12 | 'Contractor' ); 13 | 14 | insert into WORKER_TYPES ( 15 | id, 16 | code, 17 | description ) 18 | values ( 19 | WORKER_TYPES_ID.nextval, 20 | 'E', 21 | 'Employee' ); 22 | 23 | insert into WORKER_TYPES ( 24 | id, 25 | code, 26 | description ) 27 | values ( 28 | WORKER_TYPES_ID.nextval, 29 | 'U', 30 | 'Unknown' ); 31 | 32 | commit; 33 | 34 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKER_TYPES'); 35 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/worker_types.sql: -------------------------------------------------------------------------------- 1 | rem worker_types.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | column code format a4; 6 | column description format a13; 7 | column active_date format a13; 8 | column inactive_date format a13; 9 | 10 | select * 11 | from WORKER_TYPES 12 | order by code; 13 | 14 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/worker_types.tab: -------------------------------------------------------------------------------- 1 | rem worker_types.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | --drop table WORKER_TYPES; 6 | create table WORKER_TYPES ( 7 | id number(38) not null, 8 | code varchar2(30) not null, 9 | description varchar2(80) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null); 12 | 13 | --drop sequence WORKER_TYPES_ID; 14 | create sequence WORKER_TYPES_ID 15 | start with 1; 16 | 17 | alter table WORKER_TYPES add 18 | constraint WORKER_TYPES_PK 19 | primary key ( id ) 20 | using index; 21 | 22 | alter table WORKER_TYPES add 23 | constraint WORKER_TYPES_UK 24 | unique ( code, active_date ) 25 | using index; 26 | 27 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKER_TYPES'); 28 | 29 | grant all on WORKER_TYPES to public; 30 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/workers.tab: -------------------------------------------------------------------------------- 1 | rem workers.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | --drop table WORKERS; 6 | create table WORKERS ( 7 | id number(38) not null, 8 | worker_type_id number(38) not null, 9 | external_id varchar2(30) not null, 10 | first_name varchar2(30) not null, 11 | middle_name varchar2(30), 12 | last_name varchar2(30) not null, 13 | name varchar2(100) not null, 14 | birth_date date not null, 15 | gender_type_id number not null ); 16 | 17 | --drop sequence WORKERS_ID; 18 | create sequence WORKERS_ID 19 | start with 1; 20 | 21 | --drop sequence EXTERNAL_ID_SEQ; 22 | create sequence EXTERNAL_ID_SEQ 23 | start with 100000000 order; 24 | 25 | alter table WORKERS add 26 | constraint WORKERS_PK 27 | primary key ( id ) 28 | using index; 29 | 30 | alter table WORKERS add 31 | constraint WORKERS_UK1 32 | unique ( external_id ) 33 | using index; 34 | 35 | alter table WORKERS add 36 | constraint WORKERS_UK2 37 | unique ( 38 | name, 39 | birth_date, 40 | gender_type_id ) 41 | using index; 42 | 43 | alter table WORKERS add 44 | constraint WORKERS_FK1 45 | foreign key ( worker_type_id ) 46 | references WORKER_TYPES ( id ); 47 | 48 | alter table WORKERS add 49 | constraint WORKERS_FK2 50 | foreign key ( gender_type_id ) 51 | references GENDER_TYPES ( id ); 52 | 53 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKERS'); 54 | 55 | grant all on WORKERS to public; 56 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/workplace_types.ins: -------------------------------------------------------------------------------- 1 | rem workplace_types.ins 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Add workplace type code values 4 | 5 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'Y', 'N', 'B', 'Business Unit' ); 6 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'Y', 'N', 'C', 'Company' ); 7 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'Y', 'N', 'D', 'Department' ); 8 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'N', 'Y', 'L', 'Line' ); 9 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'N', 'Y', 'M', 'Machine' ); 10 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'N', 'Y', 'S', 'Site' ); 11 | insert into WORKPLACE_TYPES ( id, logical_indicator, physical_indicator, code, description ) values ( WORKPLACE_TYPES_ID.nextval, 'Y', 'Y', 'U', 'Unknown' ); 12 | commit; 13 | 14 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKPLACE_TYPES'); 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/workplace_types.tab: -------------------------------------------------------------------------------- 1 | rem workplace_types.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold workplace types 4 | 5 | --drop table WORKPLACE_TYPES; 6 | create table WORKPLACE_TYPES ( 7 | id number(38) not null, 8 | logical_indicator number(1) default 0 not null, 9 | physical_indicator number(1) default 0 not null, 10 | code varchar2(30) not null, 11 | description varchar2(80) not null, 12 | active_date date default SYSDATE not null, 13 | inactive_date date default '31-DEC-9999' not null); 14 | 15 | --drop sequence WORKPLACE_TYPES_ID; 16 | create sequence WORKPLACE_TYPES_ID 17 | start with 1; 18 | 19 | alter table WORKPLACE_TYPES add 20 | constraint WORKPLACE_TYPES_PK 21 | primary key ( id ) 22 | using index; 23 | 24 | alter table WORKPLACE_TYPES add 25 | constraint WORKPLACE_TYPES_UK 26 | unique ( code ) 27 | using index; 28 | 29 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKPLACE_TYPES'); 30 | -------------------------------------------------------------------------------- /source_20150125/Chapter01/works.tab: -------------------------------------------------------------------------------- 1 | rem works.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a table to hold work descriptions 4 | 5 | --drop table WORKS; 6 | create table WORKS ( 7 | id number(38) not null, 8 | code varchar2(30) not null, 9 | name varchar2(80) not null, 10 | active_date date default SYSDATE not null, 11 | inactive_date date default '31-DEC-9999' not null); 12 | 13 | --drop sequence WORKS_ID; 14 | create sequence WORKS_ID 15 | start with 1; 16 | 17 | alter table WORKS add 18 | constraint WORKS_PK 19 | primary key ( 20 | id ) 21 | using index; 22 | 23 | alter table WORKS add 24 | constraint WORKS_UK 25 | unique ( 26 | code, 27 | name ) 28 | using index; 29 | 30 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKS'); 31 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/README.txt: -------------------------------------------------------------------------------- 1 | README.txt for Chapter 2 2 | by Donald J. Bales on 2014-10-20 3 | 4 | This is the second of eleven example source directories for the book 5 | "Beginning Oracle PL/SQL: From Novice to Professional". Each example source 6 | directory for this book contains the source code for the examples in the book, 7 | including solutions to the exercises. 8 | 9 | 10 | OBJECT NAME DESCRIPTION 11 | --------------------------------------- -------------------------------------- 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/RPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter02/RPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter02/anonymous.sql: -------------------------------------------------------------------------------- 1 | -- This is an anonymous procedure, so it has no name 2 | declare 3 | /* 4 | You declare local cursors, variables, and methods here, 5 | but you don't need to have a declaration section. 6 | */ 7 | begin 8 | -- You write your logic here 9 | 10 | null; -- Ahhh, you've got to have at least one command! 11 | exception 12 | when NO_DATA_FOUND then 13 | raise_application_error(-20000, 'Hey, No Data Found!'); 14 | end; 15 | / 16 | -- the forward slash on a line by itself says execute this procedure 17 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter02/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter02/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter02/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter02/create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | @to_mmsddsyyyy_or_null.fun 13 | @to_number_or_null.fun 14 | 15 | @pl.prc 16 | @wait.prc 17 | 18 | @date_.pks 19 | @number_.pks 20 | 21 | @date_.pkb 22 | @number_.pkb 23 | 24 | spool off; 25 | set echo off; 26 | @ci.sql 27 | @ci.sql 28 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/date_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DATE_ as 2 | /* 3 | date_.pks 4 | by Donald J. Bales on 2014-10-20 5 | Additional DATE data type methods. 6 | */ 7 | 8 | -- The maximum and minimum dates values. 9 | 10 | d_MAX constant date := 11 | to_date('99991231235959', 'YYYYMMDDHH24MISS'); 12 | d_MIN constant date := 13 | to_date('-47120101', 'SYYYYMMDD'); 14 | 15 | 16 | -- Returns the specified date with the time set to 23:59:59, therefore, 17 | -- the end of the day. 18 | 19 | FUNCTION end_of_day( 20 | aid_date in date ) 21 | return date; 22 | 23 | 24 | -- Returns constant d_MAX. This is useful in SQL statements where the 25 | -- constant DATE_.d_MAX is not accessible. 26 | 27 | FUNCTION get_max 28 | return date; 29 | 30 | 31 | -- Returns constant d_MIN. This is useful in SQL statements where the 32 | -- constant DATE_.d_MIN is not accessible. 33 | 34 | FUNCTION get_min 35 | return date; 36 | 37 | 38 | -- Text-based help for this package. "set serveroutput on" in SQL*Plus. 39 | 40 | PROCEDURE help; 41 | 42 | 43 | -- Returns a randomly generated date that exists between the years specified. 44 | 45 | FUNCTION random( 46 | ain_starting_year in number, 47 | ain_ending_year in number ) 48 | return date; 49 | 50 | 51 | -- Returns the specified date with the time set to 00:00:00, therefore, the 52 | -- start of the day. 53 | 54 | FUNCTION start_of_day( 55 | aid_date in date ) 56 | return date; 57 | 58 | 59 | -- Test unit for this package. 60 | 61 | PROCEDURE test; 62 | 63 | 64 | end DATE_; 65 | / 66 | @se.sql DATE_ 67 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter02/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/number_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body NUMBER_ as 2 | /* 3 | number_.pkb 4 | by Donald J. Bales on 2014-10-20 5 | A utility package for the data type NUMBER 6 | */ 7 | 8 | FUNCTION to_number_or_null ( 9 | aiv_number in varchar2 ) 10 | return number is 11 | begin 12 | return to_number(aiv_number); 13 | exception 14 | when OTHERS then 15 | return NULL; 16 | end to_number_or_null; 17 | 18 | end NUMBER_; 19 | / 20 | @be.sql 21 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/number_.pks: -------------------------------------------------------------------------------- 1 | create or replace package NUMBER_ as 2 | /* 3 | number_.pks 4 | by Donald J. Bales on 2014-10-20 5 | A utility package for the data type NUMBER 6 | */ 7 | 8 | /* 9 | Returns the passed varchar2 as a number if it represents a number, 10 | otherwise, it returns NULL 11 | */ 12 | FUNCTION to_number_or_null ( 13 | aiv_number in varchar2 ) 14 | return number; 15 | 16 | end NUMBER_; 17 | / 18 | @se.sql 19 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/pl2.sql: -------------------------------------------------------------------------------- 1 | rem pl2.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Test unit for procedure pl 4 | 5 | declare 6 | v_max_line varchar2(32767); 7 | 8 | begin 9 | -- The next three lines initialize a variable v_max_line with 32,767 spaces. 10 | for i in 1..32767 loop 11 | v_max_line := v_max_line || ' '; 12 | end loop; 13 | 14 | pl('Test a line of text.'); 15 | 16 | pl('Test a number, such as 1?'); 17 | pl(1); 18 | 19 | pl('Test a date, such as 01/01/1980?'); 20 | pl(to_date('19800101', 'YYYYMMDD')); 21 | 22 | pl('Test a line <= 32767'); 23 | pl(v_max_line); 24 | 25 | pl('Test a line > 32767'); 26 | begin 27 | pl(v_max_line||' '); 28 | exception 29 | when OTHERS then 30 | pl(SQLERRM); 31 | end; 32 | 33 | pl('Test a multi-line'); 34 | begin 35 | pl('12345678901234567890123456789012345678901234567890'|| 36 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 37 | '12345678901234567890123456789012345678901234567890'|| 38 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 39 | '12345678901234567890123456789012345678901234567890'|| 40 | '12345678901234567890123456789012345678901234567890'); 41 | exception 42 | when OTHERS then 43 | pl(SQLERRM); 44 | end; 45 | end; 46 | / 47 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/to_mmsddsyyyy_or_null.fun: -------------------------------------------------------------------------------- 1 | create or replace FUNCTION to_mmsddsyyyy_or_null ( 2 | aiv_date in varchar2 ) 3 | return date is 4 | /* 5 | to_mmsddsyyyy_or_null.fun 6 | by Donald J. Bales on 2014-10-20 7 | An errorless to_date( ) method 8 | */ 9 | begin 10 | return to_date(aiv_date, 'MM/DD/YYYY'); 11 | exception 12 | /* 13 | There are too many possible errors, for example: 14 | ORA-01830: date format picture ends before 15 | converting entire input string 16 | ORA-01843: not a valid month 17 | ORA-01847: day of month must be between 1 18 | and last day of month 19 | ORA-01858: a non-numeric character was found 20 | where a numeric was expected 21 | so I used the exception OTHERS 22 | */ 23 | when OTHERS then 24 | return NULL; 25 | end to_mmsddsyyyy_or_null; 26 | / 27 | @fe.sql to_mmsddsyyyy_or_null; 28 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/to_mmsddsyyyy_or_null.sql: -------------------------------------------------------------------------------- 1 | rem to_mmsddsyyyy_or_null.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem FUNCTION to_mmsddsyyyy_or_null() test unit 4 | 5 | begin 6 | sys.dbms_output.put_line(to_mmsddsyyyy_or_null('01/01/1980')); 7 | sys.dbms_output.put_line(to_mmsddsyyyy_or_null('02/29/1980')); 8 | sys.dbms_output.put_line(to_mmsddsyyyy_or_null('02/29/1981')); 9 | sys.dbms_output.put_line(to_mmsddsyyyy_or_null('9/9/2006')); 10 | sys.dbms_output.put_line(to_mmsddsyyyy_or_null('9/9/9999')); 11 | sys.dbms_output.put_line(to_mmsddsyyyy_or_null('1/1/4712 BC')); 12 | end; 13 | / 14 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/to_number_or_null.fun: -------------------------------------------------------------------------------- 1 | create or replace FUNCTION to_number_or_null ( 2 | aiv_number in varchar2 ) 3 | return number is 4 | /* 5 | to_number_or_null.fun 6 | by Donald J. Bales on 2014-10-20 7 | An errorless to_number( ) method 8 | */ 9 | begin 10 | return to_number(aiv_number); 11 | exception 12 | when INVALID_NUMBER then 13 | return NULL; 14 | end to_number_or_null; 15 | / 16 | @fe.sql to_number_or_null; 17 | -------------------------------------------------------------------------------- /source_20150125/Chapter02/wait.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE wait( 2 | ain_seconds in number) is 3 | /* 4 | wait.prc 5 | by Donald J. Bales on 2014-10-20 6 | Wrapper for SYS.DBMS_LOCK.sleep() 7 | */ 8 | begin 9 | SYS.DBMS_LOCK.sleep(ain_seconds); 10 | end wait; 11 | / 12 | @pe.sql wait 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/README.txt: -------------------------------------------------------------------------------- 1 | README.txt for Chapter 2 2 | by Donald J. Bales on 2014-10-20 3 | 4 | This is the third of eleven example source directories for the book 5 | "Beginning Oracle PL/SQL: From Novice to Professional". Each example source 6 | directory for this book contains the source code for the examples in the book, 7 | including solutions to the exercises. 8 | 9 | 10 | OBJECT NAME DESCRIPTION 11 | --------------------------------------- -------------------------------------- 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/RPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter03/RPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter03/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter03/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter03/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter03/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter03/create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | @parameter.pks 13 | @scope.pks 14 | 15 | @parameter.pkb 16 | @scope.pkb 17 | 18 | spool off; 19 | set echo off; 20 | @ci.sql 21 | @ci.sql 22 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter03/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/multidimensional.sql: -------------------------------------------------------------------------------- 1 | rem multidimensional.sql 2 | rem by Don Bales on 2014-10-20 3 | rem Anonymouos PL/SQL procedure to demonstrate 4 | rem the use of nested PL/SQL tables 5 | 6 | declare 7 | 8 | TYPE name_table is table of WORKERS.name%TYPE 9 | index by binary_integer; 10 | 11 | TYPE name_record is record ( 12 | dim2 name_table ); 13 | 14 | TYPE dim1 is table of name_record 15 | index by binary_integer; 16 | 17 | t_dim1 dim1; 18 | 19 | begin 20 | t_dim1(1).dim2(1) := 'DOE, JOHN'; 21 | t_dim1(1).dim2(2) := 'DOE, JANE'; 22 | 23 | t_dim1(2).dim2(1) := 'DOUGH, JAYNE'; 24 | t_dim1(2).dim2(2) := 'DOUGH, JON'; 25 | 26 | pl(t_dim1(1).dim2(1)); 27 | pl(t_dim1(1).dim2(2)); 28 | pl(t_dim1(2).dim2(1)); 29 | pl(t_dim1(2).dim2(2)); 30 | end; 31 | / 32 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/parameter.pks: -------------------------------------------------------------------------------- 1 | create or replace package PARAMETER as 2 | /* 3 | parameter.pks 4 | by Donald J. Bales on 2014-10-20 5 | A packge to test parameter scope 6 | */ 7 | 8 | -- A function that execises the scope of parameters 9 | FUNCTION in_out_inout( 10 | aiv_in in varchar2, 11 | aov_out out varchar2, 12 | aiov_inout in out varchar2) 13 | return varchar2; 14 | 15 | 16 | -- A procedure that execises the scope of parameters 17 | PROCEDURE in_out_inout( 18 | aiv_in in varchar2, 19 | aov_out out varchar2, 20 | aiov_inout in out varchar2); 21 | 22 | 23 | end PARAMETER; 24 | / 25 | @se.sql PARAMETER 26 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/parameter.sql: -------------------------------------------------------------------------------- 1 | rem parameter.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem A test unit for package PARAMETER 4 | 5 | declare 6 | 7 | v_in varchar2(30) := 'IN'; 8 | v_out varchar2(30) := 9 | 'Na na, you can''t see me!'; 10 | v_inout varchar2(30) := 11 | 'But you can see me!'; 12 | v_return varchar2(30); 13 | 14 | begin 15 | pl('Before calling the function...'); 16 | pl('Inside test unit parameter v_in = '||v_in); 17 | pl('Inside test unit parameter v_out = '||v_out); 18 | pl('Inside test unit parameter v_inout = '||v_inout); 19 | pl('Test function PARAMETER.in_out_inout(v_in, v_out, v_inout).'); 20 | v_return := PARAMETER.in_out_inout(v_in, v_out, v_inout); 21 | pl(v_return); 22 | pl('After calling the function...'); 23 | pl('Inside test unit parameter v_in = '||v_in); 24 | pl('Inside test unit parameter v_out = '||v_out); 25 | pl('Inside test unit parameter v_inout = '||v_inout); 26 | pl('Resetting initial values...'); 27 | v_out := 'Na na, you can''t see me!'; 28 | v_inout := 'But you can see me!'; 29 | pl('Before calling the procedure...'); 30 | pl('Inside test unit parameter v_in = '||v_in); 31 | pl('Inside test unit parameter v_out = '||v_out); 32 | pl('Inside test unit parameter v_inout = '||v_inout); 33 | pl('Test procedure PARAMETER.in_out_inout(v_in, v_out, v_inout).'); 34 | PARAMETER.in_out_inout(v_in, v_out, v_inout); 35 | pl('OK'); 36 | pl('After calling the procedure...'); 37 | pl('Inside test unit parameter v_in = '||v_in); 38 | pl('Inside test unit parameter v_out = '||v_out); 39 | pl('Inside test unit parameter v_inout = '||v_inout); 40 | end; 41 | / 42 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/record.sql: -------------------------------------------------------------------------------- 1 | rem record.sql 2 | rem by Don Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to demonstrate 4 | rem the use of PL/SQL records 5 | 6 | declare 7 | 8 | TYPE name_record is record ( 9 | first_name WORKERS.first_name%TYPE, 10 | middle_name WORKERS.middle_name%TYPE, 11 | last_name WORKERS.last_name%TYPE ); 12 | 13 | TYPE name_table is table of name_record 14 | index by binary_integer; 15 | 16 | t_name name_table; 17 | 18 | begin 19 | t_name(1).first_name := 'JOHN'; 20 | t_name(1).last_name := 'DOE'; 21 | t_name(2).first_name := 'JANE'; 22 | t_name(2).last_name := 'DOE'; 23 | 24 | pl(t_name(1).last_name||', '||t_name(1).first_name); 25 | pl(t_name(2).last_name||', '||t_name(2).first_name); 26 | end; 27 | / 28 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/row.sql: -------------------------------------------------------------------------------- 1 | rem row.sql 2 | rem by Don Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to demonstrate 4 | rem the elementary use of PL/SQL tables 5 | 6 | declare 7 | 8 | TYPE name_table IS TABLE OF WORKERS%ROWTYPE 9 | INDEX BY BINARY_INTEGER; 10 | 11 | t_name name_table; 12 | 13 | n_name binary_integer; 14 | 15 | begin 16 | t_name(1).name := 'DOE, JOHN'; 17 | t_name(10).name := 'DOE, JANE'; 18 | pl(t_name(1).name); 19 | pl(t_name(10).name); 20 | pl('There are '||t_name.count()||' elements.'); 21 | n_name := t_name.first(); 22 | pl('The first element is '||n_name||'.'); 23 | n_name := t_name.next(n_name); 24 | pl('The next element is '||n_name||'.'); 25 | n_name := t_name.last(); 26 | pl('The last element is '||n_name||'.'); 27 | n_name := t_name.prior(n_name); 28 | pl('The prior element is '||n_name||'.'); 29 | if t_name.exists(1) then 30 | pl('Element 1 exists.'); 31 | end if; 32 | pl('I''m deleting element 10'); 33 | t_name.delete(10); 34 | pl('There are '||t_name.count()||' elements.'); 35 | if not t_name.exists(10) then 36 | pl('Element 10 no longer exists.'); 37 | end if; 38 | pl('There are '||t_name.count()||' elements.'); 39 | pl('I''m deleting all elements'); 40 | t_name.delete(); 41 | pl('There are '||t_name.count()||' elements.'); 42 | end; 43 | / 44 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/scope.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body SCOPE as 2 | /* 3 | scope.pkb 4 | by Donald J. Bales on 2014-10-20 5 | A package to test scope 6 | */ 7 | 8 | -- Here's an instance (or package body) variable declaration 9 | iv_scope varchar2(80) := 10 | 'I''m an instance (or package body) variable'; 11 | 12 | 13 | -- Here's an instance (or package body) function declaration 14 | FUNCTION my_scope_is_instance 15 | return varchar2 is 16 | v_answer_1 varchar2(3) := 'Yes'; 17 | begin 18 | pl(chr(9)||'Can function my_scope_is_instance see variable gv_scope?'); 19 | pl(chr(9)||gv_scope); 20 | return v_answer_1; 21 | end my_scope_is_instance; 22 | 23 | 24 | -- Here's a global (or package spec) function declaration 25 | FUNCTION my_scope_is_global 26 | return varchar2 is 27 | v_answer_2 varchar2(3) := 'Yes'; 28 | begin 29 | pl(chr(9)||'Can function my_scope_is_global see variable iv_scope?'); 30 | pl(chr(9)||iv_scope); 31 | return v_answer_2; 32 | end my_scope_is_global; 33 | 34 | 35 | -- Here's an instance (or package body) procedure declaration 36 | PROCEDURE my_scope_is_instance is 37 | v_answer_3 varchar2(3) := 'Yes'; 38 | begin 39 | pl(chr(9)||'Can procedure my_scope_is_instance see variable gv_scope?'); 40 | pl(chr(9)||gv_scope); 41 | pl(v_answer_3); 42 | end my_scope_is_instance; 43 | 44 | 45 | -- Here's a global (or package spec) procedure declaration 46 | PROCEDURE my_scope_is_global is 47 | v_answer_4 varchar2(3) := 'Yes'; 48 | begin 49 | pl(chr(9)||'Can procedure my_scope_is_global see variable iv_scope?'); 50 | pl(chr(9)||iv_scope); 51 | pl(v_answer_4); 52 | end my_scope_is_global; 53 | 54 | 55 | end SCOPE; 56 | / 57 | @se.sql SCOPE 58 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/scope.pks: -------------------------------------------------------------------------------- 1 | create or replace package SCOPE as 2 | /* 3 | scope.pks 4 | by Donald J. Bales on 2014-10-20 5 | A package to test scope 6 | */ 7 | 8 | -- Here's a global variable declaration 9 | gv_scope varchar2(80) := 10 | 'I''m a global (or package spec) variable'; 11 | 12 | -- Here's a global (or package spec) function declaration 13 | FUNCTION my_scope_is_global 14 | return varchar2; 15 | 16 | -- Here's a global (or package spec) procedure declaration 17 | PROCEDURE my_scope_is_global; 18 | 19 | 20 | end SCOPE; 21 | / 22 | @se.sql SCOPE 23 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/scope.sql: -------------------------------------------------------------------------------- 1 | rem scope.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Test unit for package scope 4 | 5 | declare 6 | 7 | -- ANONYMOUS PL/SQL BLOCK'S DECLARATION SECTION -- 8 | 9 | v_scope varchar2(40) := 10 | 'I''m a local variable'; 11 | 12 | -- This is a local (or embedded) function 13 | FUNCTION my_scope_is_local 14 | return varchar2 is 15 | v_answer_0 varchar2(3) := 'Yes'; 16 | begin 17 | return v_answer_0; 18 | end my_scope_is_local; 19 | 20 | -- This is a local (or embedded) procedure 21 | PROCEDURE my_scope_is_local is 22 | v_answer varchar2(3) := 'Yes'; 23 | begin 24 | pl(v_answer); 25 | end my_scope_is_local; 26 | 27 | begin 28 | 29 | -- ANONYMOUS PL/SQL BLOCK'S EXECUTABLE SECTION -- 30 | 31 | pl('Can I access my local variable?'); 32 | pl(v_scope); 33 | pl('Can I access SCOPE'' global variable?'); 34 | pl(SCOPE.gv_scope); 35 | pl('Can I access SCOPE'' instance variable?'); 36 | --pl(SCOPE.iv_scope); 37 | pl('No!'); 38 | 39 | pl('Can I access my local function?'); 40 | pl(my_scope_is_local()); 41 | pl('Can I access SCOPE'' global function?'); 42 | pl(SCOPE.my_scope_is_global()); 43 | pl('Can I access SCOPE'' instance function?'); 44 | --pl(SCOPE.my_scope_is_instance()); 45 | pl('No!'); 46 | 47 | pl('Can I access my local procedure?'); 48 | my_scope_is_local(); 49 | pl('Can I access SCOPE'' global procedure?'); 50 | SCOPE.my_scope_is_global(); 51 | pl('Can I access SCOPE'' instance procedure?'); 52 | --SCOPE.my_scope_is_instance(); 53 | pl('No!'); 54 | 55 | end; 56 | / 57 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/table.sql: -------------------------------------------------------------------------------- 1 | rem table.sql 2 | rem by Don Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to demonstrate 4 | rem the elementary use of PL/SQL tables 5 | 6 | declare 7 | 8 | TYPE name_table IS TABLE OF WORKERS.name%TYPE 9 | INDEX BY BINARY_INTEGER; 10 | 11 | t_name name_table; 12 | 13 | n_name binary_integer; 14 | 15 | begin 16 | t_name(1) := 'DOE, JOHN'; 17 | t_name(10) := 'DOE, JANE'; 18 | 19 | pl(t_name(1)); 20 | pl(t_name(10)); 21 | pl('There are '||t_name.count()||' elements.'); 22 | n_name := t_name.first(); 23 | pl('The first element is '||n_name||'.'); 24 | n_name := t_name.next(n_name); 25 | pl('The next element is '||n_name||'.'); 26 | n_name := t_name.last(); 27 | pl('The last element is '||n_name||'.'); 28 | n_name := t_name.prior(n_name); 29 | pl('The prior element is '||n_name||'.'); 30 | if t_name.exists(1) then 31 | pl('Element 1 exists.'); 32 | end if; 33 | pl('I''m deleting element 10'); 34 | t_name.delete(10); 35 | pl('There are '||t_name.count()||' elements.'); 36 | if not t_name.exists(10) then 37 | pl('Element 10 no longer exists.'); 38 | end if; 39 | pl('There are '||t_name.count()||' elements.'); 40 | pl('I''m deleting all elements'); 41 | t_name.delete(); 42 | pl('There are '||t_name.count()||' elements.'); 43 | end; 44 | / 45 | -------------------------------------------------------------------------------- /source_20150125/Chapter03/workers_variables.sql: -------------------------------------------------------------------------------- 1 | declare 2 | n_id WORKERS.id%TYPE := 1; 3 | n_worker_type_id WORKERS.worker_type_id%TYPE := 3; 4 | v_external_id WORKERS.external_id%TYPE := '6305551212'; 5 | v_first_name WORKERS.first_name%TYPE := 'JANE'; 6 | v_middle_name WORKERS.middle_name%TYPE := 'E'; 7 | v_last_name WORKERS.last_name%TYPE := 'DOE'; 8 | v_name WORKERS.name%TYPE := 'JANEDOEE'; 9 | d_birth_date WORKERS.birth_date%TYPE := 10 | to_date('19800101', 'YYYYMMDD'); 11 | n_gender_type_id WORKERS.gender_type_id%TYPE := 1; 12 | begin 13 | null; 14 | end; 15 | / 16 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/README.txt: -------------------------------------------------------------------------------- 1 | README.txt for Chapter 2 2 | by Donald J. Bales on 2014-10-20 3 | 4 | This is the fourth of eleven example source directories for the book 5 | "Beginning Oracle PL/SQL: From Novice to Professional". Each example source 6 | directory for this book contains the source code for the examples in the book, 7 | including solutions to the exercises. 8 | 9 | 10 | OBJECT NAME DESCRIPTION 11 | --------------------------------------- -------------------------------------- 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/RPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter04/RPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter04/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter04/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter04/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter04/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter04/create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | spool off; 13 | set echo off; 14 | @ci.sql 15 | @ci.sql 16 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/delete.sql: -------------------------------------------------------------------------------- 1 | rem delete.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to delete 4 | rem rows using PL/SQL literals and variables 5 | 6 | set serveroutput on size 1000000; 7 | 8 | declare 9 | 10 | -- I'll use this variable to hold the result 11 | -- of the SQL delete statement. 12 | n_count number; 13 | 14 | v_code GENDER_TYPES.code%TYPE := 'M'; 15 | 16 | begin 17 | 18 | begin 19 | delete from WORKERS d 20 | where d.name = 'DOE, JOHN J.' -- a literal 21 | and d.birth_date = to_date('19800101', 'YYYYMMDD') -- a function 22 | and d.gender_type_id = ( -- a sub-query 23 | select c.id 24 | from GENDER_TYPES c 25 | where c.code = v_code ); -- a variable 26 | 27 | n_count := sql%rowcount; 28 | exception 29 | when OTHERS then 30 | raise_application_error(-20001, SQLERRM|| 31 | ' on delete WORKERS'|| 32 | ' in filename delete.sql'); 33 | end; 34 | 35 | pl(to_char(n_count)||' row(s) deleted.'); 36 | end; 37 | / 38 | 39 | commit; 40 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter04/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/multidimensional.sql: -------------------------------------------------------------------------------- 1 | rem multidimensional.sql 2 | rem by Don Bales on 2014-10-20 3 | rem Anonymouos PL/SQL procedure to demonstrate 4 | rem the use of nested PL/SQL tables 5 | 6 | declare 7 | 8 | TYPE name_table is table of WORKERS.name%TYPE 9 | index by binary_integer; 10 | 11 | TYPE name_record is record ( 12 | dim2 name_table ); 13 | 14 | TYPE dim1 is table of name_record 15 | index by binary_integer; 16 | 17 | t_dim1 dim1; 18 | 19 | begin 20 | t_dim1(1).dim2(1) := 'DOE, JOHN'; 21 | t_dim1(1).dim2(2) := 'DOE, JANE'; 22 | 23 | t_dim1(2).dim2(1) := 'DOUGH, JAYNE'; 24 | t_dim1(2).dim2(2) := 'DOUGH, JON'; 25 | 26 | pl(t_dim1(1).dim2(1)); 27 | pl(t_dim1(1).dim2(2)); 28 | pl(t_dim1(2).dim2(1)); 29 | pl(t_dim1(2).dim2(2)); 30 | end; 31 | / 32 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/select_the_doe_family.sql: -------------------------------------------------------------------------------- 1 | rem select_the_doe_family.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to select 4 | rem the first names for the Doe family from 5 | rem the Worker table. 6 | 7 | set serveroutput on size 1000000; 8 | 9 | declare 10 | 11 | v_first_name WORKERS.first_name%TYPE; 12 | n_id WORKERS.id%TYPE; 13 | 14 | -- A local function that will be called over-and-over again 15 | -- to find the next first_name for the specified id 16 | -- and last_name. 17 | FUNCTION get_first_name( 18 | aion_id in out WORKERS.id%TYPE, 19 | aiv_last_name in WORKERS.last_name%TYPE) 20 | return WORKERS.first_name%TYPE is 21 | 22 | v_first_name WORKERS.first_name%TYPE; 23 | 24 | begin 25 | -- Use SQL pseudo-column rownum in order 26 | -- to limit the SELECT to the first row 27 | select id, 28 | first_name 29 | into aion_id, 30 | v_first_name 31 | from WORKERS 32 | where id > aion_id 33 | and last_name like aiv_last_name||'%' 34 | and rownum = 1; 35 | 36 | return v_first_name; 37 | exception 38 | when NO_DATA_FOUND then 39 | return v_first_name; 40 | when OTHERS then 41 | raise_application_error(-20001, SQLERRM|| 42 | ' on select WORKERS'|| 43 | ' in show_worker'); 44 | end get_first_name; 45 | 46 | begin 47 | -- Keep track of the primary key so you 48 | -- only retrieve the SELECTed row once 49 | n_id := 0; 50 | -- Loop until there's NO_DATA_FOUND 51 | loop 52 | -- get the first name from the local function 53 | v_first_name := get_first_name(n_id, 'DOE'); 54 | -- detect NO_DATA_FOUND 55 | if v_first_name is NULL then 56 | exit; -- Exit the loop 57 | end if; 58 | -- show the first_name 59 | pl(v_first_name); 60 | end loop; 61 | end; 62 | / 63 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/table.sql: -------------------------------------------------------------------------------- 1 | rem table.sql 2 | rem by Don Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to demonstrate 4 | rem the elementary use of PL/SQL tables 5 | 6 | declare 7 | 8 | TYPE name_table IS TABLE OF WORKERS.name%TYPE 9 | INDEX BY BINARY_INTEGER; 10 | 11 | t_name name_table; 12 | 13 | n_name binary_integer; 14 | 15 | begin 16 | t_name(1) := 'DOE, JOHN'; 17 | t_name(10) := 'DOE, JANE'; 18 | 19 | pl(t_name(1)); 20 | pl(t_name(10)); 21 | pl('There are '||t_name.count()||' elements.'); 22 | n_name := t_name.first(); 23 | pl('The first element is '||n_name||'.'); 24 | n_name := t_name.next(n_name); 25 | pl('The next element is '||n_name||'.'); 26 | n_name := t_name.last(); 27 | pl('The last element is '||n_name||'.'); 28 | n_name := t_name.prior(n_name); 29 | pl('The prior element is '||n_name||'.'); 30 | if t_name.exists(1) then 31 | pl('Element 1 exists.'); 32 | end if; 33 | pl('I''m deleting element 10'); 34 | t_name.delete(10); 35 | pl('There are '||t_name.count()||' elements.'); 36 | if not t_name.exists(10) then 37 | pl('Element 10 no longer exists.'); 38 | end if; 39 | pl('There are '||t_name.count()||' elements.'); 40 | pl('I''m deleting all elements'); 41 | t_name.delete(); 42 | pl('There are '||t_name.count()||' elements.'); 43 | end; 44 | / 45 | -------------------------------------------------------------------------------- /source_20150125/Chapter04/update_multiple.sql: -------------------------------------------------------------------------------- 1 | update WORKERS u 2 | set ( u.worker_type_id, u.gender_type_id ) = ( 3 | select c1.id, c2.id 4 | from WORKER_TYPES c1, 5 | GENDER_TYPES c2 6 | where c1.code = decode(instr(u.first_name, 'JOHN'), 0, 'E', 'C') 7 | and c2.code = decode(instr(u.first_name, 'JOHN'), 0, 'F', 'M') ) 8 | where u.last_name = 'DOE'; 9 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/README.txt: -------------------------------------------------------------------------------- 1 | README.txt for Chapter 5 2 | by Donald J. Bales on 2014-10-20 3 | 4 | This is the fifth of eleven example source directories for the book 5 | "Beginning Oracle PL/SQL: From Novice to Professional". Each example source 6 | directory for this book contains the source code for the examples in the book, 7 | including solutions to the exercises. 8 | 9 | 10 | OBJECT NAME DESCRIPTION 11 | --------------------------------------- -------------------------------------- 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/RPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter05/RPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter05/a_thru_z.ins: -------------------------------------------------------------------------------- 1 | rem a_thru_z.ins 2 | rem by Donald J. Bales on 2014-10-20 3 | rem The letters A through Z 4 | 5 | declare 6 | 7 | begin 8 | for i in ascii('A')..ascii('Z') loop 9 | insert into A_THRU_Z ( 10 | letter ) 11 | values ( 12 | chr(i)); 13 | end loop; 14 | commit; 15 | end; 16 | / 17 | 18 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'A_THRU_Z'); 19 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/a_thru_z.tab: -------------------------------------------------------------------------------- 1 | rem a_thru_z.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem The letters A through Z 4 | 5 | exec ddl_.dtab('A_THRU_Z'); 6 | create table A_THRU_Z ( 7 | letter varchar2(1)); 8 | 9 | alter table A_THRU_Z add 10 | constraint A_THRU_Z_PK 11 | primary key ( 12 | letter ) 13 | using index; 14 | 15 | grant select on A_THRU_Z to public; 16 | 17 | @a_thru_z.ins 18 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/bulk_collect_the_doe_family.sql: -------------------------------------------------------------------------------- 1 | rem bulk_collect_the_doe_family.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to select 4 | rem the first names for the Doe family from 5 | rem the Workers table. 6 | 7 | set serveroutput on size 1000000; 8 | 9 | declare 10 | 11 | TYPE worker_table is table of WORKERS.first_name%TYPE 12 | index by binary_integer; 13 | 14 | t_workers worker_table; 15 | 16 | begin 17 | select first_name 18 | BULK COLLECT 19 | into t_workers 20 | from WORKERS 21 | where last_name like 'DOE%' 22 | order by id; 23 | 24 | for i in t_workers.first..t_workers.last loop 25 | pl(t_workers(i)); 26 | end loop; 27 | end; 28 | / 29 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter05/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter05/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter05/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter05/create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | @a_thru_z.tab 13 | @top_100_first_names.tab 14 | @top_100_last_names.tab 15 | 16 | @top_100_first_names.ins 17 | @top_100_last_names.ins 18 | @a_thru_z.ins 19 | 20 | @gender_type.pks 21 | @worker.pks 22 | @worker_type.pks 23 | 24 | @gender_type.pkb 25 | @worker.pkb 26 | @worker_type.pkb 27 | 28 | @workers_cursor_for_loop.ins 29 | @workers_bulk_collect.ins 30 | @workers_forall.ins 31 | @workers.ins 32 | 33 | spool off; 34 | set echo off; 35 | @ci.sql 36 | @ci.sql 37 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/cursor_bulk_collect_the_doe_family.sql: -------------------------------------------------------------------------------- 1 | rem cursor_bulk_collect_the_doe_family.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to select 4 | rem the first names for the Doe family from 5 | rem the Workers table. 6 | 7 | set serveroutput on size 1000000; 8 | 9 | declare 10 | 11 | cursor c_workers( 12 | aiv_last_name in WORKERS.last_name%TYPE) is 13 | select first_name 14 | from WORKERS 15 | where last_name like aiv_last_name||'%' 16 | order by id; 17 | 18 | TYPE c_worker_table is table of c_workers%ROWTYPE 19 | index by binary_integer; 20 | 21 | t_workers c_worker_table; 22 | 23 | begin 24 | open c_workers('DOE'); 25 | loop 26 | fetch c_workers bulk collect into t_workers limit 2; 27 | 28 | exit when t_workers.count = 0; 29 | 30 | for i in t_workers.first..t_workers.last loop 31 | pl(t_workers(i).first_name); 32 | end loop; 33 | end loop; 34 | end; 35 | / 36 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/cursor_for_loop_the_doe_family.sql: -------------------------------------------------------------------------------- 1 | rem cursor_for_loop_the_doe_family.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to select 4 | rem the first names for the Doe family from 5 | rem the Workers table. 6 | 7 | set serveroutput on size 1000000; 8 | 9 | declare 10 | 11 | cursor c_workers( 12 | aiv_last_name in WORKERS.last_name%TYPE) is 13 | select first_name 14 | from WORKERS 15 | where last_name like aiv_last_name||'%' 16 | order by id; 17 | 18 | begin 19 | for r_worker in c_workers('DOE') loop 20 | pl(r_worker.first_name); 21 | end loop; 22 | end; 23 | / 24 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/cursor_the_doe_family.sql: -------------------------------------------------------------------------------- 1 | rem cursor_the_doe_family.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem An anonymous PL/SQL procedure to select 4 | rem the first names for the Doe family from 5 | rem the Worker table. 6 | 7 | set serveroutput on size 1000000; 8 | 9 | declare 10 | 11 | cursor c_workers( 12 | aiv_last_name in WORKERS.last_name%TYPE) is 13 | select first_name 14 | from WORKERS 15 | where last_name like aiv_last_name||'%' 16 | order by id; 17 | 18 | v_first_name WORKERS.first_name%TYPE; 19 | 20 | begin 21 | open c_workers('DOE'); 22 | loop 23 | fetch c_workers into v_first_name; 24 | 25 | if c_workers%notfound then 26 | close c_workers; 27 | exit; 28 | end if; 29 | 30 | pl(v_first_name); 31 | end loop; 32 | end; 33 | / 34 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter05/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/gender_type.pks: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE GENDER_TYPE as 2 | /* 3 | gender_type.pks 4 | by Don Bales on 2014-10-20 5 | Table GENDER_TYPES's methods. 6 | */ 7 | 8 | 9 | /* 10 | Gets the code and decription values for the specified id. 11 | */ 12 | PROCEDURE get_code_descr( 13 | ain_id in GENDER_TYPES.id%TYPE, 14 | aov_code out GENDER_TYPES.code%TYPE, 15 | aov_description out GENDER_TYPES.description%TYPE); 16 | 17 | 18 | /* 19 | Verifies that the passed code value is an exact or like match on the date specified. 20 | */ 21 | PROCEDURE get_code_id_descr( 22 | aiov_code in out GENDER_TYPES.code%TYPE, 23 | aon_id out GENDER_TYPES.id%TYPE, 24 | aov_description out GENDER_TYPES.description%TYPE, 25 | aid_on in GENDER_TYPES.active_date%TYPE); 26 | 27 | 28 | /* 29 | Verifies that the passed code value is currently an exact or like match. 30 | */ 31 | PROCEDURE get_code_id_descr( 32 | aiov_code in out GENDER_TYPES.code%TYPE, 33 | aon_id out GENDER_TYPES.id%TYPE, 34 | aov_description out GENDER_TYPES.description%TYPE); 35 | 36 | 37 | /* 38 | Returns a new primary key id value for a row. 39 | */ 40 | FUNCTION get_id 41 | return GENDER_TYPES.id%TYPE; 42 | 43 | 44 | /* 45 | Returns the id for the specified code value. 46 | */ 47 | FUNCTION get_id( 48 | aiv_code in GENDER_TYPES.code%TYPE) 49 | return GENDER_TYPES.id%TYPE; 50 | 51 | 52 | /* 53 | Test-based help for this package. "set serveroutput on" in SQL*Plus. 54 | */ 55 | PROCEDURE help; 56 | 57 | 58 | /* 59 | Test units for this package. 60 | */ 61 | PROCEDURE test; 62 | 63 | 64 | end GENDER_TYPE; 65 | / 66 | @se.sql GENDER_TYPE 67 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/top_100_first_names.tab: -------------------------------------------------------------------------------- 1 | rem top_100_first_names.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Top 100 first names from www.namestatistics.com 4 | 5 | exec ddl_.dtab('TOP_100_FIRST_NAMES'); 6 | create table TOP_100_FIRST_NAMES ( 7 | first_name varchar2(30) not null, 8 | gender_code varchar2(1) not null); 9 | 10 | alter table TOP_100_FIRST_NAMES add 11 | constraint TOP_100_FIRST_NAMES_PK 12 | primary key ( 13 | first_name, 14 | gender_code ) 15 | using index; 16 | 17 | grant select on TOP_100_FIRST_NAMES to public; 18 | 19 | @top_100_first_names.ins 20 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/top_100_last_names.tab: -------------------------------------------------------------------------------- 1 | rem top_100_last_names.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Top 100 last names from www.namestatistics.com 4 | 5 | exec ddl_.dtab('TOP_100_LAST_NAMES'); 6 | create table TOP_100_LAST_NAMES ( 7 | last_name varchar2(30) not null); 8 | 9 | alter table TOP_100_LAST_NAMES add 10 | constraint TOP_100_LAST_NAMES_PK 11 | primary key ( 12 | last_name) 13 | using index; 14 | 15 | grant select on TOP_100_LAST_NAMES to public; 16 | 17 | @top_100_last_names.ins 18 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/worker.pks: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE WORKER as 2 | /* 3 | worker.pks 4 | by Don Bales on 2014-10-20 5 | Table WORKERS' methods 6 | */ 7 | 8 | 9 | FUNCTION get_external_id 10 | return WORKERS.external_id%TYPE; 11 | 12 | 13 | FUNCTION get_id 14 | return WORKERS.id%TYPE; 15 | 16 | 17 | FUNCTION get_formatted_name( 18 | aiv_first_name in WORKERS.first_name%TYPE, 19 | aiv_middle_name in WORKERS.middle_name%TYPE, 20 | aiv_last_name in WORKERS.last_name%TYPE) 21 | return WORKERS.name%TYPE; 22 | 23 | 24 | FUNCTION get_unformatted_name( 25 | aiv_first_name in WORKERS.first_name%TYPE, 26 | aiv_middle_name in WORKERS.middle_name%TYPE, 27 | aiv_last_name in WORKERS.last_name%TYPE) 28 | return WORKERS.name%TYPE; 29 | 30 | 31 | FUNCTION is_duplicate( 32 | aiv_name in WORKERS.name%TYPE, 33 | aid_birth_date in WORKERS.birth_date%TYPE, 34 | ain_gender_type_id in WORKERS.gender_type_id%TYPE) 35 | return boolean; 36 | 37 | 38 | end WORKER; 39 | / 40 | @se.sql WORKER 41 | 42 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/worker_type.pkb: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE BODY WORKER_TYPE as 2 | /* 3 | worker_type.pkb 4 | by Don Bales on 2014-10-20 5 | Table WORKER_TYPES' methods 6 | */ 7 | 8 | 9 | -- FUNCTIONS 10 | 11 | FUNCTION get_id( 12 | aiv_code in WORKER_TYPES.code%TYPE ) 13 | return WORKER_TYPES.id%TYPE is 14 | 15 | n_id WORKER_TYPES.id%TYPE; 16 | 17 | begin 18 | select id 19 | into n_id 20 | from WORKER_TYPES 21 | where code = aiv_code; 22 | 23 | return n_id; 24 | end get_id; 25 | 26 | 27 | end WORKER_TYPE; 28 | / 29 | @be.sql WORKER_TYPE 30 | 31 | -------------------------------------------------------------------------------- /source_20150125/Chapter05/worker_type.pks: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE WORKER_TYPE as 2 | /* 3 | worker_type.pks 4 | by Don Bales on 2014-10-20 5 | Code Table WORKER_TYPES' methods. 6 | */ 7 | 8 | 9 | -- Returns the id for the specified code value. 10 | 11 | FUNCTION get_id( 12 | aiv_code in WORKER_TYPES.code%TYPE ) 13 | return WORKER_TYPES.id%TYPE; 14 | 15 | 16 | end WORKER_TYPE; 17 | / 18 | @se.sql WORKER_TYPE 19 | 20 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/OPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter06/OPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter06/README.txt: -------------------------------------------------------------------------------- 1 | README.txt for Chapter 6 2 | by Donald J. Bales on 2014-10-20 3 | 4 | This is the sixth of eleven example source directories for the book 5 | "Beginning Oracle PL/SQL: From Novice to Professional". Each example source 6 | directory for this book contains the source code for the examples in the book, 7 | including solutions to the exercises. 8 | 9 | 10 | OBJECT NAME DESCRIPTION 11 | --------------------------------------- -------------------------------------- 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter06/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter06/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter06/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter06/create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | @date_.pks 13 | @date_.pkb 14 | 15 | @gender_type.tps 16 | @worker_type.tps 17 | @worker.tps 18 | 19 | @gender_types.tab 20 | @worker_types.tab 21 | @workers.tab 22 | 23 | @gender_type.tpb 24 | @worker_type.tpb 25 | @worker.tpb 26 | 27 | @gender_types.ins 28 | @worker_types.ins 29 | @workers.ins 30 | 31 | @gender_typez.vw 32 | @worker_typez.vw 33 | 34 | spool off; 35 | set echo off; 36 | @ci.sql 37 | @ci.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/date_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DATE_ as 2 | /* 3 | date_.pks 4 | by Donald J. Bales on 2014-10-20 5 | Additional DATE data type methods. 6 | */ 7 | 8 | -- The maximum and minimum date_.values. 9 | 10 | d_MAX constant date := 11 | to_date('99991231235959', 'YYYYMMDDHH24MISS'); 12 | d_MIN constant date := 13 | to_date('-47120101', 'SYYYYMMDD'); 14 | 15 | 16 | -- Returns the specified date with the time set to 23:59:59, therefore, 17 | -- the end of the day. 18 | 19 | FUNCTION end_of_day( 20 | aid_date in date ) 21 | return date; 22 | 23 | 24 | -- Returns constant d_MAX. This is useful in SQL statements where the 25 | -- constant DATE_.d_MAX is not accessible. 26 | 27 | FUNCTION get_max 28 | return date; 29 | 30 | 31 | -- Returns constant d_MIN. This is useful in SQL statements where the 32 | -- constant DATE_.d_MIN is not accessible. 33 | 34 | FUNCTION get_min 35 | return date; 36 | 37 | 38 | -- Text-based help for this package. "set serveroutput on" in SQL*Plus. 39 | 40 | PROCEDURE help; 41 | 42 | 43 | -- Returns a randomly generated date that exists between the years specified. 44 | 45 | FUNCTION random( 46 | ain_starting_year in number, 47 | ain_ending_year in number ) 48 | return date; 49 | 50 | 51 | -- Returns the specified date with the time set to 00:00:00, therefore, the 52 | -- start of the day. 53 | 54 | FUNCTION start_of_day( 55 | aid_date in date ) 56 | return date; 57 | 58 | 59 | -- Test unit for this package. 60 | 61 | PROCEDURE test; 62 | 63 | 64 | end DATE_; 65 | / 66 | @se.sql DATE_ 67 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter06/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/gender_type.pks: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE GENDER_TYPE as 2 | /* 3 | gender_type.pks 4 | by Don Bales on 2014-10-20 5 | Table GENDER_TYPES's methods. 6 | */ 7 | 8 | /* 9 | Gets the code and decription values for the specified id. 10 | */ 11 | PROCEDURE get_code_descr( 12 | ain_id in GENDER_TYPES.id%TYPE, 13 | aov_code out GENDER_TYPES.code%TYPE, 14 | aov_description out GENDER_TYPES.description%TYPE); 15 | 16 | /* 17 | Verifies that the passed code value is an exact or like match on the date specified. 18 | */ 19 | PROCEDURE get_code_id_descr( 20 | aiov_code in out GENDER_TYPES.code%TYPE, 21 | aon_id out GENDER_TYPES.id%TYPE, 22 | aov_description out GENDER_TYPES.description%TYPE, 23 | aid_on in GENDER_TYPES.active_date%TYPE); 24 | 25 | /* 26 | Verifies that the passed code value is currently an exact or like match. 27 | */ 28 | PROCEDURE get_code_id_descr( 29 | aiov_code in out GENDER_TYPES.code%TYPE, 30 | aon_id out GENDER_TYPES.id%TYPE, 31 | aov_description out GENDER_TYPES.description%TYPE); 32 | 33 | /* 34 | Returns a new primary key id value for a row. 35 | */ 36 | FUNCTION get_id 37 | return GENDER_TYPES.id%TYPE; 38 | 39 | /* 40 | Returns the id for the specified code value. 41 | */ 42 | FUNCTION get_id( 43 | aiv_code in GENDER_TYPES.code%TYPE) 44 | return GENDER_TYPES.id%TYPE; 45 | 46 | /* 47 | Test-based help for this package. "set serveroutput on" in SQL*Plus. 48 | */ 49 | PROCEDURE help; 50 | 51 | /* 52 | Test units for this package. 53 | */ 54 | PROCEDURE test; 55 | 56 | end GENDER_TYPE; 57 | / 58 | @se.sql GENDER_TYPE 59 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/gender_types.ins: -------------------------------------------------------------------------------- 1 | rem gender_types.ins 2 | rem copyright by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | insert into GENDER_TYPES values ( gender_type( 'F', 'Female' ) ); 6 | insert into GENDER_TYPES values ( gender_type( 'M', 'Male' ) ); 7 | insert into GENDER_TYPES values ( gender_type( 'U', 'Unknown' ) ); 8 | commit; 9 | 10 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'GENDER_TYPES'); 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/gender_types.tab: -------------------------------------------------------------------------------- 1 | rem gender_types.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create an object table for the Gender Type codes 4 | 5 | --drop table GENDER_TYPES; 6 | create table GENDER_TYPES of GENDER_TYPE; 7 | 8 | --drop sequence GENDERS_ID; 9 | create sequence GENDERS_ID 10 | start with 1; 11 | 12 | alter table GENDER_TYPES add 13 | constraint GENDER_TYPES_PK 14 | primary key ( id ) 15 | using index; 16 | 17 | alter table GENDER_TYPES add 18 | constraint GENDER_TYPES_UK 19 | unique ( code, active_date ) 20 | using index; 21 | 22 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'GENDER_TYPES'); 23 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/gender_typez.vw: -------------------------------------------------------------------------------- 1 | rem gender_typez.vw 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create an object view for relational table GENDER_TYPES 4 | 5 | create view GENDER_TYPEZ of GENDER_TYPE 6 | with object identifier (id) as 7 | select id, 8 | code, 9 | description, 10 | active_date, 11 | inactive_date 12 | from RPS.GENDER_TYPES; 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_type.pkb: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE BODY WORKER_TYPE as 2 | /* 3 | worker_type.pkb 4 | by Don Bales on 2014-10-20 5 | Table WORKER_TYPES' methods 6 | */ 7 | 8 | 9 | -- FUNCTIONS 10 | 11 | FUNCTION get_id( 12 | aiv_code in WORKER_TYPES.code%TYPE ) 13 | return WORKER_TYPES.id%TYPE is 14 | 15 | n_id WORKER_TYPES.id%TYPE; 16 | 17 | begin 18 | select id 19 | into n_id 20 | from WORKER_TYPES 21 | where code = aiv_code; 22 | 23 | return n_id; 24 | end get_id; 25 | 26 | 27 | end WORKER_TYPE; 28 | / 29 | @be.sql WORKER_TYPE 30 | 31 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_type.pks: -------------------------------------------------------------------------------- 1 | create or replace PACKAGE WORKER_TYPE as 2 | /* 3 | worker_type.pks 4 | by Don Bales on 2014-10-20 5 | Code Table WORKER_TYPES' methods. 6 | */ 7 | 8 | 9 | -- Returns the id for the specified code value. 10 | 11 | FUNCTION get_id( 12 | aiv_code in WORKER_TYPES.code%TYPE ) 13 | return WORKER_TYPES.id%TYPE; 14 | 15 | 16 | end WORKER_TYPE; 17 | / 18 | @se.sql WORKER_TYPE 19 | 20 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_type.sql: -------------------------------------------------------------------------------- 1 | declare 2 | -- Declare a worker_type variable 3 | o_worker_type WORKER_TYPE; 4 | 5 | begin 6 | -- Now use the default constructor to create a new instance 7 | -- of the object 8 | o_worker_type := new WORKER_TYPE( 9 | NULL, 'H', 'A hard worker', SYSDATE, NULL); 10 | -- Now allocate a new ID using the member function get_id() 11 | o_worker_type.id := o_worker_type.get_id(); 12 | -- Now show the values of the attributes in the instance 13 | pl('o_worker_type.id = '||o_worker_type.id); 14 | pl('o_worker_type.code = '||o_worker_type.code); 15 | pl('o_worker_type.description = '||o_worker_type.description); 16 | pl('o_worker_type.active_date = '||o_worker_type.active_date); 17 | pl('o_worker_type.inactive_date = '||o_worker_type.inactive_date); 18 | end; 19 | / 20 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_types.ins: -------------------------------------------------------------------------------- 1 | rem worker_typet.ins 2 | rem copyright by Donald J. Bales on 2014-10-20 3 | rem 4 | 5 | insert into WORKER_TYPES values ( worker_type( 'C', 'Contractor' ) ); 6 | insert into WORKER_TYPES values ( worker_type( 'E', 'Employee' ) ); 7 | insert into WORKER_TYPES values ( worker_type( 'U', 'Unknown' ) ); 8 | commit; 9 | 10 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKER_TYPES'); 11 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_types.sql: -------------------------------------------------------------------------------- 1 | rem worker_types.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem test unit for object table WORKER_TYPES 4 | 5 | declare 6 | -- Declare a variable of the user-define type 7 | o_worker_type WORKER_TYPE; 8 | 9 | begin 10 | -- Insert a test object using the convenience constructor 11 | insert into WORKER_TYPES 12 | values ( WORKER_TYPE( 'T', 'Test') ); 13 | 14 | -- Now update the inactive date on the object 15 | update WORKER_TYPES 16 | set inactive_date = SYSDATE 17 | where code = 'T'; 18 | 19 | -- Retrieve the object in order to show its values 20 | select value(g) 21 | into o_worker_type 22 | from WORKER_TYPES g 23 | where code = 'T'; 24 | 25 | -- Show the object's values 26 | pl('o_worker_type.id = '||o_worker_type.id); 27 | pl('o_worker_type.code = '||o_worker_type.code); 28 | pl('o_worker_type.description = '||o_worker_type.description); 29 | pl('o_worker_type.active_date = '||o_worker_type.active_date); 30 | pl('o_worker_type.inactive_date = '||o_worker_type.inactive_date); 31 | 32 | -- Delete the test object 33 | delete WORKER_TYPES 34 | where code = 'T'; 35 | 36 | -- This time insert the test object using the instance variable 37 | insert into WORKER_TYPES 38 | values ( o_worker_type ); 39 | 40 | -- Last, delete the object from the relational table 41 | delete WORKER_TYPES 42 | where code = 'T'; 43 | 44 | -- Commit all these operations 45 | commit; 46 | 47 | -- Confirm that the test completed successfully 48 | pl('Test completed successfully.'); 49 | end; 50 | / 51 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_types.tab: -------------------------------------------------------------------------------- 1 | rem worker_type.tab 2 | rem copyright by Donald J. Bales on 2014-10-20 3 | rem Create an object table for the Worker Type codes 4 | 5 | --drop table WORKER_TYPES; 6 | create table WORKER_TYPES of WORKER_TYPE; 7 | 8 | --drop sequence WORKER_TYPES_ID; 9 | create sequence WORKER_TYPES_ID 10 | start with 1; 11 | 12 | alter table WORKER_TYPES add 13 | constraint WORKER_TYPES_PK 14 | primary key ( id ) 15 | using index; 16 | 17 | alter table WORKER_TYPES add 18 | constraint WORKER_TYPES_UK 19 | unique ( code ) 20 | using index; 21 | 22 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKER_TYPES'); 23 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/worker_typez.vw: -------------------------------------------------------------------------------- 1 | rem worker_typez.vw 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create an object view for table WORKER_TYPES 4 | 5 | create view WORKER_TYPEZ of WORKER_TYPE 6 | with object identifier (id) as 7 | select id, 8 | code, 9 | description, 10 | active_date, 11 | inactive_date 12 | from RPS.WORKER_TYPES; 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter06/workers.tab: -------------------------------------------------------------------------------- 1 | rem worker_ot.tab 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create an object table for Workers 4 | 5 | --drop table WORKERS; 6 | create table WORKERS of WORKER; 7 | 8 | --drop sequence WORKERS_ID; 9 | create sequence WORKERS_ID 10 | start with 1; 11 | 12 | --drop sequence EXTERNAL_ID_SEQ; 13 | create sequence EXTERNAL_ID_SEQ 14 | start with 100000000 order; 15 | 16 | alter table WORKERS add 17 | constraint WORKERS_PK 18 | primary key ( id ) 19 | using index; 20 | 21 | alter table WORKERS add 22 | constraint WORKERS_UK1 23 | unique ( external_id ) 24 | using index; 25 | 26 | alter table WORKERS add 27 | constraint WORKERS_UK2 28 | unique ( 29 | name, 30 | birth_date, 31 | gender_type_id ) 32 | using index; 33 | 34 | alter table WORKERS add 35 | constraint WORKERS_FK1 36 | foreign key ( worker_type_id ) 37 | references WORKER_TYPES ( id ); 38 | 39 | alter table WORKERS add 40 | constraint WORKERS_FK2 41 | foreign key ( gender_type_id ) 42 | references GENDER_TYPES ( id ); 43 | 44 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'WORKERS'); 45 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/I needed this to enable debugging in SqlDeveloper.txt: -------------------------------------------------------------------------------- 1 | /* 2 | begin 3 | DBMS_NETWORK_ACL_ADMIN.create_acl ( 4 | acl => 'remote_debugger.xml', 5 | description => 'Remote Debugging ACL', 6 | principal => 'OPS', 7 | is_grant => TRUE, 8 | privilege => 'connect', 9 | start_date => SYSTIMESTAMP, 10 | end_date => NULL); 11 | 12 | commit; 13 | end; 14 | 15 | 16 | begin 17 | DBMS_NETWORK_ACL_ADMIN.assign_acl ( 18 | acl => 'remote_debugger.xml', 19 | host => '192.168.2.2', 20 | lower_port => '80', 21 | upper_port => '99999'); 22 | 23 | commit; 24 | end; 25 | 26 | */ 27 | 28 | -- I needed this to enable debugging in SqlDeveloper 29 | begin 30 | DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( 31 | host => '192.168.2.2', 32 | lower_port => null, 33 | upper_port => null, 34 | ace => xs$ace_type(privilege_list => xs$name_list('jdwp'), 35 | principal_name => 'OPS', 36 | principal_type => xs_acl.ptype_db)); 37 | commit; 38 | end; 39 | / -------------------------------------------------------------------------------- /source_20150125/Chapter07/OPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter07/OPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter07/README.txt: -------------------------------------------------------------------------------- 1 | README.txt for Chapter 7 2 | by Donald J. Bales on 2014-10-20 3 | 4 | This is the seventh of eleven example source directories for the book 5 | "Beginning Oracle PL/SQL: From Novice to Professional". Each example source 6 | directory for this book contains the source code for the examples in the book, 7 | including solutions to the exercises. 8 | 9 | 10 | OBJECT NAME DESCRIPTION 11 | --------------------------------------- -------------------------------------- 12 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/RPS on ORCL.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter07/RPS on ORCL.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter07/avg_profile.sql: -------------------------------------------------------------------------------- 1 | rem avg_profile.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a DBMS_PROFILER report by avg desc 4 | 5 | define runid="&1"; 6 | 7 | column avg_pct format 990.99; 8 | column line# format 9999; 9 | column occur format 9999 10 | column text format a42 trunc; 11 | column unit_name format a11; 12 | 13 | set linesize 1000; 14 | set newpage 1; 15 | set pagesize 32767; 16 | set trimspool on; 17 | set verify off; 18 | 19 | spool avg_profile_&runid..txt; 20 | 21 | select v.unit_name, 22 | round(v.avg_time/t.avg_time*100, 2) avg_pct, 23 | v.occur, 24 | v.line#, 25 | ltrim(s.text) text 26 | from SYS.ALL_SOURCE s, 27 | ( select u.runid, 28 | u.unit_owner, 29 | u.unit_type, 30 | u.unit_name, 31 | d.min_time, 32 | to_number(decode(d.total_occur, 33 | NULL, NULL, 34 | 0, 0, 35 | round(d.total_time/d.total_occur))) avg_time, 36 | d.max_time, 37 | d.total_time, 38 | d.total_occur occur, 39 | d.line# 40 | from PLSQL_PROFILER_UNITS u, 41 | PLSQL_PROFILER_DATA d 42 | where u.runid = d.runid 43 | and u.unit_number = d.unit_number 44 | and d.runid = &runid ) v, 45 | ( select sum(to_number(decode(d.total_occur, 46 | NULL, NULL, 47 | 0, 0, 48 | round(d.total_time/d.total_occur)))) avg_time 49 | from PLSQL_PROFILER_UNITS u, 50 | PLSQL_PROFILER_DATA d 51 | where u.runid = d.runid 52 | and u.unit_number = d.unit_number 53 | and d.runid = &runid ) t 54 | where v.unit_owner = s.owner(+) 55 | and v.unit_type = s.type(+) 56 | and v.unit_name = s.name(+) 57 | and v.line# = s.line(+) 58 | and v.avg_time > 0 59 | order by v.avg_time desc, 60 | v.unit_name, 61 | v.line#; 62 | 63 | spool off; 64 | 65 | set verify on; 66 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/avg_profile_2.txt: -------------------------------------------------------------------------------- 1 | 2 | UNIT_NAME AVG_PCT OCCUR LINE# TEXT 3 | ----------- ------- ----- ----- ------------------------------------------ 4 | 53.21 1 4 5 | DEBUG 45.39 22 92 insert into DEBUGS 6 | DEBUG 0.36 22 97 commit; 7 | 0.31 2 1 8 | 0.16 18 1 9 | 0.12 1 11 10 | 0.10 10 7 11 | DEBUG 0.07 132 49 self.unique_session_id := SYS.DBMS_SESSION 12 | 0.04 2 1 13 | 0.03 10 8 14 | DEBUG 0.02 132 46 pl('debug(two params)'); 15 | 0.02 10 6 16 | DEBUG 0.02 132 50 self.insert_user := USER; 17 | PL 0.02 133 11 SYS.DBMS_OUTPUT.put_line(aiv_text); 18 | DEBUG 0.02 132 53 return; 19 | DEBUG 0.02 22 90 v_text := substrb(aiv_program_unit||': '|| 20 | DEBUG 0.02 22 89 begin 21 | DEBUG 0.01 22 81 STATIC PROCEDURE set_text( 22 | DEBUG 0.01 22 98 end set_text; 23 | DEBUG 0.01 132 39 CONSTRUCTOR FUNCTION debug( 24 | DEBUG 0.01 132 51 self.insert_date := SYSDATE; 25 | 0.01 1 10 26 | DEBUG 0.01 132 54 end debug; 27 | DEBUG 0.00 132 47 self.id := ain_id; 28 | 0.00 1 11 29 | 0.00 1 12 30 | PL 0.00 133 12 end pl; 31 | 0.00 11 5 32 | DEBUG 0.00 132 48 self.text := aiv_text; 33 | 34 | 29 rows selected. 35 | 36 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/avg_profile_ops.debug.sql.txt: -------------------------------------------------------------------------------- 1 | and d.runid = ops.debug.sql ) t 2 | * 3 | ERROR at line 33: 4 | ORA-00904: "OPS"."DEBUG"."SQL": invalid identifier 5 | 6 | 7 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter07/ci.txt -------------------------------------------------------------------------------- /source_20150125/Chapter07/cmd.exe.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/Chapter07/cmd.exe.lnk -------------------------------------------------------------------------------- /source_20150125/Chapter07/date_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DATE_ as 2 | /* 3 | date_.pks 4 | by Donald J. Bales on 2014-10-20 5 | Additional DATE data type methods. 6 | */ 7 | 8 | -- The maximum and minimum date_.values. 9 | 10 | d_MAX constant date := 11 | to_date('99991231235959', 'YYYYMMDDHH24MISS'); 12 | d_MIN constant date := 13 | to_date('-47120101', 'SYYYYMMDD'); 14 | 15 | 16 | -- Returns the specified date with the time set to 23:59:59, therefore, 17 | -- the end of the day. 18 | 19 | FUNCTION end_of_day( 20 | aid_date in date ) 21 | return date; 22 | 23 | 24 | -- Returns constant d_MAX. This is useful in SQL statements where the 25 | -- constant DATE_.d_MAX is not accessible. 26 | 27 | FUNCTION get_max 28 | return date; 29 | 30 | 31 | -- Returns constant d_MIN. This is useful in SQL statements where the 32 | -- constant DATE_.d_MIN is not accessible. 33 | 34 | FUNCTION get_min 35 | return date; 36 | 37 | 38 | -- Text-based help for this package. "set serveroutput on" in SQL*Plus. 39 | 40 | PROCEDURE help; 41 | 42 | 43 | -- Returns a randomly generated date that exists between the years specified. 44 | 45 | FUNCTION random( 46 | ain_starting_year in number, 47 | ain_ending_year in number ) 48 | return date; 49 | 50 | 51 | -- Returns the specified date with the time set to 00:00:00, therefore, the 52 | -- start of the day. 53 | 54 | FUNCTION start_of_day( 55 | aid_date in date ) 56 | return date; 57 | 58 | 59 | -- Test unit for this package. 60 | 61 | PROCEDURE test; 62 | 63 | 64 | end DATE_; 65 | / 66 | @se.sql DATE_ 67 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/Chapter07/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/failure.sql: -------------------------------------------------------------------------------- 1 | rem failure.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem a script that fails on purpose 4 | 5 | declare 6 | 7 | n_number number; 8 | v_number varchar2(30); 9 | 10 | begin 11 | pl('begin'); 12 | 13 | pl('before n_number assignment'); 14 | 15 | n_number := 1; 16 | 17 | pl('after n_number assignment'); 18 | 19 | pl('before v_number assignment'); 20 | 21 | v_number := 'two'; 22 | 23 | pl('after v_number assignment'); 24 | 25 | pl('before addition'); 26 | begin 27 | pl('n_number + v_number = '||to_char(n_number + to_number(v_number))); 28 | exception 29 | when OTHERS then 30 | pl('n_number = '||to_char(n_number)); 31 | pl('v_number = '||v_number); 32 | raise_application_error(-20000, SQLERRM|| 33 | ' on n_number + v_number'|| 34 | ' in failure.sql'); 35 | end; 36 | pl('after addition'); 37 | 38 | pl('end'); 39 | end; 40 | / 41 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool ops.create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | @date_.pks 13 | @date_.pkb 14 | 15 | @ops.debug.tps 16 | @ops.debugs.tab 17 | @ops.debug.tpb 18 | 19 | @ops.debugger.pks 20 | @ops.debugger.pkb 21 | 22 | spool off; 23 | set echo off; 24 | @ci.sql 25 | @ci.sql 26 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debug.sql: -------------------------------------------------------------------------------- 1 | rem debug.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem A test unit for type DEBUG 4 | 5 | declare 6 | 7 | begin 8 | DEBUG.set_text('DEBUG.SQL', 'before the loop'); 9 | for i in 1..10 loop 10 | DEBUG.set_text('DEBUG.SQL', 'loop '||to_char(i)||' before sleep'); 11 | SYS.DBMS_LOCK.sleep(3); 12 | DEBUG.set_text('DEBUG.SQL', 'loop '||to_char(i)||' after sleep'); 13 | end loop; 14 | DEBUG.set_text('DEBUG.SQL:', 'after the loop'); 15 | end; 16 | / 17 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debug.tps: -------------------------------------------------------------------------------- 1 | create type DEBUG as object ( 2 | /* 3 | debug.tps 4 | by Donald Bales on 2014-10-20 5 | Type DEBUG's specification: 6 | A type for logging debug information 7 | */ 8 | id number(38), 9 | text varchar2(256), 10 | unique_session_id varchar2(24), 11 | insert_user varchar2(30), 12 | insert_date date, 13 | -- Get the next primary key value 14 | STATIC FUNCTION get_id 15 | return number, 16 | -- A NULL values constructor 17 | CONSTRUCTOR FUNCTION debug( 18 | self in out nocopy debug) 19 | return self as result, 20 | -- A convenience constructor 21 | CONSTRUCTOR FUNCTION debug( 22 | self in out nocopy debug, 23 | ain_id in number, 24 | aiv_text in varchar2) 25 | return self as result, 26 | -- Override the default constructor 27 | CONSTRUCTOR FUNCTION debug( 28 | self in out nocopy debug, 29 | id in number, 30 | text in varchar2, 31 | unique_session_id in varchar2, 32 | insert_user in varchar2, 33 | insert_date in date) 34 | return self as result, 35 | -- Write to the debug object table 36 | STATIC PROCEDURE set_text( 37 | aiv_program_unit in varchar2, 38 | aiv_text in varchar2), 39 | -- A map function 40 | MAP MEMBER FUNCTION to_map 41 | return number 42 | ) not final; 43 | / 44 | @se.sql 45 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debug.tps.original: -------------------------------------------------------------------------------- 1 | create type DEBUG as object ( 2 | /* 3 | debug.tps 4 | by Donald Bales on 2014-10-20 5 | Type DEBUG's specification: 6 | A type for logging debug information 7 | */ 8 | id number(38), 9 | text varchar2(256), 10 | unique_session_id varchar2(24), 11 | insert_user varchar2(30), 12 | insert_date date, 13 | -- Get the next primary key value 14 | STATIC FUNCTION get_id 15 | return number, 16 | -- A NULL values constructor 17 | CONSTRUCTOR FUNCTION debug( 18 | self in out nocopy debug) 19 | return self as result, 20 | -- A convenience constructor 21 | CONSTRUCTOR FUNCTION debug( 22 | self in out nocopy debug, 23 | ain_id in number, 24 | aiv_text in varchar2) 25 | return self as result, 26 | -- Override the default constructor 27 | CONSTRUCTOR FUNCTION debug( 28 | self in out nocopy debug, 29 | id in number, 30 | text in varchar2, 31 | unique_session_id in varchar2, 32 | insert_user in varchar2, 33 | insert_date in date) 34 | return self as result, 35 | -- Write to the debug object table 36 | STATIC PROCEDURE set_text( 37 | aiv_program_unit in varchar2, 38 | aiv_text in varchar2), 39 | -- A map function 40 | MAP MEMBER FUNCTION to_map 41 | return number 42 | ) not final; 43 | / 44 | @se.sql 45 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debug.tps.with_wasted_sequence_problem.txt: -------------------------------------------------------------------------------- 1 | create type DEBUG as object ( 2 | /* 3 | debug.tps 4 | by Donald Bales on 2014-10-20 5 | Type DEBUG's specification: 6 | A type for logging debug information 7 | */ 8 | id number(38), 9 | text varchar2(256), 10 | unique_session_id varchar2(24), 11 | insert_user varchar2(30), 12 | insert_date date, 13 | -- Get the next primary key value 14 | STATIC FUNCTION get_id 15 | return number, 16 | -- A NULL values constructor 17 | CONSTRUCTOR FUNCTION debug( 18 | self in out nocopy debug) 19 | return self as result, 20 | -- A convenience constructor 21 | CONSTRUCTOR FUNCTION debug( 22 | self in out nocopy debug, 23 | aiv_text in varchar2) 24 | return self as result, 25 | -- Override the default constructor 26 | CONSTRUCTOR FUNCTION debug( 27 | self in out nocopy debug, 28 | id in number, 29 | text in varchar2, 30 | unique_session_id in varchar2, 31 | insert_user in varchar2, 32 | insert_date in date) 33 | return self as result, 34 | -- Write to the debug object table 35 | STATIC PROCEDURE set_text( 36 | aiv_program_unit in varchar2, 37 | aiv_text in varchar2), 38 | -- A map function 39 | MAP MEMBER FUNCTION to_map 40 | return number 41 | ) not final; 42 | / 43 | @se.sql 44 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debug_a_session.sql: -------------------------------------------------------------------------------- 1 | rem debug_a_sesion.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Query DEBUGS uing the specified unique session ID 4 | 5 | define unique_session_id=&1; 6 | 7 | select id, 8 | text 9 | from DEBUGS 10 | where unique_session_id = upper('&unique_session_id') 11 | and insert_date > SYSDATE - (10/(24*60)) 12 | order by id; 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debugger.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DEBUGGER as 2 | /* 3 | debugger.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Object Table DEBUGS' package 6 | */ 7 | 8 | -- Declare a table type and then table to hold the 9 | -- enabled program units 10 | TYPE program_unit_table is table of varchar2(1) 11 | index by varchar2(30); 12 | 13 | t_program_unit program_unit_table; 14 | 15 | 16 | PROCEDURE disable( 17 | aiv_program_unit in varchar2) is 18 | 19 | v_program_unit varchar2(30); 20 | 21 | begin 22 | v_program_unit := upper(aiv_program_unit); 23 | 24 | if t_program_unit.exists(v_program_unit) then 25 | t_program_unit.delete(v_program_unit); 26 | end if; 27 | end disable; 28 | 29 | 30 | PROCEDURE enable( 31 | aiv_program_unit in varchar2) is 32 | 33 | v_program_unit varchar2(30); 34 | 35 | begin 36 | v_program_unit := upper(aiv_program_unit); 37 | 38 | if not t_program_unit.exists(v_program_unit) then 39 | t_program_unit(v_program_unit) := NULL; 40 | end if; 41 | end enable; 42 | 43 | 44 | PROCEDURE set_text( 45 | aiv_program_unit in varchar2, 46 | aiv_text in DEBUGS.text%TYPE) is 47 | 48 | v_program_unit varchar2(30); 49 | 50 | begin 51 | v_program_unit := upper(aiv_program_unit); 52 | 53 | if t_program_unit.exists(v_program_unit) then 54 | DEBUG.set_text(v_program_unit, aiv_text); 55 | end if; 56 | end set_text; 57 | 58 | 59 | end DEBUGGER; 60 | / 61 | @be.sql DEBUGGER; 62 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debugger.pks: -------------------------------------------------------------------------------- 1 | create or replace package DEBUGGER as 2 | /* 3 | debugger.pks 4 | by Donald J. Bales on 2014-10-20 5 | Object Table DEBUGS's package 6 | */ 7 | 8 | -- Disable debug logging for the specified program unit 9 | PROCEDURE disable( 10 | aiv_program_unit in varchar2); 11 | 12 | -- Enable debug logging for the specified program unit 13 | PROCEDURE enable( 14 | aiv_program_unit in varchar2); 15 | 16 | -- Conditionally log the debug information for the specified 17 | -- program unit, if it is enabled 18 | PROCEDURE set_text( 19 | aiv_program_unit in varchar2, 20 | aiv_text in DEBUGS.text%TYPE); 21 | 22 | 23 | end DEBUGGER; 24 | / 25 | @se.sql DEBUGGER; 26 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debugger.sql: -------------------------------------------------------------------------------- 1 | rem debugger.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem A test unit for package DEBUGGER 4 | 5 | declare 6 | 7 | begin 8 | -- Enable debug output 9 | DEBUGGER.enable('DEBUGGER.SQL'); 10 | -- Test 11 | DEBUGGER.set_text('DEBUGGER.SQL', 'before the loop '); 12 | for i in 1..10 loop 13 | DEBUGGER.set_text('DEBUGGER.SQL', 'loop '||to_char(i)||' before sleep'); 14 | SYS.DBMS_LOCK.sleep(3); 15 | DEBUGGER.set_text('DEBUGGER.SQL', 'loop '||to_char(i)||' after sleep'); 16 | end loop; 17 | DEBUGGER.set_text('DEBUGGER.SQL', 'after the loop '); 18 | 19 | -- Disable debug output 20 | DEBUGGER.disable('DEBUGGER.SQL'); 21 | -- Test 22 | DEBUGGER.set_text('DEBUGGER.SQL', 'before the loop '); 23 | for i in 1..10 loop 24 | DEBUGGER.set_text('DEBUGGER.SQL', 'loop '||to_char(i)||' before sleep'); 25 | -- SYS.DBMS_LOCK.sleep(3); 26 | DEBUGGER.set_text('DEBUGGER.SQL', 'loop '||to_char(i)||' after sleep'); 27 | end loop; 28 | DEBUGGER.set_text('DEBUGGER.SQL', 'after the loop '); 29 | end; 30 | / 31 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ops.debugs.tab: -------------------------------------------------------------------------------- 1 | rem debugs.tab 2 | rem by Donald Bales on 2014-10-20 3 | rem Create debugging message table 4 | 5 | -- drop table DEBUGS; 6 | create table DEBUGS of DEBUG; 7 | 8 | alter table DEBUGS add 9 | constraint DEBUGS_PK 10 | primary key ( 11 | id ) 12 | using index; 13 | 14 | -- drop sequence DEBUGS_ID; 15 | create sequence DEBUGS_ID 16 | start with 1 order; 17 | 18 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'DEBUGS'); 19 | 20 | grant all on DEBUGS to PUBLIC; 21 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/ord_profile.sql: -------------------------------------------------------------------------------- 1 | rem ord_profile.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Create a DBMS_PROFILER report by program unit and line number 4 | 5 | define runid="&1"; 6 | 7 | column avg_time format 9999999; 8 | column line# format 9999; 9 | column occur format 9999 10 | column text format a40 trunc; 11 | column unit_name format a13; 12 | 13 | set linesize 1000; 14 | set newpage 1; 15 | set pagesize 32767; 16 | set trimspool on; 17 | set verify off; 18 | 19 | spool ord_profile_&runid..txt; 20 | 21 | select v.unit_name, 22 | v.avg_time, 23 | v.occur, 24 | v.line#, 25 | ltrim(s.text) text 26 | from SYS.ALL_SOURCE s, 27 | ( select u.unit_owner, 28 | u.unit_type, 29 | u.unit_name, 30 | d.min_time, 31 | to_number(decode(d.total_occur, 32 | NULL, NULL, 33 | 0, 0, 34 | round(d.total_time/d.total_occur))) avg_time, 35 | d.max_time, 36 | d.total_time, 37 | d.total_occur occur, 38 | d.line# 39 | from PLSQL_PROFILER_UNITS u, 40 | PLSQL_PROFILER_DATA d 41 | where u.runid = d.runid 42 | and u.unit_number = d.unit_number 43 | and d.runid = &runid ) v 44 | where v.unit_owner = s.owner(+) 45 | and v.unit_type = s.type(+) 46 | and v.unit_name = s.name(+) 47 | and v.line# = s.line(+) 48 | order by v.unit_name, 49 | v.line#; 50 | 51 | spool off; 52 | 53 | set verify on; 54 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/profile.sql: -------------------------------------------------------------------------------- 1 | define runid="&1"; 2 | column text format a80 trunc; 3 | select v.unit_name, 4 | v.min_time, 5 | v.avg_time, 6 | v.max_time, 7 | v.total_time, 8 | v.total_occur, 9 | v.line#, 10 | s.text 11 | from SYS.ALL_SOURCE s, 12 | ( select u.unit_owner, 13 | u.unit_type, 14 | u.unit_name, 15 | d.min_time, 16 | to_number(decode(d.total_occur, 17 | NULL, NULL, 18 | 0, 0, 19 | round(d.total_time/d.total_occur))) avg_time, 20 | d.max_time, 21 | d.total_time, 22 | d.total_occur, 23 | d.line# 24 | from PLSQL_PROFILER_UNITS u, 25 | PLSQL_PROFILER_DATA d 26 | where u.runid = d.runid 27 | and u.unit_number = d.unit_number 28 | and d.runid = &runid ) v 29 | where v.unit_owner = s.owner(+) 30 | and v.unit_type = s.type(+) 31 | and v.unit_name = s.name(+) 32 | and v.line# = s.line(+) 33 | order by 1, 2; 34 | 35 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.create_all.sql: -------------------------------------------------------------------------------- 1 | set echo on; 2 | set linesize 1000; 3 | set newpage 1; 4 | set pagesize 32767; 5 | set trimspool on; 6 | spool rps.create_all.txt; 7 | 8 | @ddl_.pks 9 | @ddl_.pkb 10 | @pl.prc 11 | 12 | @date_.pks 13 | @date_.pkb 14 | 15 | @rps.debugs.tab 16 | @rps.debug.pks 17 | @rps.debug.pkb 18 | 19 | spool off; 20 | set echo off; 21 | @ci.sql 22 | @ci.sql 23 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.debug.pks: -------------------------------------------------------------------------------- 1 | create or replace package DEBUG as 2 | /* 3 | debug.pks 4 | by Donald J. Bales on 2014-10-20 5 | Table DEBUGS's package 6 | */ 7 | 8 | n_id number := 0; 9 | 10 | -- Gets the next primary key value for the table 11 | FUNCTION get_id 12 | return DEBUGS.id%TYPE; 13 | 14 | -- Enable debug output for the specified program unit 15 | PROCEDURE enable( 16 | aiv_program_unit in varchar2); 17 | 18 | -- Disable debug output for the specified program unit 19 | PROCEDURE disable( 20 | aiv_program_unit in varchar2); 21 | 22 | -- Log debug output if enabled for the specified program unit 23 | PROCEDURE set_text( 24 | aiv_program_unit in varchar2, 25 | aiv_text in DEBUGS.text%TYPE); 26 | 27 | 28 | end DEBUG; 29 | / 30 | @se.sql DEBUG; 31 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.debug.sql: -------------------------------------------------------------------------------- 1 | rem debug.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Test unit for package DEBUG 4 | 5 | declare 6 | 7 | v_program_unit varchar2(30) := 8 | 'debug.sql'; 9 | 10 | begin 11 | DEBUG.enable(v_program_unit); 12 | DEBUG.set_text(v_program_unit, 'before the loop '); 13 | for i in 1..10 loop 14 | DEBUG.set_text(v_program_unit, 'loop '||to_char(i)||' before sleep'); 15 | SYS.DBMS_LOCK.sleep(3); 16 | DEBUG.set_text(v_program_unit, 'loop '||to_char(i)||' after sleep'); 17 | end loop; 18 | DEBUG.set_text(v_program_unit, 'after the loop '); 19 | DEBUG.disable(v_program_unit); 20 | DEBUG.set_text(v_program_unit, 'before the loop '); 21 | for i in 1..10 loop 22 | DEBUG.set_text(v_program_unit, 'loop '||to_char(i)||' before sleep'); 23 | -- SYS.DBMS_LOCK.sleep(3); 24 | DEBUG.set_text(v_program_unit, 'loop '||to_char(i)||' after sleep'); 25 | end loop; 26 | DEBUG.set_text(v_program_unit, 'after the loop '); 27 | end; 28 | / 29 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.debugs.tab: -------------------------------------------------------------------------------- 1 | rem debugs.tab 2 | rem by Donald Bales on 2014-10-20 3 | rem Create debugging message table 4 | 5 | --drop table DEBUGS; 6 | create table DEBUGS ( 7 | id number not null, 8 | text varchar2(256), 9 | unique_session_id varchar2(24) not null, 10 | insert_user varchar2(30) default USER not null, 11 | insert_date date default SYSDATE not null ); 12 | 13 | alter table DEBUGS add 14 | constraint DEBUGS_PK 15 | primary key ( 16 | id ) 17 | using index; 18 | 19 | --drop sequence DEBUGS_ID; 20 | create sequence DEBUGS_ID 21 | start with 1 order; 22 | 23 | execute SYS.DBMS_STATS.gather_table_stats(USER, 'DEBUGS'); 24 | 25 | grant all on DEBUGS to PUBLIC; 26 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.workers_ins_insert_w_codes.sql: -------------------------------------------------------------------------------- 1 | insert into WORKERS ( 2 | id, 3 | worker_type_id, 4 | external_id, 5 | first_name, 6 | middle_name, 7 | last_name, 8 | name, 9 | birth_date, 10 | gender_type_id) 11 | select WORKERS_ID.nextval, 12 | decode(mod(WORKERS_ID.currval, 2), 13 | 0, c1.id, c2.id), 14 | lpad(to_char(EXTERNAL_ID_SEQ.nextval), 9, '0'), 15 | first_name, 16 | letter||'.', 17 | last_name, 18 | WORKER.get_formatted_name( 19 | first_name, letter||'.', last_name), 20 | DATE_.random( 21 | to_number(to_char(SYSDATE, 'YYYY')) - 65, 22 | to_number(to_char(SYSDATE, 'YYYY')) - 18), 23 | decode(gender_code, 'F', c3.id, c4.id) 24 | from TOP_100_LAST_NAMES, 25 | TOP_100_FIRST_NAMES, 26 | A_THRU_Z, 27 | WORKER_TYPES c1, 28 | WORKER_TYPES c2, 29 | GENDER_TYPES c3, 30 | GENDER_TYPES c4 31 | where c1.code = 'E' 32 | and c2.code = 'C' 33 | and c3.code = 'F' 34 | and c4.code = 'M'; 35 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.workers_ins_insert_w_constants_timing.sql: -------------------------------------------------------------------------------- 1 | rem workers_ins_insert_w_codes_timing.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Seed the Worker table with the top 100 names 4 | rem 100 last x 100 first x 26 middle = 260,000 entries 5 | 6 | set serveroutput on size 1000000; 7 | 8 | declare 9 | 10 | -- This is the number of seconds since midnight 11 | -- I'll use it to profile my code's performance. 12 | n_start number; 13 | 14 | -- I'll use this to keep track of the number of 15 | -- rows inserted. 16 | n_inserted number := 0; 17 | 18 | begin 19 | -- Delete any existing entries 20 | delete WORKERS; 21 | 22 | commit; 23 | 24 | -- Use an INSERT INTO SELECT SQL statement 25 | n_start := to_number(to_char(SYSDATE, 'SSSSS')); 26 | 27 | insert into WORKERS ( 28 | id, 29 | worker_type_id, 30 | external_id, 31 | first_name, 32 | middle_name, 33 | last_name, 34 | name, 35 | birth_date, 36 | gender_type_id) 37 | select WORKERS_ID.nextval, 38 | decode(mod(WORKERS_ID.currval, 2), 39 | 0, 2, 1), 40 | lpad(to_char(EXTERNAL_ID_SEQ.nextval), 9, '0'), 41 | first_name, 42 | letter||'.', 43 | last_name, 44 | WORKER.get_formatted_name( 45 | first_name, letter||'.', last_name), 46 | DATE_.random( 47 | to_number(to_char(SYSDATE, 'YYYY')) - 65, 48 | to_number(to_char(SYSDATE, 'YYYY')) - 18), 49 | decode(gender_code, 'F', 1, 2) 50 | from TOP_100_LAST_NAMES, 51 | TOP_100_FIRST_NAMES, 52 | A_THRU_Z; 53 | 54 | n_inserted := n_inserted + sql%rowcount; 55 | 56 | pl(to_char(n_inserted)||' rows inserted in '|| 57 | (to_number(to_char(SYSDATE, 'SSSSS')) - n_start)|| 58 | ' seconds.'); 59 | 60 | commit; 61 | end; 62 | / 63 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.workers_ins_insert_with_constants.sql: -------------------------------------------------------------------------------- 1 | insert into WORKERS ( 2 | id, 3 | worker_type_id, 4 | external_id, 5 | first_name, 6 | middle_name, 7 | last_name, 8 | name, 9 | birth_date, 10 | gender_type_id) 11 | select WORKERS_ID.nextval, 12 | decode(mod(WORKERS_ID.currval, 2), 13 | 0, 2, 1), 14 | lpad(to_char(EXTERNAL_ID_SEQ.nextval), 9, '0'), 15 | first_name, 16 | letter||'.', 17 | last_name, 18 | WORKER.get_formatted_name( 19 | first_name, letter||'.', last_name), 20 | DATE_.random( 21 | to_number(to_char(SYSDATE, 'YYYY')) - 65, 22 | to_number(to_char(SYSDATE, 'YYYY')) - 18), 23 | decode(gender_code, 'F', 1, 2) 24 | from TOP_100_LAST_NAMES, 25 | TOP_100_FIRST_NAMES, 26 | A_THRU_Z; 27 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/rps.workers_ins_insert_with_constants.sql.pln: -------------------------------------------------------------------------------- 1 | 2 | Explained. 3 | 4 | Plan hash value: 3139420850 5 | 6 | ---------------------------------------------------------------------------------------------------- 7 | | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 8 | ---------------------------------------------------------------------------------------------------- 9 | | 0 | INSERT STATEMENT | | 260K| 4570K| 717 (1)| 00:00:01 | 10 | | 1 | LOAD TABLE CONVENTIONAL | WORKERS | | | | | 11 | | 2 | SEQUENCE | WORKERS_ID | | | | | 12 | | 3 | MERGE JOIN CARTESIAN | | 260K| 4570K| 717 (1)| 00:00:01 | 13 | | 4 | MERGE JOIN CARTESIAN | | 2600 | 23400 | 10 (0)| 00:00:01 | 14 | | 5 | INDEX FULL SCAN | A_THRU_Z_PK | 26 | 52 | 1 (0)| 00:00:01 | 15 | | 6 | BUFFER SORT | | 100 | 700 | 9 (0)| 00:00:01 | 16 | | 7 | INDEX FAST FULL SCAN| TOP_100_LAST_NAMES_PK | 100 | 700 | 0 (0)| 00:00:01 | 17 | | 8 | BUFFER SORT | | 100 | 900 | 717 (1)| 00:00:01 | 18 | | 9 | INDEX FAST FULL SCAN | TOP_100_FIRST_NAMES_PK | 100 | 900 | 0 (0)| 00:00:01 | 19 | ---------------------------------------------------------------------------------------------------- 20 | 21 | 16 rows selected. 22 | 23 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/run_profile.sql: -------------------------------------------------------------------------------- 1 | rem run_profile.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Capture DBMS_PROFILER information for the specified script 4 | 5 | define script="&1"; 6 | 7 | set verify off; 8 | 9 | declare 10 | 11 | n_run_number number; 12 | 13 | begin 14 | DBMS_PROFILER.start_profiler( 15 | '&script'||' on '||to_char(SYSDATE, 'YYYYMMDD HH24MISS'), 16 | ' ', 17 | n_run_number); 18 | 19 | pl('DBMS_PROFILER run_number = '||to_char(n_run_number)); 20 | end; 21 | / 22 | 23 | @&script 24 | 25 | execute DBMS_PROFILER.stop_profiler; 26 | execute DBMS_PROFILER.flush_data; 27 | 28 | set verify on; 29 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_equalto.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from WORKERS 3 | where name = 'DOE, JOHN J.' 4 | order by 1; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_equalto.sql.pln: -------------------------------------------------------------------------------- 1 | 2 | Explained. 3 | 4 | Plan hash value: 2276017427 5 | 6 | ---------------------------------------------------------------------------------------------------- 7 | | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 8 | ---------------------------------------------------------------------------------------------------- 9 | | 0 | SELECT STATEMENT | | 1 | 66 | 6 (17)| 00:00:01 | 10 | | 1 | SORT ORDER BY | | 1 | 66 | 6 (17)| 00:00:01 | 11 | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| WORKERS | 1 | 66 | 5 (0)| 00:00:01 | 12 | |* 3 | INDEX RANGE SCAN | WORKERS_UK2 | 1 | | 3 (0)| 00:00:01 | 13 | ---------------------------------------------------------------------------------------------------- 14 | 15 | Predicate Information (identified by operation id): 16 | --------------------------------------------------- 17 | 18 | 3 - access("NAME"='DOE, JOHN J.') 19 | 20 | 15 rows selected. 21 | 22 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_likepct.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from WORKERS 3 | where name like 'DOE%' 4 | order by 1; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_likepct.sql.pln: -------------------------------------------------------------------------------- 1 | 2 | Explained. 3 | 4 | Plan hash value: 2276017427 5 | 6 | ---------------------------------------------------------------------------------------------------- 7 | | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 8 | ---------------------------------------------------------------------------------------------------- 9 | | 0 | SELECT STATEMENT | | 1 | 66 | 6 (17)| 00:00:01 | 10 | | 1 | SORT ORDER BY | | 1 | 66 | 6 (17)| 00:00:01 | 11 | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| WORKERS | 1 | 66 | 5 (0)| 00:00:01 | 12 | |* 3 | INDEX RANGE SCAN | WORKERS_UK2 | 1 | | 3 (0)| 00:00:01 | 13 | ---------------------------------------------------------------------------------------------------- 14 | 15 | Predicate Information (identified by operation id): 16 | --------------------------------------------------- 17 | 18 | 3 - access("NAME" LIKE 'DOE%') 19 | filter("NAME" LIKE 'DOE%') 20 | 21 | 16 rows selected. 22 | 23 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_pctlikepct.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from WORKERS 3 | where name like '%DOE%' 4 | order by 1; 5 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_pctlikepct.sql.pln: -------------------------------------------------------------------------------- 1 | 2 | Explained. 3 | 4 | Plan hash value: 412163233 5 | 6 | -------------------------------------------------------------------------------------- 7 | | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | 8 | -------------------------------------------------------------------------------------- 9 | | 0 | SELECT STATEMENT | | 13000 | 837K| | 1065 (1)| 00:00:01 | 10 | | 1 | SORT ORDER BY | | 13000 | 837K| 1144K| 1065 (1)| 00:00:01 | 11 | |* 2 | TABLE ACCESS FULL| WORKERS | 13000 | 837K| | 856 (1)| 00:00:01 | 12 | -------------------------------------------------------------------------------------- 13 | 14 | Predicate Information (identified by operation id): 15 | --------------------------------------------------- 16 | 17 | 2 - filter("NAME" LIKE '%DOE%' AND "NAME" IS NOT NULL) 18 | 19 | 14 rows selected. 20 | 21 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_pctlikepct2.sql: -------------------------------------------------------------------------------- 1 | select /*+ INDEX(WORKERS WORKERS_UK2) */ 2 | * 3 | from WORKERS 4 | where name like '%DOE%' 5 | order by 1; 6 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_pctlikepct2.sql.pln: -------------------------------------------------------------------------------- 1 | 2 | Explained. 3 | 4 | Plan hash value: 2470337875 5 | 6 | ------------------------------------------------------------------------------------------------------------ 7 | | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | 8 | ------------------------------------------------------------------------------------------------------------ 9 | | 0 | SELECT STATEMENT | | 13000 | 837K| | 14787 (1)| 00:00:01 | 10 | | 1 | SORT ORDER BY | | 13000 | 837K| 1144K| 14787 (1)| 00:00:01 | 11 | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| WORKERS | 13000 | 837K| | 14579 (1)| 00:00:01 | 12 | |* 3 | INDEX FULL SCAN | WORKERS_UK2 | 13000 | | | 1576 (1)| 00:00:01 | 13 | ------------------------------------------------------------------------------------------------------------ 14 | 15 | Predicate Information (identified by operation id): 16 | --------------------------------------------------- 17 | 18 | 3 - filter("NAME" LIKE '%DOE%' AND "NAME" IS NOT NULL) 19 | 20 | 15 rows selected. 21 | 22 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_pctlikepcts.sql.pln: -------------------------------------------------------------------------------- 1 | SP2-0310: unable to open file "select_workers_pctlikepcts.sql" 2 | Plan hash value: 1388734953 3 | 4 | ----------------------------------------------------------------- 5 | | Id | Operation | Name | Rows | Cost (%CPU)| Time | 6 | ----------------------------------------------------------------- 7 | | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | 8 | | 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 | 9 | ----------------------------------------------------------------- 10 | 11 | 8 rows selected. 12 | 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/select_workers_pctlikepcts2.sql.pln: -------------------------------------------------------------------------------- 1 | SP2-0310: unable to open file "select_workers_pctlikepcts2.sql" 2 | Plan hash value: 1388734953 3 | 4 | ----------------------------------------------------------------- 5 | | Id | Operation | Name | Rows | Cost (%CPU)| Time | 6 | ----------------------------------------------------------------- 7 | | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | 8 | | 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 | 9 | ----------------------------------------------------------------- 10 | 11 | 8 rows selected. 12 | 13 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/success.sql: -------------------------------------------------------------------------------- 1 | rem success.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem a script with success messages 4 | 5 | declare 6 | 7 | n_number number; 8 | 9 | begin 10 | pl('begin'); 11 | 12 | n_number := -1; 13 | 14 | pl('No error here!'); 15 | 16 | n_number := 0; 17 | 18 | pl('Still no error here!'); 19 | 20 | n_number := 'one'; 21 | 22 | pl('After the error.'); 23 | 24 | pl('end'); 25 | exception 26 | when OTHERS then 27 | raise_application_error(-20000, SQLERRM|| 28 | ' on assigning a value to n_number'|| 29 | ' in success.sql'); 30 | end; 31 | / 32 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/usi.sql: -------------------------------------------------------------------------------- 1 | rem usi.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Show me my unique session ID 4 | 5 | execute pl('unique_session_id='||SYS.DBMS_SESSION.unique_session_id); 6 | -------------------------------------------------------------------------------- /source_20150125/Chapter07/xp.sql: -------------------------------------------------------------------------------- 1 | rem xp.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Display the execution plan for the last executed cursor 4 | 5 | define script="&1"; 6 | 7 | set linesize 1000; 8 | set newpage 1; 9 | set pagesize 0; 10 | set trimspool on; 11 | set verify off; 12 | 13 | EXPLAIN PLAN FOR 14 | select 1 from DUAL; 15 | 16 | spool &script..pln; 17 | 18 | EXPLAIN PLAN FOR 19 | @&script 20 | 21 | set echo off; 22 | 23 | select * from table(SYS.DBMS_XPLAN.DISPLAY); 24 | 25 | spool off; 26 | 27 | set pagesize 32767; 28 | set verify on; 29 | -------------------------------------------------------------------------------- /source_20150125/MyTools/be.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/MyTools/ci.sql: -------------------------------------------------------------------------------- 1 | rem ci.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Compile my invalid objects 4 | 5 | set feedback off; 6 | set linesize 1000; 7 | set newpage 1; 8 | set pagesize 32767; 9 | set trimspool on; 10 | set serveroutput on size 1000000; 11 | 12 | spool ci.txt; 13 | declare 14 | 15 | cursor c1 is 16 | select object_type, 17 | object_name 18 | from SYS.USER_OBJECTS 19 | where status = 'INVALID' 20 | order by 1, 2; 21 | 22 | v_sql varchar2(100); 23 | 24 | begin 25 | for r1 in c1 loop 26 | begin 27 | if r1.object_type = 'PACKAGE BODY' then 28 | v_sql := 'alter PACKAGE '||r1.object_name||' compile BODY'; 29 | elsif r1.object_type = 'TYPE BODY' then 30 | v_sql := 'alter TYPE '||r1.object_name||' compile BODY'; 31 | else 32 | v_sql := 'alter '||r1.object_type||' '||r1.object_name||' compile'; 33 | end if; 34 | execute immediate v_sql; 35 | pl(r1.object_type||' '||r1.object_name||' compiled successfully'); 36 | exception 37 | when OTHERS then 38 | pl(SQLERRM||' on '||v_sql); 39 | end; 40 | end loop; 41 | end; 42 | / 43 | 44 | spool off; 45 | 46 | set feedback on; 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source_20150125/MyTools/ci.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beg-oracle-pl-sql/0f4f3747713e8560dcdf3725c3fec461e899c885/source_20150125/MyTools/ci.txt -------------------------------------------------------------------------------- /source_20150125/MyTools/ddl_.pkb: -------------------------------------------------------------------------------- 1 | create or replace package body DDL_ as 2 | /* 3 | ddl.pkb 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | */ 7 | 8 | 9 | PROCEDURE dseq( 10 | aiv_sequence_name in varchar2) is 11 | 12 | v_ddl varchar2(500); 13 | 14 | begin 15 | begin 16 | v_ddl := 'drop sequence '||aiv_sequence_name; 17 | 18 | execute immediate v_ddl; 19 | 20 | SYS.DBMS_OUTPUT.put_line('Sequence dropped.'); 21 | exception 22 | when OTHERS then 23 | if SQLCODE = -2289 then 24 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 25 | else 26 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 27 | end if; 28 | end; 29 | end dseq; 30 | 31 | 32 | PROCEDURE dtab( 33 | aiv_table_name in varchar2) is 34 | 35 | v_ddl varchar2(500); 36 | 37 | begin 38 | begin 39 | v_ddl := 'drop table '||aiv_table_name; 40 | 41 | execute immediate v_ddl; 42 | 43 | SYS.DBMS_OUTPUT.put_line('Table dropped.'); 44 | exception 45 | when OTHERS then 46 | if SQLCODE = -942 then 47 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 48 | else 49 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 50 | end if; 51 | end; 52 | end dtab; 53 | 54 | 55 | PROCEDURE dtrg( 56 | aiv_trigger_name in varchar2) is 57 | 58 | v_ddl varchar2(500); 59 | 60 | begin 61 | begin 62 | v_ddl := 'drop trigger '||aiv_trigger_name; 63 | 64 | execute immediate v_ddl; 65 | 66 | SYS.DBMS_OUTPUT.put_line('Trigger dropped.'); 67 | exception 68 | when OTHERS then 69 | if SQLCODE = -4080 then 70 | SYS.DBMS_OUTPUT.put_line(substr(SQLERRM, instr(SQLERRM, ': ') + 2, 255)); 71 | else 72 | SYS.DBMS_OUTPUT.put_line(SQLERRM); 73 | end if; 74 | end; 75 | end dtrg; 76 | 77 | 78 | end DDL_; 79 | / 80 | @be.sql 81 | -------------------------------------------------------------------------------- /source_20150125/MyTools/ddl_.pks: -------------------------------------------------------------------------------- 1 | create or replace package DDL_ as 2 | /* 3 | ddl.pks 4 | by Donald J. Bales on 2014-10-20 5 | Error-less DDL commands 6 | 7 | Some database objects have a create or replace syntax. While you're developing 8 | that can be quite handy because it allows you to easily create a re-runnable 9 | script. This package adds a cuople of errorless drop commands that also make 10 | it easier to create a re-runnable script. 11 | */ 12 | 13 | 14 | -- Drop the specified sequence if it exists. 15 | -- If it does not, report nothing, otherwise 16 | -- report the SQLERRM 17 | PROCEDURE dseq( 18 | aiv_sequence_name in varchar2); 19 | 20 | 21 | -- Drop the specified table if it exists. 22 | -- If it does not, report nothing, otherwise 23 | -- report the SQLERRM 24 | PROCEDURE dtab( 25 | aiv_table_name in varchar2); 26 | 27 | 28 | -- Drop the specified trigger if it exists. 29 | -- If it does not, report nothing, otherwise 30 | -- report the SQLERRM 31 | PROCEDURE dtrg( 32 | aiv_trigger_name in varchar2); 33 | 34 | 35 | end DDL_; 36 | / 37 | @se.sql 38 | -------------------------------------------------------------------------------- /source_20150125/MyTools/desc.sql: -------------------------------------------------------------------------------- 1 | define table_name="&1"; 2 | set linesize 78; 3 | prompt &table_name 4 | desc &table_name 5 | set linesize 1000; 6 | undefine table_name -------------------------------------------------------------------------------- /source_20150125/MyTools/drop_all.sql: -------------------------------------------------------------------------------- 1 | declare 2 | 3 | cursor c1 is 4 | select 'DROP '|| 5 | decode(object_type, 6 | 'PACKAGE SPECIFICATION', 'PACKAGE', 7 | 'TYPE SPECIFICATION', 'TYPE', 8 | object_type)|| 9 | ' '|| 10 | object_name sql_statement 11 | from USER_OBJECTS 12 | where object_name not in ('DDL_', 'PL'); 13 | 14 | n_count number := 0; 15 | 16 | begin 17 | for i in 1..5 loop 18 | for r1 in c1 loop 19 | begin 20 | execute immediate r1.sql_statement; 21 | 22 | n_count := n_count + 1; 23 | exception 24 | when OTHERS then 25 | null; 26 | end; 27 | end loop; 28 | end loop; 29 | SYS.DBMS_OUTPUT.put_line(n_count||' objects dropped.'); 30 | end; 31 | / 32 | 33 | -------------------------------------------------------------------------------- /source_20150125/MyTools/fe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/MyTools/login.sql: -------------------------------------------------------------------------------- 1 | rem login.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem Set my default SQL*Plus environment 4 | set linesize 1000; 5 | set newpage 1; 6 | set pagesize 32767; 7 | set serveroutput on size 1000000; 8 | set trimspool on; 9 | prompt default settings loaded successfully! 10 | -------------------------------------------------------------------------------- /source_20150125/MyTools/pe.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | -------------------------------------------------------------------------------- /source_20150125/MyTools/pl.prc: -------------------------------------------------------------------------------- 1 | create or replace PROCEDURE pl( 2 | aiv_text in varchar2 ) is 3 | /* 4 | pl.prc 5 | by Donald J. Bales on 2014-10-20 6 | A wrapper procedure for SYS.DBMS_OUTPUT.put_line() 7 | for the lazy typist. 8 | */ 9 | 10 | begin 11 | SYS.DBMS_OUTPUT.put_line(aiv_text); 12 | end pl; 13 | / 14 | @pe.sql pl 15 | -------------------------------------------------------------------------------- /source_20150125/MyTools/pl.sql: -------------------------------------------------------------------------------- 1 | rem pl.sql 2 | rem by Donald J. Bales on 2014-10-20 3 | rem pl's test unit 4 | 5 | prompt 'Test a line <= 255'; -- 20 21 22 23 24 25 6 | exec pl('12345678901234567890123456789012345678901234567890'|| 7 | '12345678901234567890123456789012345678901234567890'|| 8 | '12345678901234567890123456789012345678901234567890'|| 9 | '12345678901234567890123456789012345678901234567890'|| 10 | '1234567890123456789012345678901234567890123456789012345'); 11 | prompt 'Test a line > 255'; 12 | exec pl('12345678901234567890123456789012345678901234567890'|| 13 | '12345678901234567890123456789012345678901234567890'|| 14 | '12345678901234567890123456789012345678901234567890'|| 15 | '12345678901234567890123456789012345678901234567890'|| 16 | '12345678901234567890123456789012345678901234567890'|| 17 | '12345678901234567890123456789012345678901234567890'); 18 | prompt 'Test a multi-line'; 19 | exec pl('12345678901234567890123456789012345678901234567890'|| 20 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 21 | '12345678901234567890123456789012345678901234567890'|| 22 | '12345678901234567890123456789012345678901234567890'||chr(10)|| 23 | '12345678901234567890123456789012345678901234567890'|| 24 | '12345678901234567890123456789012345678901234567890'); 25 | -------------------------------------------------------------------------------- /source_20150125/MyTools/se.sql: -------------------------------------------------------------------------------- 1 | show errors 2 | --------------------------------------------------------------------------------