G-7230: Avoid declaring global variables public.
Major
Reliability
Reason
You should always declare package-level data inside the package body. You can then define "get and set" methods (functions and procedures, respectively) in the package specification to provide controlled access to that data. By doing so you can guarantee data integrity, you can change your data structure implementation, and also track access to those data structures.
Data structures (scalar variables, collections, cursors) declared in the package specification (not within any specific program) can be referenced directly by any program running in a session with EXECUTE rights to the package.
Instead, declare all package-level data in the package body and provide "get and set" methods - a function to get the value and a procedure to set the value - in the package specification. Developers then can access the data using these methods - and will automatically follow all rules you set upon data modification.
Example (bad)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | create or replace package employee_api as k_min_increase constant types.sal_increase_type := 0.01; k_max_increase constant types.sal_increase_type := 0.5; g_salary_increase types.sal_increase_type := k_min_increase; procedure set_salary_increase (in_increase in types.sal_increase_type); function salary_increase return types.sal_increase_type; end employee_api; / create or replace package body employee_api as procedure set_salary_increase (in_increase in types.sal_increase_type) is begin g_salary_increase := greatest(least(in_increase,k_max_increase) ,k_min_increase); end set_salary_increase; function salary_increase return types.sal_increase_type is begin return g_salary_increase; end salary_increase; end employee_api; / |
Example (good)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | create or replace package employee_api as procedure set_salary_increase (in_increase in types.sal_increase_type); function salary_increase return types.sal_increase_type; end employee_api; / create or replace package body employee_api as g_salary_increase types.sal_increase_type(4,2); procedure init; procedure set_salary_increase (in_increase in types.sal_increase_type) is begin g_salary_increase := greatest(least(in_increase ,constants.max_salary_increase()) ,constants.min_salary_increase()); end set_salary_increase; function salary_increase return types.sal_increase_type is begin return g_salary_increase; end salary_increase; procedure init is begin g_salary_increase := constants.min_salary_increase(); end init; begin init(); end employee_api; / |