Auswahl  

 

Oracle
DBA, Netzwerk
RDBMS 11.x:RDBMS 12.x:RDBMS 18.1:RDBMS 18.3:RDBMS 19.1
07.11.17 (MP)
15.06.18 (MM)
External Table, DBA

Body

Wie oft möchte man den einen oder anderen Netzwerkparameter aus den Dateien tnsnames.ora, listener.ora oder sqlnet.ora von einem Unix-Server auslesen? Was also tun?

Variante 1 (relativ umständlich):

1. Putty zur Datenbank-Maschine öffnen
2. Anmelden als oracle
3. Wechseln ins ORACLE_HOME/network/admin Verzeichnis
4. cat listener.ora absetzen

Variante 2 (sehr praktisch): in einem SQL-Client folgenden SQL-Befehl absetzen:

SELECT system.get_net_files('LISTENER.ORA') FROM dual;


Wenn Sie sich für die zweite Lösung entschieden haben, hier der Code zur Funktion:

Hinweis: Der Inhaber der Funktion muss folgende Rechte direkt besitzen: CREATE TABLE, CREATE ANY DIRECTORY und DROP ANY DIRECTORY

Also, wenn der Benutzer SYSTEM die Funktion bekommen soll:

GRANT CREATE ANY DIRECTORY TO system;
GRANT DROP ANY DIRECTORY TO system;


PL/SQL Funktions-Code:

CREATE OR REPLACE FUNCTION get_net_files(file_name IN VARCHAR2)
  RETURN  sys.ODCIVarchar2List PIPELINED
IS
  PRAGMA AUTONOMOUS_TRANSACTION;
    v_path VARCHAR2(2001);
    v_sql  VARCHAR2(2001);
    v_text VARCHAR2(4000);
    curs   sys_refcursor;
BEGIN
  -- Nur diese drei Dateien dürfen verwendet werden
  IF upper(file_name) not in ('TNSNAMES.ORA','LISTENER.ORA','SQLNET.ORA') THEN
    RAISE_APPLICATION_ERROR
    (-20500,'Invalid Filename: Allowed only: TNSNAMES.ORA,LISTENER.ORA,SQLNET.ORA');
  END IF;

-- Pfad für die Netzwerdateien verwenden.
-- Windows akzeptiert auch Slashes (Unix aber keine Backslashes :-) )

SELECT sys_context('userenv','ORACLE_HOME')||'/network/admin' INTO v_path from dual;

-- Temp Directory anlegen
  v_sql:='CREATE OR REPLACE DIRECTORY my_network_path$ AS '''||v_path||'''';
    EXECUTE IMMEDIATE v_sql;

-- Falls Tabelle schon vorhanden ist, löschen

BEGIN
  v_sql:='DROP TABLE system.network_temp_tab';
  EXECUTE IMMEDIATE v_sql;
  EXCEPTION WHEN OTHERS THEN NULL;
END;

-- External Tabelle anlegen. Diese nimmt den Inhalt einer der Netzwerkdateien auf
-- Wir verwenden keine Logfiles (da würden sonst Fehler für jede leere Zeile stehen)
-- Auch Bad und Discarddateien ersparen wir uns
-- Das Trennzeichen $$ gibt es in den Dateien nicht, also wird die komplette Zeile in die
-- Spalte text gelesen

v_sql:=q'!CREATE TABLE system.network_temp_tab
  (text VARCHAR2(4000))
  ORGANIZATION EXTERNAL
    (TYPE ORACLE_LOADER
     DEFAULT DIRECTORY my_network_path$
     ACCESS PARAMETERS (RECORDS DELIMITED BY NEWLINE
                        NOBADFILE NODISCARDFILE NOLOGFILE
                        FIELDS TERMINATED BY '$$' LDRTRIM
                        REJECT ROWS WITH ALL NULL FIELDS)     
     LOCATION ('!'||lower(file_name)||q'!'))
   REJECT LIMIT 5000!';
  EXECUTE IMMEDIATE v_sql;

-- Refcursor muss verwendet werden, weil Tabelle zum Kompilierungszeitpunkt noch nicht vorhanden ist

OPEN curs FOR 'SELECT text FROM system.network_temp_tab';
  LOOP
    FETCH curs INTO v_text;
    EXIT WHEN curs%NOTFOUND OR curs%NOTFOUND IS NULL;
    PIPE ROW (v_text);
  END LOOP;
CLOSE curs;

-- Temp Directory und Tabelle wieder aufräumen

v_sql:='DROP TABLE system.network_temp_tab';
  EXECUTE IMMEDIATE v_sql;
v_sql:='DROP DIRECTORY  my_network_path$';
  EXECUTE IMMEDIATE v_sql;
  COMMIT;
END;
/


Im SQL Developer bekommt man dann bei folgendem Select ...

SELECT system.get_net_files('LISTENER.ORA') FROM dual;


...die Ausgabe:

gsdgsdg

 

Besuchen Sie uns doch bei einer unsere über 40 Oracle Schulungen in München - Unterhaching.