![]() |
Datenbank: MYSQL • Version: 5.0 • Zugriff über: ZEOS
Datensatz von Datenbank zu Datenbank kopieren / updaten
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. |
Re: Datensatz von Datenbank zu Datenbank kopieren / updaten
Hi Stefan,
ich hab das ganze auch schon gebraucht. Setze allerdings MyDac ein...
Delphi-Quellcode:
Vielleicht hilft Dir der Codeausschnitt weiter...
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; Gruß Uwe |
Re: Datensatz von Datenbank zu Datenbank kopieren / updaten
Zitat:
|
Re: Datensatz von Datenbank zu Datenbank kopieren / updaten
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:
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. |
Re: Datensatz von Datenbank zu Datenbank kopieren / updaten
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:
Wichtig beim Kopieren ist, dass die Primärschlüsselfeld(er) nicht mitkopiert werden.
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; 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. |
Re: Datensatz von Datenbank zu Datenbank kopieren / updaten
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... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz