I
If you have a constants in a package you might want to expose them to your SQL queries. You wont able to access them from your SQL statements (for example from views or adhoc queries) unless you create a function for each of them and call that function instead of the constant.
With the generator your functions will be consistent, typo free and with correct datatypes.
Here is a generator for that:
SET SERVEROUTPUT ON SIZE UNLIMITED DECLARE in_package_name CONSTANT VARCHAR2(30) := 'CONSTANTS'; -- source package with constants in_constant_prefix CONSTANT VARCHAR2(30) := ''; -- process just constants starting with this prefix in_fn_prefix CONSTANT VARCHAR2(30) := 'get_'; -- add optional prefix to functions in_generate_body CONSTANT BOOLEAN := TRUE; -- switch between spec and body generator BEGIN FOR c IN ( SELECT LOWER(s.name) AS package_name, REGEXP_SUBSTR(LOWER(s.text), LOWER(in_constant_prefix) || '[a-z0-9_]+') AS constant_name, REGEXP_SUBSTR(UPPER(s.text), '\sCONSTANT\s+([A-Z0-9_]+\.?[A-Z0-9_]*(%TYPE)?)', 1, 1, NULL, 1) AS data_type, s.text, '%' || REPLACE(LOWER(in_constant_prefix), '_', '\_') || LOWER('% CONSTANT %') AS like_ FROM user_source s WHERE s.type = 'PACKAGE' AND s.name = UPPER(in_package_name) AND LOWER(s.text) LIKE '%' || REPLACE(LOWER(in_constant_prefix), '_', '\_') || LOWER('% CONSTANT %') ESCAPE '\' ORDER BY s.line ) LOOP DBMS_OUTPUT.PUT_LINE(''); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' FUNCTION %s%s', LOWER(in_fn_prefix), REPLACE(c.constant_name, LOWER(in_constant_prefix), ''))); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' RETURN %s', CASE WHEN INSTR(c.data_type, '%TYPE') > 0 THEN REPLACE(LOWER(c.data_type), '%type', '%TYPE') ELSE c.data_type END)); -- IF in_generate_body THEN DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' DETERMINISTIC')); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' AS')); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' PRAGMA UDF;')); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' BEGIN')); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' RETURN %s.%s;', c.package_name, c.constant_name)); DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' END;', c.data_type)); DBMS_OUTPUT.PUT_LINE(''); DBMS_OUTPUT.PUT_LINE(''); ELSE DBMS_OUTPUT.PUT_LINE(APEX_STRING.FORMAT(' DETERMINISTIC;')); END IF; END LOOP; END; /
You just call it once for specification, once for body and copy the content into your package.
And with some modifications you cound generate get and set functions to use similar approach for package variables.
Comments
Post a Comment