Download presentation
Presentation is loading. Please wait.
Published byBrian Campbell Modified over 11 years ago
1
SAGE Computing Services Customised Oracle Training Workshops and Consulting Creative Conditional Compilation … and raising the bar with your PL/SQL Scott Wesley Systems Consultant
3
The example everybodys seen…
4
PL/SQL Users Guide & Reference 10g Release 2 –Fundamentals of the PL/SQL Language Conditional Compilation
5
Availability 11g Release 1 10g Release 2 –Enabled out of the box 10.1.0.4 – Once patched, enabled by default –Disable using _parameter 9.2.0.6 – Once patched, disabled by default –Enable using _parameter
6
Catch 22 INDICES OF
7
Catch 22 Conditional Compilation Patch INDICES OF
8
Facilitates removal of unnecessary code at compile time Performance Readability Accuracy Testing It's cool!
9
Selection Directives $IF boolean_static_expression $THEN text [ $ELSIF boolean_static_expression $THEN text ] [ $ELSE text ] $END Inquiry Directives DBMS_OUTPUT.PUT_LINE($$PLSQL_LINE); ALTER SESSION SET PLSQL_CCFLAGS= ' max_sentence:100 ' ; IF sentence > $$max_sentence THEN Error Directives $IF $$PLSQL_OPTIMIZE_LEVEL != 2 $THEN $ERROR 'intensive_program must be compiled with maximum optimisation' $END Semantics
10
Inquiry Directives
11
> BEGIN DBMS_OUTPUT.PUT_LINE('Unit:'||$$PLSQL_UNIT); DBMS_OUTPUT.PUT_LINE('Line:'||$$PLSQL_LINE); END anon; / Unit: Line:4
12
> CREATE OR REPLACE PROCEDURE sw_test IS BEGIN DBMS_OUTPUT.PUT_LINE('Unit:'||$$PLSQL_UNIT); DBMS_OUTPUT.PUT_LINE('Line:'||$$PLSQL_LINE); END sw_test; / Procedure created. > exec sw_test Unit:SW_TEST Line:4
13
ALTER SESSION SET PLSQL_CCFLAGS = 'max_sentence:100'; Session altered.
14
> BEGIN IF p_sentence < $$max_sentence THEN DBMS_OUTPUT.PUT_LINE('Parole Available'); ELSE DBMS_OUTPUT.PUT_LINE('Life'); END IF; END; / Life
15
ALTER SYSTEM SET PLSQL_CCFLAGS = 'VARCHAR2_SIZE:100, DEF_APP_ERR:-20001'; DECLARE lc_variable_chr VARCHAR2($$VARCHAR2_SIZE); e_def_app_err EXCEPTION; PRAGMA EXCEPTION_INIT (e_def_app_err, $$DEF_APP_ERR); BEGIN --> rest of your code END anon; /
16
First Demo: Post-processed Source Demo: cc1.sql cc2.sql
17
Reuse Settings
18
ALTER SYSTEM SET PLSQL_CCFLAGS = 'MY_PI:314'; CREATE OR REPLACE PROCEDURE universe_alpha IS BEGIN DBMS_OUTPUT.PUT_LINE('Alpha pi = '||$$my_pi/100); END; CREATE OR REPLACE PROCEDURE universe_gamma IS BEGIN DBMS_OUTPUT.PUT_LINE('Gamma pi = '||$$my_pi/100); END; CREATE OR REPLACE PROCEDURE universe_oz IS BEGIN DBMS_OUTPUT.PUT_LINE('Oz pi = '||$$my_pi/100); END; ALTER PROCEDURE universe_alpha COMPILE PLSQL_CCFLAGS = 'MY_PI:289' REUSE SETTINGS; ALTER PROCEDURE universe_gamma COMPILE PLSQL_CCFLAGS = 'MY_PI:423' REUSE SETTINGS; > BEGIN universe_alpha; universe_gamma; universe_oz; END; / Alpha pi = 2.89 Gamma pi = 4.23 Oz pi = 3.14
19
Second Demo: Directive Usage Demo: cc3.sql cc4.sql cc5.sql
20
Some versioning examples?
21
Using new version code today $IF dbms_db_version.ver_le_10 $THEN -- version 10 and earlier code $ELSIF dbms_db_version.ver_le_11 $THEN -- version 11 code $ELSE -- version 12 and later code $END
22
10.1 vs 10.2 dbms_output
23
CREATE OR REPLACE PROCEDURE sw_debug (p_text IN VARCHAR2) IS $IF $$sw_debug_on $THEN l_text VARCHAR2(32767); $END BEGIN $IF $$sw_debug_on $THEN -- Lets provide debugging info $IF dbms_db_version.ver_le_10_1 $THEN -- We have to truncate for <= 10.1 l_text := SUBSTR(p_text, 1,200); $ELSE l_text := p_text; $END DBMS_OUTPUT.PUT_LINE(p_text); $ELSE -- No debugging NULL; $END END sw_debug;
26
10g vs 11g result_cache FUNCTION quantity_ordered (p_item_id IN items.item_id%TYPE) RETURN NUMBER $IF dbms_version.ver_le_10 $THEN -- nothing $ELSE RESULT_CACHE $END IS BEGIN...
27
9i vs 10g Bulk Insert
28
CREATE OR REPLACE PACKAGE BODY sw_bulk_insert IS PROCEDURE sw_insert (sw_tab IN t_sw_tab) IS BEGIN $IF dbms_db_version.ver_le_9 $THEN DECLARE l_dense t_sw_tab; ln_index PLS_INTEGER := sw_tab.FIRST; BEGIN > WHILE (l_index IS NOT NULL) LOOP l_dense(l_dense.COUNT + 1) := sw_tab(l_index); l_index := sw_tab.NEXT(l_index); END LOOP dense_loop; FORALL i IN 1..l_dense.COUNT INSERT INTO sw_table VALUES l_dense(i); END; $ELSE FORALL i IN INDICES OF sw_tab INSERT INTO sw_table VALUES sw_tab(i); $END END sw_insert; END sw_bulk_insert;
31
Paradigm Examples
32
Latent debugging code
33
CREATE OR REPLACE PACKAGE pkg_debug IS debug_flag CONSTANT BOOLEAN := FALSE; END pkg_debug; / CREATE OR REPLACE PROCEDURE sw_proc IS BEGIN $IF pkg_debug.debug_flag $THEN dbms_output.put_line ('Debugging Details'); $END END sw_proc; /
34
Assertions ?
35
Assertions should be used to document logically impossible situations Development tool Testing Aid In-line Documentation if the impossible occurs, then something fundamental is clearly wrong. This is distinct from error handling. Run-time Cost
36
Latent Assertions ?
37
The removal of assertions from production code is almost always done automatically. It usually is done via conditional compilation. www.answers.com/topic/assert
38
$IF $$asserting OR CC_assertion.asserting $THEN IF p_param != c_pi*r*r THEN raise_application_error(.. END IF; $END -- individual program unit -- entire application
39
Testing subprograms only in package body
40
CREATE PACKAGE universe IS PROCEDURE create_sun; PROCEDURE create_planets; -- CC test procedure PROCEDURE test_orbit; END universe; CREATE PACKAGE BODY universe IS -- Private PROCEDURE orbit IS.. END; -- Public PROCEDURE create_sun IS.. END; PROCEDURE create_planets IS.. END; -- Testers PROCEDURE test_orbit IS BEGIN $IF $$testing $THEN orbit; $ELSE RAISE program_error; $END END test_orbit; END universe;
41
CREATE PACKAGE universe IS PROCEDURE create_sun; PROCEDURE create_planets; -- CC test sequence PROCEDURE test_run; END universe; CREATE PACKAGE BODY universe IS -- Private PROCEDURE orbit IS.. END; -- Public PROCEDURE create_sun IS.. END; PROCEDURE create_planets IS.. END; -- Test sequence PROCEDURE test_run IS BEGIN $IF $$testing $THEN create_sun; create_planets; orbit; $ELSE RAISE program_error; $END END test_run; END universe;
42
Mock objects
43
FUNCTION get_emp(p_emp_id IN emp.emp_id%TYPE) RETURN t_emp IS l_emp t_emp; BEGIN $IF $$mock_emp $THEN l_emp.emp_name := 'Scott';.. RETURN l_emp; $ELSE SELECT * FROM emp INTO l_emp WHERE emp_id = p_emp_id; RETURN l_emp; $END END get_emp;
44
Comparing competing implementations during prototyping
45
PROCEDURE xyz IS $IF $$alternative = 1 $THEN -- varray declaration $ELSIF $$alternative = 2 $THEN -- nested table declaration $END BEGIN $IF $$alternative = 1 $THEN -- simple varray solution $ELSIF $$alternative = 2 $THEN -- elegant nested table solution $END END xyz; $IF $$alternative = 1 $THEN -- first verbose solution that came to mind $ELSIF $$alternative = 2 $THEN -- some crazy idea you came up with at 3am you need to try out $END
46
Component Based Installation
47
PACKAGE BODY core IS PROCEDURE execute_component(p_choice IN VARCHAR2) IS BEGIN CASE p_choice -- Base is always installed. WHEN 'base' THEN base.main(); $IF CC_licence.cheap_installed $THEN WHEN 'cheap' THEN cheap.main(); $END... $IF CC_licence.pricey_installed $THEN WHEN 'pricey' THEN pricey.main(); $END END CASE; EXCEPTION WHEN case_not_found THEN dbms_output.put_line('Component '||p_choice||' is not installed.'); END execute_component; END core;
48
Get It Right with the Error Directive
49
$IF $$PLSQL_OPTIMIZE_LEVEL != 2 $THEN $ERROR 'intensive_program must be compiled with maximum optimisation' $END
50
BEGIN... /* * * Note to self: Must remember to finish this bit * */... END;
51
BEGIN... -- Jacko: this doesnt work, fix before moving to prod!... END;
52
1 CREATE PROCEDURE process_court_outcome IS 2 BEGIN 3 IF lr_victim.age > 18 THEN 4 send_to_prison(lr_victim); 5 ELSE 6 $ERROR 7 'Waiting for business to advise '|| 8 $$PLSQL_UNIT||' line: '||$$PLSQL_LINE 9 $END 10 END IF; 11 END process_court_outcome; 12 / Warning: Procedure created with compilation errors. SQL> sho err LINE/COL ERROR -------- ---------------------------------------- 6/6 PLS-00179: $ERROR: Waiting for business to advise PROCESS_COURT_OUTCOME line: 8
53
CREATE OR REPLACE PACKAGE pkg_debug IS debug_flag CONSTANT BOOLEAN := FALSE; $IF $$CC_dev_notes $THEN PROCEDURE insert_dev_note(p_note IN VARCHAR2,p_unit IN VARCHAR2,p_line IN VARCHAR2) IS PRAGMA AUTONOMOUS TRANSACTION; BEGIN INSERT INTO dev_notes (note, unit, line) VALUES (p_note, p_unit, p_line); END insert_dev_note; $END END pkg_debug; /
54
CREATE PROCEDURE process_court_outcome IS BEGIN IF lr_victim.age > 18 THEN send_to_prison(lr_victim); ELSE pkg_debug.insert_dev_note ('Waiting for business to advise',$$PLSQL_UNIT,$$PLSQL_LINE); END IF; END process_court_outcome; /
55
Good Practices
56
Inquiry directives have null values for normal behaviour $IF $$cc_flag = 'x' $THEN cc_code; $END
57
Choose restriction type carefully $IF $$debug_on OR module_y.cc_debug $THEN sw_debug('Error'); $END
58
but theres always this...
59
SQL> define debug=/* begin &debug select 'conditionally' into :c1 from dual; -- */ select 'always' into :c2 from dual; end; /
60
SAGE Computing Services Customised Oracle Training Workshops and Consulting Questions and Answers? Presentations are available from our website: http://www.sagecomputing.com.au enquiries@sagecomputing.com.au scott.wesley@sagecomputing.com.au
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.