Y
You already faced this issue. You need to change/remove function and you don't know where it is used. Or you need to know if the functions is even used somewhere. Oracle provides us with user_source/all_source views where you can easily search source code of procedures, functions, packages and triggers. But views are tricky, there are no such objects for views. Fortunately you can create your own from view definition stored as LONG in user_views.text column.
Lets create a table which will store the view source lines:
CREATE TABLE user_views_source ( owner VARCHAR2(30) CONSTRAINT nn_user_views_source_owner NOT NULL, name VARCHAR2(30) CONSTRAINT nn_user_views_source_name NOT NULL, line NUMBER(10) CONSTRAINT nn_user_views_source_line NOT NULL, text VARCHAR2(2000), -- CONSTRAINT pk_user_views_source PRIMARY KEY (owner, name, line) ); -- COMMENT ON TABLE user_views_source IS '[CORE] User views source converted to lines';
Then you need to create this procedure to convert view definitions to this table (as lines to mimic user_source view):
CREATE OR REPLACE PROCEDURE rebuild_user_views_source ( in_owner all_views.owner%TYPE := NULL ) AS v_content VARCHAR2(32767); -- FUNCTION get_user_views_text ( in_view_name all_views.view_name%TYPE, in_owner all_views.owner%TYPE := NULL ) RETURN VARCHAR2 AS out_text all_views.text%TYPE; BEGIN SELECT v.text INTO out_text FROM all_views v WHERE v.owner = NVL(in_owner, USER) AND v.view_name = in_view_name; -- RETURN out_text; END; BEGIN DELETE FROM user_views_source t WHERE t.owner = NVL(in_owner, USER); -- FOR c IN ( SELECT t.owner, t.view_name AS name FROM all_views t WHERE t.owner = NVL(in_owner, USER) ) LOOP v_content := get_user_views_text(c.name, c.owner); -- INSERT INTO user_views_source (owner, name, line, text) SELECT c.owner, c.name, LEVEL AS line, REGEXP_SUBSTR(v_content, '^.*$', 1, LEVEL, 'm') AS text FROM DUAL CONNECT BY REGEXP_SUBSTR(v_content, '^.*$', 1, LEVEL, 'm') IS NOT NULL AND PRIOR c.name = c.name AND PRIOR SYS_GUID() IS NOT NULL; END LOOP; END; /
Usage is simple. Just refresh this table before searching (or on regular/event basis) using the procedure above. And then you can search source code including the views.
BEGIN rebuild_user_views_source(); COMMIT; END; / -- WITH x AS ( SELECT '&SEARCH' AS search_string FROM DUAL ) -- SELECT t.name, 'VIEW' AS type, t.line, t.text FROM user_views_source t CROSS JOIN x WHERE UPPER(t.text) LIKE '%' || UPPER(x.search_string) || '%' ESCAPE '\' UNION ALL -- SELECT t.name, t.type, t.line, t.text FROM user_source t CROSS JOIN x WHERE UPPER(t.text) LIKE '%' || UPPER(x.search_string) || '%' ESCAPE '\';
Update
You can easily adjust the query to search for multiple words (in the same object but not on different lines). Following query will returns all objects which contains both &FIRST and &SECOND words.
WITH z AS ( SELECT '&FIRST' AS searching_for FROM DUAL UNION ALL SELECT '&SECOND' FROM DUAL ), x AS ( SELECT z.*, ROW_NUMBER() OVER (ORDER BY NULL) AS r# FROM z ), s AS ( SELECT s.name, 'VIEW' AS type, s.line, s.text, x.r# FROM src_views s CROSS JOIN x WHERE UPPER(s.text) LIKE UPPER('%' || x.searching_for || '%') UNION ALL -- SELECT s.name, s.type, s.line, s.text, x.r# FROM user_source s CROSS JOIN x WHERE UPPER(s.text) LIKE UPPER('%' || x.searching_for || '%') ) SELECT s.* FROM s WHERE (s.name, s.type) IN ( SELECT s.name, s.type FROM s GROUP BY s.name, s.type HAVING COUNT(DISTINCT s.r#) = (SELECT COUNT(*) FROM x) ) ORDER BY 1, 2, 3;
Comments
Post a Comment