Announcement

Collapse
No announcement yet.

Connect zweier Datenbanken

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

  • Connect zweier Datenbanken

    Hey,
    gibt es eine Möglicjkeit in einem SQL-Script zwei Datenbanken gleichzeitig zu connecten? Ich möchte Daten aus einer DB in eine andere DB gleichem Formats pumpen, da die Struktur der ersten defekt ist. Ich habe hierzu kein Example gefunden.

    mfg T.Schumann

  • #2
    Hallo Torsten,<br><br>
    nicht unmittelbar in einem SQL-Skript, aber ich würde mir die verfügbaren Drittherstellertools mal ansehen. z.B. Interbase DataPump v3.2 genießt einen ganz guten Ruf. http://www.clevercomponents.com<br><br>
    Gruss,<br>
    Thomas Steinmaurer<br>
    IB LogManager 2.0 - The Logging/Auditing Tool for InterBase and Firebird<br>
    http://www.iblogmanager.com<br&gt
    Thomas Steinmaurer

    Firebird Foundation Committee Member
    Upscene Productions - Database Tools for Developers
    Mein Blog

    Comment


    • #3
      Hey Thomas,
      ich habe folgendes Problem: Ich muß Bilder(JPG) aus einer DB in eine andere Pumpen. Ich habe auch ein Datapump geschrieben. Die QuellDB ist 14GB groß. Beim Kopieren der Bilder tritt nach ca. 1Std. folgende Fehlermeldung auf "Kein freier Arbeitsspeicher mehr" und der Server steht. Beim zweiten Versuch kopiere ich die Bilder erst auf Platte und lese sie von dort wieder ein. Trotzdem kommt der Fehler.
      Meine letzte Idee war es direkt von DB zu Db zu versuchen.
      Wir benutzen die IBO'S und laden die in eine IBOQuery. Ich meine zu wissen, daß der Fehler durch die internen Blobstreams kommt.
      Dies ist mein Problem und ich brauche eine Lösung dafür.

      mfg
      T.Schuman

      Comment


      • #4
        Hallo Torsten,<br><br>
        erzähl etwas wie Du das Datapump implementiert hast. Wie machst Du das? Wie sieht Dein Transaktionshandling aus? Welchen IsolationLevel verwendest Du? Wann wird ein Commit ausgeführt? IBO hat auch eine eigene Datapump Komponente. Hast Du die schon mal versucht?<br><br>
        Gruss,<br>
        Thoma
        Thomas Steinmaurer

        Firebird Foundation Committee Member
        Upscene Productions - Database Tools for Developers
        Mein Blog

        Comment


        • #5
          Hey Thomas,
          ich lese die Bilderdaten über
          qryQuelle->FieldByName("BILD")->SaveToFile( asPfad + "\\BILD.jpg");
          und schtreibe sie über
          qryTarget->FieldByName("BILD")->LoadFromFile( asPfad + "\\BILD.jpg");
          wieder ein. Die Targetquery wird natürlich nach jedem Record committed. Die Quellquery wenn ich sie nicht mehr brauche.

          Beispiel:
          while(!qryQuelle->Eof )
          {
          /*
          strBild->Clear();
          strO_Bild->Clear();
          strB_Bild->Clear();
          strThumb->Clear();
          strVector->Clear();

          strBild->LoadFromStream((TMemoryStream*)qryQuelle->CreateBlobStream(qryQuelle->FieldByName("BILD"), bmRead));
          strO_Bild->LoadFromStream((TMemoryStream*)qryQuelle->CreateBlobStream(qryQuelle->FieldByName("O_BILD"), bmRead));
          strB_Bild->LoadFromStream((TMemoryStream*)qryQuelle->CreateBlobStream(qryQuelle->FieldByName("B_BILD"), bmRead));
          strThumb->LoadFromStream((TMemoryStream*)qryQuelle->CreateBlobStream(qryQuelle->FieldByName("THUMBNAIL"), bmRead));
          strVector->LoadFromStream((TMemoryStream*)qryQuelle->CreateBlobStream(qryQuelle->FieldByName("VECTOR_DATEN"), bmRead));
          */

          if(FileExists(asPfad + "\\BILD.jpg)")) DeleteFile(asPfad + "\\BILD.jpg)");
          if(FileExists(asPfad + "\\O_BILD.jpg)")) DeleteFile(asPfad + "\\O_BILD.jpg)");
          if(FileExists(asPfad + "\\B_BILD.jpg)")) DeleteFile(asPfad + "\\B_BILD.jpg)");
          if(FileExists(asPfad + "\\THUMBNAIL.jpg)")) DeleteFile(asPfad + "\\THUMBNAIL.jpg)");
          if(FileExists(asPfad + "\\VECTOR_DATEN.dat)")) DeleteFile(asPfad + "\\VECTOR_DATEN.dat)");

          qryQuelle->FieldByName("BILD")->SaveToFile( asPfad + "\\BILD.jpg");
          qryQuelle->FieldByName("O_BILD")->SaveToFile(asPfad + "\\O_BILD.jpg");
          qryQuelle->FieldByName("B_BILD")->SaveToFile(asPfad + "\\B_BILD.jpg");
          qryQuelle->FieldByName("THUMBNAIL")->SaveToFile(asPfad + "\\THUMBNAIL.jpg");
          qryQuelle->FieldByName("VECTOR_DATEN")->SaveToFile(asPfad + "\\VECTOR_DATEN.dat");

          qryTarget->SQL->Clear();
          asTarget = "Insert into T_Bilder ";
          asTarget += "(";
          asTarget += "ID,"; //1
          asTarget += "VG_ID,"; //2
          asTarget += "BEARBEITET,"; //3
          asTarget += "KENNZEICHEN,"; //4
          asTarget += "BESCHREIBUNG,"; //5
          asTarget += "ZUORDNUNG,"; //6
          asTarget += "BILD,"; //7
          asTarget += "O_BILD,"; //8
          asTarget += "THUMBNAIL,"; //9
          asTarget += "BREITE,"; //10
          asTarget += "HOEHE,"; //11
          asTarget += "ANWENDER,"; //12
          asTarget += "COMPUTERNAME,"; //13
          asTarget += "VECTOR_DATEN,"; //14
          asTarget += "B_BILD,"; //15
          asTarget += "NURORG,"; //16
          asTarget += "GANR,"; //17
          asTarget += "SACHVERST,"; //18
          asTarget += "ERSTELLT_AM,"; //19
          asTarget += "ARCHIV,"; //20
          asTarget += "GEDREHT )"; //21
          asTarget += "Values(";
          asTarget += "0 ,"; //1
          asTarget += qryQuelle->FieldByName("VG_ID")->AsString + ","; //2
          //asTarget += "'" + qryQuelle->FieldByName("BEARBEITET")->AsString+ "',"; //3
          if(qryQuelle->FieldByName("BEARBEITET")->AsString == "1")
          asTarget += "1,";
          else
          asTarget += "0,";

          asTarget += "'" + qryQuelle->FieldByName("KENNZEICHEN")->AsString+ "',"; //4
          asTarget += "'" + qryQuelle->FieldByName("BESCHREIBUNG")->AsString+ "',"; //5
          asTarget += "'" + qryQuelle->FieldByName("ZUORDNUNG")->AsString+ "',"; //6
          asTarget += ":BILD,"; //7
          asTarget += ":O_Bild,"; //8
          asTarget += ":THUMBNAIL,"; //9
          asTarget += qryQuelle->FieldByName("BREITE")->AsString + ","; //10
          asTarget += qryQuelle->FieldByName("HOEHE")->AsString + ","; //11
          asTarget += "'" + qryQuelle->FieldByName("ANWENDER")->AsS

          Comment


          • #6
            Hallo Torsten,<br><br>
            sorry, aber jetzt bin ich etwas von unformatierten Sourcecode erschlagen ;-). D.h. Du machst das derzeit in etwa so. qryQuelly in einer Schleife durchlaufen, Bild im Dateisystem abspeichern, Bild in qryTarget reinholen und mit zusätzlichen Textinformationen abspeichern, die Bilder löschen und weiter gehts mit dem nächsten Datensatz. Ist das richtig?<br><br>
            Ich hoffe ich verrenn mich nicht im Source, aber folgende Dinge fallen mir auf:<br><br>
            - Die Verwendung von Streams wurde auskommentiert, oder?<br>
            - Da sich das INSERT INTO nur durch die eingefügten Werte ändert, würde ich ein parametrisiertes INSERT vorschlagen, das einmal Prepared wird und dann immer nur mit den Werten gefüllt wird. So läuft jedes Mal das Insert-Statement durch den Optimizer, obwohl einmal reichen würde<br>
            - Nochmals, welchen Transaction Isolation Level verwendest Du?<br>
            - Ein Commit nach jedem eingefügten Datensatz ist reine Verschwendung. Besser wär ein Commit (hard commit, kein CommitRetaining) nach so 5000 bis 10000 Datensätzen zu machen. Wieviele Datensätze werden denn in der Regel transferiert?<br>
            - Spricht etwas dagegen die nativen IBO Komponenten einzusetzen, vor allem TIB_DSQL ist sehr schnell beim Ausführen von reinen DML-Statements, da es sich hierbei um keine gepufferten Datenmengen handelt (z.B. zum Vorwärts bzw. Rückwarts scrollen)<br>
            - Muss wirklich nur ein Datensatz von einer Datenbank in eine andere Datenbank transferiert werden, dann kann man auch unter Verwendung des Two-Phase Commit Protokolls mit 2 TIB_Connection, 1 TIB_Transaction, 2 TIB_Cursor und 1 TIB_Datapump Komponente eine sehr ordentlich Datapump-Lösung realisieren.<br><br>
            Gruss,<br>
            Thoma
            Thomas Steinmaurer

            Firebird Foundation Committee Member
            Upscene Productions - Database Tools for Developers
            Mein Blog

            Comment


            • #7
              Hey Thomas,
              DU hast es richtig erkannt, die Bilder werden per Platte übergeben. Die Streams habe ich auskommentiert, da ich dachte, daß diese der Speicherfresser sind. Vorher habe ich alles per Stream übergeben.

              Die Parametrisierung sehe ich ein.
              Der Isolationslevel ist tiCommitted.

              Den Commit kann ich auch nach ca. 5000 DS machen.

              Die Anzahl der DS bewegt sich zwischen 10.000 und 25.000.

              Ich würde sehr gern nur mit den IBO-Komponenten arbeiten, aber wir hatten noch keine Zeit uns mit diesen auseinander zu setzen, außerdem ist die Hilfe zu den Koimponenten sehr spatanisch. Ich habe gestern erst bemerkt, daß ein DataPump direkt von IBO_Database und IB_Connection gemacht werden können. Aber ich habe nicht herausgefunden wie ich dies zu Laufzeit hinkriege. In der Entwicklung geht alles bestens.

              mfg

              T.Schuman

              Comment


              • #8
                Hallo Torsten,<br><br>
                wenn Deine Probleme nicht beseitigt sein sollten, und Du Unterstützung bei der Realisierung eines DataPump auf Basis der nativen IBO-Zugriffskomponenten brauchst, dann kannst Du mich auch privat kontaktieren ([email protected]).<br><br>
                Gruss,<br>
                Thoma
                Thomas Steinmaurer

                Firebird Foundation Committee Member
                Upscene Productions - Database Tools for Developers
                Mein Blog

                Comment


                • #9
                  Danke Thomas

                  mfg Torste

                  Comment

                  Working...
                  X