Manchmal umfassen Applikationen nicht nur viel Quelltext, sondern auch sehr viele Views, in denen u. a. auch Funktionen aus diversen Packages verwendet werden. Wenn nun eine bestimmte Funktion geändert werden soll / muss, so sollte man dringend im Vorfeld klären, welche Stellen davon betroffen sind. So kann man sichergehen, dass die gewünschte Änderung keine unerwünschten Nebenwirkungen hat.
Dazu muss man aber erst einmal herausfinden, wo die betreffende Funktion überall aufgerufen wird.
Sofern sich die Signatur der Funktion hinreichend ändert, z. B. weil ein weiterer Parameter dazu kommt, kann man dazu theoretisch in einer Testumgebung einfach die Funktion abändern und schauen, was dadurch INVALID wird und es auch nach Neukompilierung bleibt.
Wenn sich aber die Signatur NICHT ändert, oder wenn keine vernünftige Testumgebung zur Verfügung steht (sowas soll es geben), dann muss man sich anderweitig auf die Suche begeben.
Abhängigkeiten helfen hier in aller Regel nicht wirklich weiter: USER_DEPENDENCIES listet nur das Package auf, nicht die einzelne Funktion. Und wenn das Package eine Reihe von Hilfsfunktionen beinhaltet, ist man - fast - genau so schlau wie vorher.
Solange es sich um Aufrufe innerhalb von PL/SQL handelt, sind die Stellen noch relativ einfach zu finden:
SELECT * FROM user_source WHERE LOWER(text) LIKE '%<funktionsname>%';
Bei Views dagegen wird die Sache schwieriger. Rein intuitiv würde man es ja analog probieren mit:
SELECT * FROM user_views WHERE LOWER(text) LIKE '%<funktionsname>%';
Das funktioniert aber nicht, weil text vom Typ LONG ist. Und so wird die Abfrage quittiert mit:
ORA-00932: Inkonsistente Datentypen: CHAR erwartet, LONG erhalten
Und jede View einzeln anschauen, kann sehr mühsam werden. Da hilft am besten ein kleiner Umweg über PL/SQL:
CREATE OR REPLACE FUNCTION read_view_text ( p_viewname IN VARCHAR2)
RETURN VARCHAR2
IS
v_text VARCHAR2 (32767);
BEGIN
SELECT text
INTO v_text
FROM user_views
WHERE UPPER(view_name) = UPPER(p_viewname);
RETURN v_text;
EXCEPTION
WHEN OTHERS
THEN
RETURN NULL;
END read_view_text;
/
Und dann sucht man mit Hilfe dieser Funktion:
SELECT * FROM user_views
WHERE LOWER(read_view_text(view_name)) LIKE '%<funktionsname>%';
Das Prinzip ist natürlich auch auf andere LONG-Spalten anwendbar, z. B. query in user_snapshots / user_mviews.
Ab Version 12.1 hat user_views ein paar neue Spalten erhalten, u. a. auch text_vc vom Typ VARCHAR2(4000). Und damit funktioniert das ganze dann direkt (zumindest für die ersten 4000 Bytes):
SELECT * FROM user_views WHERE LOWER(text_vc) LIKE '%<funktionsname>%';