AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Datensatz von Datenbank zu Datenbank kopieren / updaten
Thema durchsuchen
Ansicht
Themen-Optionen

Datensatz von Datenbank zu Datenbank kopieren / updaten

Ein Thema von stekohl · begonnen am 12. Jun 2008 · letzter Beitrag vom 9. Jul 2008
Antwort Antwort
stekohl

Registriert seit: 12. Jun 2008
9 Beiträge
 
#1

Datensatz von Datenbank zu Datenbank kopieren / updaten

  Alt 12. Jun 2008, 09:46
Datenbank: MYSQL • Version: 5.0 • Zugriff über: ZEOS
Hallo Leute,

ich schildere mal was ich machen will.

Ich habe eine Serverdatenbank und eine lokale Datenbank.
Die Serverdatenbank liegt auf meiner Homepage als lokale Datenbank dient der mobile MYSQL Teil von XAAMPP.
So kann ich meine Anwendung einfach auf einen USB Stick halten.

So weit so gut, ich komme per Zeos auf beide Datenbanken. Da sich beide Datenbanken replizieren sollen und zwar in beide Richtungen habe ich mir ein relativ idiotensicheres Konzept per UUID's als prim. Key und für jede Tabelle ein UPDATEID Feld per UUID einfallen lassen. Den adm. Teil der Datenbank sollte jedoch nur serverseitig editiert werden können und per Repl. auf dem client nur aktualisiert werden.
Jetzt zu meinem Problem.
Wie kann ich per SQL (geht glaube ich garnicht) oder per Delphi (zeos) einen Datensatz von einem Server zum anderen Server übertragen? Kann ich per Select Datensätze in einen Zwischenpuffer laden und dann per insert into aus dem Puffer wieder in die "baugleiche" tabelle auf einem anderen Server schreiben.
Ich habe mir einen Wolf gesucht ob es einen "RECORDSET" oder so änlich gibt den ic kopieren kann. Meine Delphi-DB erfahrungen sind so aktuell wie meine verwendete Delphiversion. Da habe ich noch mit der BDE gearbeitet. Leider sind die Repl.-fähigkeiten von MYSQL sehr beschränkt, ich bin da von MSSQL und SYBASE doch ein wenig verwöhnt gewesen. BatchMov habe ich früher öfter verwendet, jedoch steht mir die BDE Komponente ja für Zeos nicht zur verfügung.

Ich dank schon mal für Eueren Hirnschmalz.
Gruß,
Stephan
  Mit Zitat antworten Zitat
alphaville

Registriert seit: 6. Dez 2006
Ort: Wurmlingen
3 Beiträge
 
Delphi 2006 Enterprise
 
#2

Re: Datensatz von Datenbank zu Datenbank kopieren / updaten

  Alt 1. Jul 2008, 15:29
Hi Stefan,

ich hab das ganze auch schon gebraucht. Setze allerdings MyDac ein...

Delphi-Quellcode:
procedure TfrmBetriebstaettenInstallation.cmdFillClick(Sender: TObject);
var
  I,J,K : Integer;
  arrTab: Array[1..100] of string;

begin
    arrTab[1] := 'sd_abteilung';
    arrTab[2] := 'sd_bild';
    arrTab[3] := 'sd_mitarbeiter';
    arrTab[4] := 'sd_werk';
    arrTab[5] := 'pd_abmahnung';
    arrTab[6] := 'sd_plz';
    arrTab[7] := 'sd_schulabschluss';

    cmdFill.Enabled := False;
    cmdSync.Enabled := False;

    for K := 1 to 7 do begin
      if (K=3) then continue;
      
      ShowSqlString('Übertrage Tabelle '+arrTab[K]+'...'); // Hinweis
      qrwZentrale.SQL.Clear; // SQL-Befehl leeren
      // =====================================================================
      // Werkspezifische Daten
      // =====================================================================
      if (K<6) then begin
        qrwZentrale.SQL.Add('SELECT '+arrTab[K]+'.*');
        qrwZentrale.SQL.Add('FROM `'+arrTab[K]+'`,`cfg_transfer`');
        qrwZentrale.SQL.Add('WHERE LAND_ID='''+tblMySql['LAND_ID']+'''');
        qrwZentrale.SQL.Add(' AND `'+arrTab[K]+'`.WERK_ID=cfg_transfer.WERK_ID');
        qrwZentrale.SQL.Add(' AND cfg_transfer.SERVER_ID='''+tblMySql['SERVER_ID']+''';');
      end else begin
        qrwZentrale.SQL.Add('SELECT * FROM `'+arrTab[K]+'` WHERE LAND_ID='''+tblMySql['LAND_ID']+''';');
      end;
      ShowSql(qrwZentrale.SQL); // SQL-Befehl anzeigen
      qrwZentrale.Open; // SQL-Befehl ausführen

      for I := 0 to qrwZentrale.RecordCount - 1 do begin
        qrwExtern.SQL.Clear; // SQL-Befehl leeren
        qrwExtern.SQL.Add('REPLACE INTO `'+arrTab[K]+'` VALUES (');
        for J := 0 to qrwZentrale.FieldCount - 1 do begin
          if (J <> qrwZentrale.FieldCount - 1) then begin
            if (qrwZentrale.Fields[J].Value=NULL) then begin
              qrwExtern.SQL.Add('NULL,');
            end else begin
              if (qrwZentrale.Fields[J].DataType=ftDate) then begin
                qrwExtern.SQL.Add(''''+Copy(qrwZentrale.Fields[J].Value,7,4)+'-'+Copy(qrwZentrale.Fields[J].Value,4,2)+'-'+Copy(qrwZentrale.Fields[J].Value,1,2) +''',');
              end else begin
                qrwExtern.SQL.Add(''''+qrwZentrale.Fields[J].AsString +''',');
              end;
            end;
          end else begin
            if (qrwZentrale.Fields[J].Value=NULL) then begin
              qrwExtern.SQL.Add('NULL');
            end else begin
              if (qrwZentrale.Fields[J].DataType=ftDate) then begin
                qrwExtern.SQL.Add(''''+Copy(qrwZentrale.Fields[J].Value,7,4)+'-'+Copy(qrwZentrale.Fields[J].Value,4,2)+'-'+Copy(qrwZentrale.Fields[J].Value,1,2) +'''');
              end else begin
                qrwExtern.SQL.Add(''''+qrwZentrale.Fields[J].AsString +'''');
              end;
            end;
          end;
        end;
        qrwExtern.SQL.Add(');');
        ShowSql(qrwExtern.SQL); // SQL-Befehl anzeigen
        qrwExtern.Execute;
        qrwZentrale.Next;
      end;
    end;
    Send_SuchTabellen; // Alle Suchtabellen frisch übertragen
    Send_Stammdaten;
    dbExtern.Disconnect; // Verbindung trennen
    ShowMessage('Ready...');
end;
Vielleicht hilft Dir der Codeausschnitt weiter...

Gruß Uwe
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.201 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: Datensatz von Datenbank zu Datenbank kopieren / updaten

  Alt 1. Jul 2008, 15:31
Zitat von stekohl:
Leider sind die Repl.-fähigkeiten von MYSQL sehr beschränkt, ich bin da von MSSQL und SYBASE doch ein wenig verwöhnt gewesen.
Was geht nicht. AFAIK haben meine Arbeitskollegen schon ein paar MySQL-DB's mit Replikation im Produktiveinsatz.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
stekohl

Registriert seit: 12. Jun 2008
9 Beiträge
 
#4

Re: Datensatz von Datenbank zu Datenbank kopieren / updaten

  Alt 8. Jul 2008, 18:45
Hallo bemühte Delphianer,

danke erst mal für die Antworten.

Der Quelltext ist arbeit und auch danke dafür, jedoch bekomme ich bei 102 Tabellen da eher einen Schreibkrampf. Für kleine Datenbanken überhaubt kein Problem. Für die Programmierung eine eigenen Replizierungsmethode oder - anwendung hatte ich mir halt gewünscht, den kompletten Datensatz zu übertragen.

Es soll so eine Art Expertensystem sein. Also ein Helpdeskprogramm, dass per MYSQL auf eine zentrale Datenbank zugreift und die Tabellen abgleicht und updatet. Dabei ist die Logik relativ einfach. Alle Clients dürfen nur ihre eigenen Beiträge ändern, neue Beträge verfassen und je nach Zugriffsrecht moderieren.
Alle Datensätze haben, ich nenne es mal so, personalisierte UID's als Primarykey und ein Änderungsfeld (Datum/Zeit). MYSQL erzeigt ja leider nicht für jeden Client einen eigenen UID Teil, sondern nur für jeden Server. Und die vorderen 8 Bytes können bei 100 Client relativ schnell mal doppelt vorkommen. So nutze ich jetzt die Delphi API UID Funktion und eben einen HASH aus Usernamen und Datum. So komme ich auf eine Schlüsselfeldbreite von 56 Byte. Da bei ca. 100 Clints schon gewisse Anforderungen an die Datenbank gestellt werden war ich von der Performance von MYSQL relativ angetan. Auch die relativ einfache Verfügbarkeit auf einen Internetserver ist ein Argument.

So soll nun die Replikation laufen. Als erstes werden User/Usergruppen/Rechte Tabellen vom Server zum Client übertragen. Diese werden nur in der Masterdatenbank geändert, also nur online. So werden Sicherheitrelevante Daten nur in eine Richtung repliziert.
Alle Anderen Tabellen: Termine/TODO/Prüfmittel und eben die Fehlertabellen werden in beide Richtungen repliziert.

Zitat von Bernhard Geyer:
Zitat von stekohl:
Leider sind die Repl.-fähigkeiten von MYSQL sehr beschränkt, ich bin da von MSSQL und SYBASE doch ein wenig verwöhnt gewesen.
Was geht nicht. AFAIK haben meine Arbeitskollegen schon ein paar MySQL-DB's mit Replikation im Produktiveinsatz.
Tja, bei Sybase gebe ich eben die Tabelle an die ich repl. will und welche Felder der Tabelle Schlüsselfelder sind. Den Rest mach Sybase relativ gut selber. Großer Nachteil. Server relativ Wartungsintensiv und es kann nicht das Angebot von Provider genutzt werden. Und eben nicht für lau. Auch das die Installation von Sybase auf dem Rechner nicht ganz ohne ist.

I have a dream. Das ich eine lokale Datenbank aller XAAMP auf die Laptops packe, weil da ja nix am System prinzipiell geändert wird.

Nun aber die alles entscheidenen Frage. Wie kann ich diese Replizierungfunktion so rationalisieren, dass ich eben nicht für jedes Feld einer Tabelle per "Select" und "insert into" arbeiten muß. Ich würde halt gerne die Datensätze per Filter auswählen, was ja kein Problem ist, und eben dann den kompletten Datensatz hin und her schauffeln.

Ich weiß natürlich, dass jeder Datenbanklprofi beim kompletten kopieren von Datensätzen Ausschlag und Stickhusten bekommt, jedoch selektiere ich ja sauber vorher die benötigten Datensätze.
Die MYSQL eigenene Replikationfunktionen per Transaktionlog schliesse ich Aufgrund der viele Clients erst mal als unpraktikabel aus. Ich würde halt nur ungern aus per MYSQL Verbindung auf dem Server rumpfuschen.

So ich hoffe Ihr könnt meinen geistigen Ergüssen folgen. Die Formulierungen und Gedankensprünge gehen stark in Richtung Pete Klocke.

Danke für Eure Antworten.
Gruß,
Stephan
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

Re: Datensatz von Datenbank zu Datenbank kopieren / updaten

  Alt 8. Jul 2008, 19:07
Angenommen du hast zwei baugleiche Tabellen in versch. Datenbanken (mit Primärschlüssel!!!).
Ohne Primärschlüssel ist ein Abgleich nicht möglich!

Du öffnest beide Tabellen mit SELECT * FROM Tabelle ORDER BY Pkfelder.
Du durchläufst beide Tabellen und vergleichst jeweils den Primärschlüssel.
Sind beide Schlüssel gleich, musst du herausfinden, ob du A->B oder B->A aktualisieren willst.
Vielleicht willst du immer nur A->B, das ist einfacher.
Delphi-Quellcode:
procedure CopyDataSetRecord(Src,Dst: TDataSet; TagMask:Integer=0);
var
   i: Integer;
   fSrc,fDst: TField;
begin
   for i := 0 to Src.FieldCount-1 do
   begin
      fSrc := Src.Fields[i];
      fDst := Dst.FindField(fSrc.FieldName);

      if Assigned(fDst) and ((fSrc.Tag and TagMask)=0) then
      begin
         fDst.Value := fSrc.Value;
      end;
   end;
end;
Wichtig beim Kopieren ist, dass die Primärschlüsselfeld(er) nicht mitkopiert werden.
Das lässt sich durch geschicktes Einsetzen der TagMask erreichen.

Sind die Primärschlüssel unterschiedlich, musst du schauen, ob in der Tabelle von DB-A ein Datensatz vorhanden ist, der in DB-B fehlt (oder umgekehrt).
Jenachdem wird ein Delete oder Insert fällig und wieder dient obige Prozedure zum Kopieren der Daten.
Dann solange weitermachen, bis bei beiden Datensets Eof=True ist.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von RavenIV
RavenIV

Registriert seit: 12. Jan 2005
Ort: Waldshut-Tiengen
2.875 Beiträge
 
Delphi 2007 Enterprise
 
#6

Re: Datensatz von Datenbank zu Datenbank kopieren / updaten

  Alt 9. Jul 2008, 12:29
Ich hab mich auch schon intensiv mit MySQL auseinander gesetzt.
Und dabei herausgefunden, dass es sehr wohl Replikationstools gibt.
Manche sind von MySQL, es gibt aber auch Tools von Drittanbietern.

Einfach mal ein Bisschen im www umschauen...
Klaus E.
Linux - das längste Text-Adventure aller Zeiten...
Wer nie Linux mit dem vi konfiguriert hat, der hat am Leben vorbei geklickt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz