T
Typically you have some constants in packages. And sooner or later you need to use these constants in SQL statements outside of the package, like in a view. Sadly even the latest Oracle 23ai won't help you with this. The solution is to create a function for each constant, which can be very tedious if you have many constants.
I have created a generator to automate this, but here is a different approach. We have can utilize the USER_SOURCE view to get the constant value and the USER_IDENTIFIERS view to localize constants in the package. With this approach you can also expose constants from the BODY.
Here is the function:
CREATE OR REPLACE FUNCTION get_constant ( in_package VARCHAR2, in_name VARCHAR2, in_prefix VARCHAR2 := NULL, in_private CHAR := NULL ) RETURN VARCHAR2 RESULT_CACHE AS out_value VARCHAR2(4000); BEGIN SELECT NULLIF( REGEXP_REPLACE( REGEXP_REPLACE( REGEXP_REPLACE( LTRIM(SUBSTR(s.text, INSTR(s.text, ':=') + 2)), ';\s*[-]{2}.*$', ';'), '[;]\s*', ''), '(^[''])|(['']\s*$)', ''), 'NULL') INTO out_value FROM user_identifiers t JOIN user_source s ON s.name = t.object_name AND s.type = t.object_type AND s.line = t.line WHERE t.object_name = UPPER(in_package) AND t.object_type = 'PACKAGE' || CASE WHEN in_private IS NOT NULL THEN ' BODY' END AND t.name = UPPER(in_prefix || in_name) AND t.type = 'CONSTANT' AND t.usage = 'DECLARATION' AND t.usage_context_id = 1; -- RETURN out_value; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NULL; END; /
I would suggest to create one function for strings, other two for numbers and dates so you can avoid implicit data type conversions.
This approach can be very helpful if you want to just create some adhoc queries or if your project is small and you are lazy. These dictionary views might be a bit slow, so you might consider using the materialized view for the query.
Comments
Post a Comment