Auswahl  

 

Oracle
PL/SQL
12.1
PL/SQL, SQL
25.06.18
MP
25.06.18
MP

Body

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 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>%';