Announcement

Collapse
No announcement yet.

JOIN mehrerer Tabellen auf anderen Datenbankservern?

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

  • JOIN mehrerer Tabellen auf anderen Datenbankservern?

    Hallo Forum!

    Ich würde gerne die Daten einer Fremdtabelle, die auf einem anderen Server liegen, mit JOIN verbinden und frage mich, ob sowas überhaupt geht oder wie ich das sonst am geschicktesten machen könnte. Folgendes Szenario (nur ein Beispiel fürs Prinzip):

    Datenbank 1 (Oracle DB auf Server 1):

    $connect1 = odbc_connect("db1", "user1", "password1");

    $querystring1 = <<<EOT
    SELECT * FROM DBO."Kunden"
    INNER JOIN DBO."Tickets"
    ON DBO."Kunden"."Kundennummer" = DBO."Tickets"."Kundennummer"
    WHERE DBO."Kunden"."Kundennummer" > '10000';
    EOT;

    $result1 = odbc_exec($connect1, $querystring1);
    ...

    Datenbank 2 (MS-Access MDB auf Server 2):

    $connect2 = odbc_connect("db2", "user2", "password2");

    $querystring2 = <<<EOT
    SELECT * FROM "GeschenkKunden";
    EOT;

    $result2 = odbc_exec($connect2, $querystring2);
    ...

    Aktuell kann ich mir beide Resultate getrennt voneinander ausgeben lassen.

    Nun würde ich gerne die Tabelle von Datenbank 2 in das SELECT von Datenbank 1 JOINen. Gemeinsamer Schlüssel der beiden Tabllen ist "Kundennummer".
    Geht sowas überhaupt? Weil wenn ich einfach die DB2 in das JOIN von DB1 einfüge, dann schlägt ja logischerweise die Query fehl, da der odbc_exec sich nur auf DB1 bezieht. D.h. irgendwie/irgendwo müsste zuerst eine getrennte odbc_exec für DB2 ausgeführt werden, damit die richtige Datenbank die Infos liefert.
    Müsste ich das vielleicht mit einem Subselect o.ä. machen? Also dass das Resultat der DB2 Abfrage in der DB1 Abfrage berücksichtigt wird.


    Danke schön,
    Peter

  • #2
    Hallo,

    dafür musst du auf einem der Server einen sg. DB LINK anlegen.

    Gruß Falk
    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


    • #3
      Das geht aber out-of-the-box aber nur, wenn es sich um 2 Oracle Datenbanken handelt.
      Ansonsten muss man vorher noch mit Gateways herumdoktern und das ist ohne DBA der sich damit auskennt nicht mal so einfach eingerichtet.

      Dim
      Zitat Tom Kyte:
      I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

      Comment


      • #4
        Hm schade, dass das nur mit zwei Oracle-DBs geht, weil das mit dem Link eine super Lösung gewesen wäre. Ich kann an dem Server leider nichts verändern (lassen) wegen Gateways.

        Ich habe mir noch was anderes überlegt. Ist zwar nicht besonders elegant, aber vielleicht trotzdem eine handhabbare Methode. Man kann doch tempöräre Tabellen in Oracle anlegen. Wäre es denn möglich, die Daten aus der DB2 Abfrage (Access MDB) in eine temporäre Tabelle des DB1 (Oracle) zu übertragen und diese temporäre Tabelle anschließend mit INNER JOIN in die DB1 Abfrage dazuzufügen? Es sind nur relativ wenige Datensätze in DB2 (ca. 50 Zeilen und 5 Spalten). Was meint ihr dazu - wäre das eine Möglichkeit?

        Wie müsste so ein Ausdruck aussehen? Wenn ich die Tabelle anlege, dann kommt ein Fehler, wenn diese schon existiert. Mache ich ein DROP, dann kommt ein Fehler, wenn diese nicht existiert. Das müsste ich irgendwie abfangen - nur wie? Folgendes funktioniert leider nicht:

        /* Tabelle löschen, falls sie nicht existiert */
        drop table TMP_ARTIKEL
        where exists (
        SELECT table_name FROM all_tables
        WHERE table_name = 'TMP_ARTIKEL');

        /* Neue Tabelle anlegen */
        create global temporary table tmp_artikel (
        artikel_nr number(5),
        umsatz number(10,2))
        on commit delete rows;

        Wie kann ich die Daten dann einfügen? Ich habe mal testweise die Daten von DB2 in ein Array gespeichert. Sollte ich dann mit einer Schleife arbeiten und alle "Zeilen" des Arrays nacheinander mit INSERT in die TMP_ARTIKEL einfügen oder geht das auch in einem Gesamtblock (das komplette Array auf einmal)?

        Viele Grüße,
        Peter

        Comment


        • #5
          Hi,

          die GTT musst Du nicht löschen, sondern kannst einfach stehen lassen, des weiteren gibt es in Oracle kein DROP WHERE EXISTS.

          Die 50 Sätze kannst natürlich per generiertem INSERT einfügen.
          In Java kann man dies mittles addBatch und einem PreparedStatement recht einfach machen, in Access kenn ich mich zu wenig aus.
          Im schlimmsten Fall musst Du eben 50mal ein Insert abschicken - das wird die DB verkraften.

          Dim
          Zitat Tom Kyte:
          I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

          Comment


          • #6
            * Tabelle löschen, falls sie nicht existiert */
            drop table TMP_ARTIKEL
            where exists (
            SELECT table_name FROM all_tables
            WHERE table_name = 'TMP_ARTIKEL');
            also...
            als erstes ist ein DROP... ein DDL-Statement.
            dies kannst du nicht mit einem Select verbinden.

            /* Neue Tabelle anlegen */
            create global temporary table tmp_artikel (
            artikel_nr number(5),
            umsatz number(10,2))
            on commit delete rows;
            als zweites stellt sich mir die frage warum du eine TEMPORARY TABLE überhaupt wieder droppen willst. sie ist nach beendigung deiner session oder einem commit oder rollback eh leer.

            nächste frage ist, mit welcher programmiersprache du ran gehst.

            hier im oracle-forum gehe ich mal von PL/SQL aus...oder?

            greetz

            jogi

            Comment


            • #7
              Originally posted by RichterPeter View Post

              /* Tabelle löschen, falls sie nicht existiert */
              drop table TMP_ARTIKEL
              where exists (
              SELECT table_name FROM all_tables
              WHERE table_name = 'TMP_ARTIKEL');


              Peter
              set heading off
              set feedback off
              spool drop_user_tables.sql
              SELECT 'DROP TABLE "'|| table_name ||'";' FROM user_tables WHERE table_name like '%Teil des Tabellennamens%';
              spool off
              @drop_user_tables.sql

              Gruß

              Martin

              Comment


              • #8
                Hi,

                danke für die Antworten! Das mit dem DROP wollte ich nur machen, weil beim Anlegen der Datenbank sonst ein Fehler gekommen wäre.
                Als Programmiersprache verwende ich PHP (bitte nicht lachen, das ist eine Vorgabe).

                Wenn ich das richtig verstanden habe, dann könnte ich mir den Schritt sowieso sparen, da die Tabelle dauerhaft (nur eben ohne Inhalt) auf dem Server verbleibt oder? D.h. ich würde einmalig die Tabelle anlegen und dann zukünftig nur mit INSERT die Tabelle befüllen und per SELECT später auslesen. Die Daten in dieser DB2-Tabelle sind sehr statisch d.h. da ändert sich nur alle paar Wochen was daran. Dann würde ich am Anfang einmal die Dateien einlesen und dann während der Session weiter verwenden ohne erneut einzulesen.

                Ähm - ich hatte obigen Beitrag heute Mittag geschrieben aber keine Zeit mehr gehabt, ihn abzuschicken. Ich habe das mal so wie oben beschrieben gemacht und die Daten aus einem PHP-Array aus "Spalten" und "Zeilen" an das INSERT verfüttert.
                Das klappt absolut phantastisch! Ohne spürbaren Zeitverlust und das INNER JOIN funktioniert ebenfalls genau so wie ich das wollte. :-)

                Jetzt hänge ich nur noch an einem winzigen Problemchen. Und zwar hatte ich anfangs ständig einen "ORA-00918: Spalte nicht eindeutig definiert" Fehler bekommen, obwohl scheinbar alles OK definiert war.
                Ich habe nur durch viel Herumprobieren heraus gefunden, dass wohl ein Sonderzeichen in den Daten (!) das Problem verursacht. Und zwar ist das Zeichen ƒ (http://de.wikipedia.org/wiki/%C6%91).

                Wenn ich abschließend ein
                DBO."Kunden"."Waehrung" <> 'ƒ'
                einfüge, dann funktioniert die Abfrage ohne Fehlermeldung. Prinzipiell könnte ich damit leben (auf die seltsamen Quelldaten habe ich keinen Einfluss), nur wundert es mich, dass die Quelldaten dann so eine Fehlermeldung verursachen. Könnt ihr euch vorstellen, warum das so ist? Das passiert auch nur, wenn ein JOIN beteiligt ist. Wenn ich nur eine SELECT * FROM DBO."Kunden"; mache, dann klappt die Query ohne Fehler und ich sehe im Ergebnis dieses Sonderzeichen ƒ.

                Viele Grüße,
                Peter

                Comment

                Working...
                X