Announcement

Collapse
No announcement yet.

Datenbank Link in einer Prozedur

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Datenbank Link in einer Prozedur

    Hallo zusammen,

    ich habe eine Prozedur, die über einen Datenbank Link auf eine zweite Datenbank zugreift. Wenn der Link aktiv ist, alles kein Problem.
    Das Programm, was nun die Prozedur aufruft, legt diesen Link an. Beim Beenden wird dieser Link wieder gelöscht.
    Wenn ich nun die Prozedur Compilieren will (z.B. nach einem Update), dann läuft dies auf eine Fehlermeldung: ORA-04054: database link TEST does not exist
    Gibt es eine Möglichkeit, die Prozedur trotz des fehlenden Links zu compilieren?

  • #2
    Hallo, Das koennte ueber das<BR>
    EXECUTE IMMEDIATE Statement gehen.<BR>
    Hier wird das SQL Satement in einen String verpackt.<BR>
    Somit ist es egal ob ein Link oder ein anderes Objekt existiert.<BR>
    Bsp:<BR>
    procedure t1<BR>
    as<BR>
    stmt VARCHAR2(200);<BR>
    begin<BR>
    stmt := 'SELECT * FROM OWNER.TABELLE@DBLINK WHERE NR >= 200';<BR>
    EXECUTE IMMEDIATE stmt;<BR>
    -- Kein Anpsruch auf absolute Richtigkeit<BR>
    -- Schau mal in der Doku bei Execute Immediate nach<BR>
    end;<BR>
    <BR>
    Gruss<BR>
    Matthias<BR&gt

    Comment


    • #3
      Hallo Matthias,

      erst mal danke für Deine Antwort. War schon sehr informativ. Jedoch habe ich das mal ausprobiert und leider festgestellt, dass die Anweisung EXECUTE IMMEDIATE zwar bei einfachen Skripten zwar in den Prozeduren funktionieren, leider jedoch nicht in einem Cusor, den ich verwende.
      Hat jemand eine Ahnung, wie ich das hin bekomme, dass die Prozedur Valid wird, obwohl ich keinen Datenbanklink angelegt habe?

      Vielen Dank im voraus,

      Stepha

      Comment


      • #4
        Hallo Stephan,

        wenn du deine procedure nicht auf dynamisches SQL, also EXECUTE IMMEDIATE oder durch Nutzung von dbms_sql umstellen willst/kannst, dann gibt es keine Chance zu verhindern, das ORACLE die procedure auf INVALID setzt, wenn der DB-Link gelöscht wird. Dies ist aus meiner Sicht auch völlig OK!
        Was mir nicht ganz einleuchtet ist das dynamische Anlegen und Löschen des DB-Link durch ein Programm (mir fällt kein vernünftiger Grund dafür ein) und auf der anderen Seite der Verzicht auf die notwendige Dynamik. Vielleicht solltest du diesen Ansatz nochmal überdenken.

        Gruß Fal
        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

        Comment


        • #5
          Hallo Falk,

          da hast Du recht. Da Problem ist nur, dass die Entwickler der Datenbank, auf der ich zugreifen möchte, es ungerne sehen, wenn der Link immer offen bleibt......
          Ich werde einfach :-) mal diesen Ansatz klären und eventuell einen dauernden Link einrichten.
          Wie verhält sich das denn, wenn eine der Datenbanken neu gestartet werden. Sind dann die Links noch aktiv oder müssen die neu angelegt werden?

          Vielen Dank und Grüße,

          Stepha

          Comment


          • #6
            Hallo Stephan,

            die große Frage ist jetzt "Wie definierst du aktiv und offen?" Ich werds mal versuchen
            <b>Ist der Link offen?</b> Du kannst ja beim Anlegen des DB-Link die Connection-Methode mit dem "CONNECT TO" angeben. CONNECT TO CURRENT_USER bietet dabei die größte Sicherheit und Transparenz, aber auch den größeren Administrativen Aufwand (Auf beiden DB muß der User angelegt sein und mit entsprechenden Rechten versehen werden). CONNECT TO <i>user</i> IDENTIFIED BY <i>password</i> Ist die einfachere Variante, aber auch die mit den größten Risiken, da alle User der Lokalen DB, die den DB-Link nutzen dürfen (bei einem PUBLIC DATABASE LINK Alle) über genau die Rechte auf der Remote-DB verfügen, die der mit <i>user</i> IDENTIFIED BY <i>password</i> angegebenen User dort hat. Die Datenbankentwickler können also schon eine "sichere" Connection implementieren.
            <b>Ist der Link aktiv?</b> Nach dem Anlegen mit CREATE DATABASE LINK ist der Link für die lokale DB gültig, egal ob mit den angegebenen Werten eine Connection zur Remote DB hergestellt werden kann oder nicht! Dies wird erst zur Laufzeit, wenn der DB-Link benutzt wird validiert. Wird jetzt also die Remote DB heruntergefahren oder die TNS-Verbindung geht krachen oder ... oder ..., dann haben alle aktiven Sessions, die den DB-Link benutzen ein Problem und alle neuen Sessions können nicht über den DB-Link zugreifen. Der Link, als Objekt in der Lokalen DB bleibt aber gültig ("VALID") - und damit aktiv!?

            Gruß Fal
            Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

            Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

            Comment


            • #7
              Als Ergänzung: Mit einem <b>"PUBLIC DATABASE LINK CONNECT TO SYS IDENTIFIED BY change_on_install"</b> hätte ich als Datenbankentwickler auch ein Problem
              Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

              Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

              Comment


              • #8
                Hallo Falk,

                wir haben das so geregelt:
                Auf der RemoteDB wurde ein User eingerichtet, der nur eingeschränkte Rechte hat. Dann habe ich es doch geschafft, eine Prozedur zu schreiben, die auch wenn der LINK nicht vorhanden, zu kompilieren ist.
                Hier ein Beispiel:

                ##########################################
                CREATE OR REPLACE PROCEDURE Proc_Test2
                AS
                TYPE daten_template IS REF CURSOR;
                daten_cursor daten_template;
                daten_record1 VARCHAR2(200);
                daten_record2 VARCHAR2(200);
                sqlstring VARCHAR2(1000);

                BEGIN

                sqlstring := 'SELECT NAME, VORNAME FROM natperson@DBLINK;

                OPEN daten_CURSOR FOR sqlstring;

                LOOP

                FETCH daten_cursor INTO daten_record1, daten_record2;
                EXIT WHEN daten_cursor%NOTFOUND;

                INSERT INTO TEST
                VALUES(daten_record1, daten_record2);

                END LOOP;
                COMMIT;

                CLOSE daten_cursor;

                END Proc_Test2;
                /
                #############################################

                Danke noch mal für Deine Hilfe.

                Viele Grüße,
                Stepha

                Comment

                Working...
                X