Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Zwei SQL-Datenbanken abgleichen, WIE? (https://www.delphipraxis.net/30067-zwei-sql-datenbanken-abgleichen-wie.html)

DiscMix 19. Sep 2004 13:42


Zwei SQL-Datenbanken abgleichen, WIE?
 
Hallo,

ich habe eine Verständnisfrage:

Ich habe einen SQLServer. Auf diesem Server liegen zwei Datenbanken. Datenbank 1 (Name: Cobra) hat eine Tabelle Adressen, Datenbank zwei (Name: Winline) hat eine Tabelle Kunden. Beide Tabellen haben eine Schnittmenge von Feldern die ich abgleichen möchte.

Beispiel:

Schaue dir alle Datensätze in der Tabelle Adressen in der Datenbank Cobra an, die in den letzten 10 Minuten geändert wurden (Zeitstempel). Als Ergebnis habe ich eine Liste von Datensätzen, diese müssen nun in die Tabelle Kunden in den entsprechenden Datensatz (wenn vorhanden) oder neu angelegt werden.

Ich arbeite mit ADO.

Brauche ich zwei ADOConnection ? Wie kann ich die Tabellen bei zwei unterschiedlichen SQL-Datenbanken abgleichen, bzw. drauf zugreifen.

Ich brauche irgendwie einen Denkanstoss.

Danke

aschne1 19. Sep 2004 22:21

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Hi

Geht das nicht mit der SQL-Anweisung UNION ?

Ausserdem denke ich beim Ausdruck Schnittmenge an Redunanzen. Musst Du die Daten ableichen oder lässt sich das auch mit einer Verknüpfung lösen?

Für zwei Datenbanken brauchst Du auch zwei ADOConnections.

Gruss

Armin

Robert_G 19. Sep 2004 23:42

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Zitat:

Zitat von aschne1
Geht das nicht mit der SQL-Anweisung UNION ?

Eher MINUS ;) (bzw. UNION um die zu löschenden DS hinten "ranzuklatschen" )

Da die Infos etwas spärlich sind, nehme ich für mein Beispiel an, dass die Spalten A & B eindeutig sein müssen (zum Bleistift Vorname & Nachname), möglicherweise reicht dir auch eine Art Kundennummer. :gruebel:

SQL-Code:
SELECT Decode(k.A
             ,NULL    
             ,1            /* kein Wert in Kunden -> INSERT */
             ,2) DmlType  /* andernfalls        -> UPDATE */
      ,Decode(k.A         /* Der PK wird nur für's UPDATE gebraucht ;) */ 
             ,NULL
             ,-1
             ,k.PK) PK
      ,sQ.A
      ,sQ.B
      ,sQ.C
FROM (SELECT A, B, C
       FROM  WinLine
       MINUS
       SELECT A, B, C     /* alle Datensätze aus WinLine, */
       FROM  Kunden)  sQ /* die so nicht in Kunden enthalten sind */
       LEFT JOIN Kunden k
       ON k.A = sQ.A and  /* deshalb Eindeutigkeit von A & B ;) */
          k.B = sQ.B
UNION ALL
SELECT 3 DmlType          /* alle Datensätze aus Kunden, */
      ,k.PK               /* die in WinLine nicht mehr da sind */ 
      ,k.A                /* -> löschen */
      ,k.B
      ,k.C
FROM  Kunden k          
WHERE not EXISTS (SELECT IrgendWas
                   FROM  WinLine
                   WHERE k.A = sQ.A and
                          k.B = sQ.B)
Beispiel:
  • Kunden
    Code:
    PK A  B  C
    1   AA BB 1
    3   BB CC 3
    WinLine
    Code:
    PK A  B  C
    4   DD EE 5
    6   BB CC 2
    Sollte ergeben:
    Code:
    DmlType PK A  B  C
    1        -1  DD EE 5   -> INSSERT
    2        3   BB CC 3   -> UPDATE  
    3        1   AA BB 1   -> DELETE

Zitat:

Zitat von aschne1
Ausserdem denke ich beim Ausdruck Schnittmenge an Redunanzen. Musst Du die Daten ableichen oder lässt sich das auch mit einer Verknüpfung lösen?

Deshalb MINUS ;)
Zitat:

Zitat von aschne1
Für zwei Datenbanken brauchst Du auch zwei ADOConnections.

Das hätte eine ziemlich krasse Anzahl von Roundtrips zur Folge.
Da ich absolut null (naja vielleicht 0,01 :mrgreen: ) Ahnung vom SQL Svr habe muss ich jetzt mal fragen: Kann der SQL Svr DB-Links?
  • Wenn ja:
    Melde dich in der DB an, für die du einen DBLink zur anderen gelegt hast. (eine Connection)
    Ergänze die nötige Syntax in der Abfrage
    In Ora sieht sowas so aus (DB von X hat einen DBLink Lnk auf die DB von Y):
    SQL-Code:
    SELECT A, B, C
    FROM  X
    MINUS
    SELECT A, B, C
    FROM  Y@Lnk
    Vielleicht ist es im SQL Svr nicht so sehr verschieden (wobei das @ bei euch IMHO nur für Parameter verwendet wird)
  • Wenn NICHT:
    Lege beides in EINE DB! (auch eine Connection)
    Die Trennung, auf 2 DBs, macht IMHO nur dann Sinn, wenn du innerhalb des Servers von einer DB auf die andere kommst.

Wirklich Licht ins Dunkel wird wohl nur ein Profi für den SQL Svr sein. (Um die Zeit dürfte sich Leusel durch die DP schleichen. :zwinker: )

p.s.: Hui, war vielleicht etwas zuviel des Guten.... :gruebel:

DiscMix 20. Sep 2004 08:34

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Erstmal vielen Dank für die ausführlichen Infos.

Ich möchte mein Problem (Herausforderung) genauer beschreiben:
Es gibt zwei Programme:
Cobra (Adress Plus), eine Adresssammlung + CRM.
Winline, eine Warenwirtschaft.

Beide arbeiten mit den SQL-Server, beide sind unabhängig, daher hat jeder seine eigene SQL-DB.
Cobra bsp. Cobra01. In der Datenbank Cobra01 gibt es die Tabelle Addresses. In dieser Tabelle
werden die Adressstammdaten gepflegt. So weit so gut.

Die Winline hat auch eine eigene DB bsp. Winline01. In dieser DB gibt es eine Tabelle Debitoren o.
Kunden. Hier werden die Stammdaten der Kunden gepflegt.

Nun möchte ich eine (einseitige) Schnittstelle realisieren, die anhand von Filterkriterien die Tabelle
Addresses der Cobra filtert, und diese Filtermenge für einen Abgleich mit der Tabelle Kunden in der
Winline nutzt. Praktisch arbeitet man in der Adressdatenbank, irgendwann deklariert man eine Adresse
als Kunden, dann muss diese an die Winline übergeben werden. Wobei unterschieden werden muss, ob der
Datensatz in der Winline schon vorhanden ist, oder neu angelegt werden muss.

Die SQL-Statements sind keine Probleme.
Nur irgendwie fehlt mir die Info wie ich von der einen DB in die andere Daten schaufelt kann...?!?!

Gruss
Marco

mikhal 20. Sep 2004 09:21

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Um welchen SQL Server handelt es sich?

Wenn MS SQL Server kannst du Tabellen nach folgendem Schema ansprechen: <Datenbankname>.<DatenbankOwner>.<Tabellenname>.

Beispiel: Datenbankname=Test, DatenbankOwner=Standard, Tabelle=Adresse => Test.dbo.Adresse

Grüße
Mikhal

baff 20. Sep 2004 10:10

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Hi,

schau mal ob dir das weiter hilft. Gibt sicher noch weitaus elegantere Methoden,
habe aber grad wenig zeit.

need: 2 adoconnection, 2 adodateset (zum ansehen 2 datasources und 2 grids), 1 adocommand

bei adodateset1 kannste deine abfrage nach Änderungen(Zeitstempel) machen

brauchst natürlich eine Eindeutigkeit(Kunden-NR oder so) - hier mal "Name"
sonst wird mehr geupdated als erforderlich.

Insert hab ich jetzt mal weggelassen, das kannste ggf. selber einbauen.


-------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var i,b:integer;
begin
ADODataSet1.FindFirst;
for i:=0 to ADODataSet1.RecordCount-1
do begin
ADODataSet2.FindFirst;
for b:=0 to ADODataSet2.RecordCount-1
do begin
if ADODataSet2.fieldvalues['NAME']=ADODataSet1.fieldvalues['NAME']
then
begin
ADOCommand1.CommandText:='update testvar_tbl set ort='+ quotedstr(ADODataSet1.fieldvalues['ORT']) +' where name='+ quotedstr(ADODataSet1.fieldvalues['NAME']);
ADOCommand1.Execute;
end;
if b<ADODataSet2.RecordCount-1 then
ADODataSet2.FindNext;
end;
if i<ADODataSet1.RecordCount-1 then
ADODataSet1.FindNext;
end;
end;


-----------------------------------------------------------------------------------

Am Besten du gibst mal noch an wie all die Spalten in den Tabellen heißen,
dann kann ma da was Konkretes posten.

gruss
marcel

DiscMix 20. Sep 2004 10:38

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Vielen Dank,

ich versuche es heute abend mal....

gruss
marco

Robert_G 20. Sep 2004 10:59

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Wäre es nicht so möglich?
  • Anmeldung an WinLine
  • Link zur KundenDB (KundenDB.Kunden)
  • Ein view auf die zu ändernden Daten:
    SQL-Code:
    CREATE OR REPLACE VIEW Clients2Synchronize AS
    SELECT Decode(k.A
                 ,NULL
                 ,1                     /* kein Wert in Kunden -> INSERT */
                 ,2) DmlType           /* andernfalls        -> UPDATE */
          ,Decode(k.A                  /* Der PK wird nur für's UPDATE gebraucht ;) */
                 ,NULL
                 ,-1
                 ,k.PK) PK
          ,sQ.A
          ,sQ.B
          ,sQ.C
    FROM (SELECT A, B, C
           FROM  WinLine
           MINUS
           SELECT A, B, C              /* alle Datensätze aus WinLine, */
           FROM  KundenDB.Kunden)  sQ /* die so nicht in Kunden enthalten sind */
           LEFT JOIN KundenDB.Kunden k
           ON k.A = sQ.A and           /* deshalb Eindeutigkeit von A & B ;) */
              k.B = sQ.B
    UNION ALL
    SELECT 3 DmlType                   /* alle Datensätze aus Kunden, */
          ,k.PK                        /* die in WinLine nicht mehr da sind */
          ,k.A                         /* -> löschen */
          ,k.B
          ,k.C
    FROM  KundenDB.Kunden k
    WHERE not EXISTS (SELECT IrgendWas
                       FROM  WinLine
                       WHERE k.A = sQ.A and
                              k.B = sQ.B)
  • INSERT:
    SQL-Code:
    INSERT INTO WinLine
       (A, B, C)
       SELECT A, B, C
       FROM  Clients2Synchronize sQ
       WHERE sQ.DmlType = 1
  • UPDATE:
    SQL-Code:
    UPDATE WinLine w
    SET   (w.A, w.B, w.B) = (SELECT A, B, C
                              FROM  Clients2Synchronize sQ
                              WHERE sQ.DmlType = 2 And sQ.PK = w.PK)
  • DELETE (wahrscheinlich unnötig):
    SQL-Code:
    DELETE FROM WinLine w
    WHERE w.PK in (SELECT PK
                    FROM  Clients2Synchronize sQ
                    WHERE sQ.DmlType = 3)

Von Lösungen á la Daten in eine Delphi App holen, irgendwas damit machen und dann wieder zurückschieben halte überhaupt nichts.
Wenn man so seine Probleme löst, kann man sich gleich mySQL zulegen, eine halbwegs "intelligente" DB wie der SQL Svr wäre dann sinnlos.

BTW: Wer seine Problemlösungen nicht in reinem SQL oder der Script-Sprache der DB formulieren kann, sollte sein DB-Design überdenken. ;)

Wie immer: Als ohne Gewehr, bin halt kein SQL Svr'ler ;) Leusel??? :roll:

Klarabella 28. Sep 2004 14:22

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Sorry, dass ich mich jetzt noch hierzu äußere, aber hab so n ähnliches Problem! :(
Und zwar soll bei mir ebenfalls ein Abgleich von bestimmten Daten stattfinden.
Dies jedoch zwischen einem Sybase Server und einem MS SQL Server.
Außerdem soll es ständig zur Laufzeit passieren (beispielsweise, wenn in der Sybase DB ein neuer Kunde angelegt wird, soll dieser in die DB auf dem MS SQL Server übernommen werden - jedoch nur, wenn noch nicht vorhanden!).
Mir fehlt im Moment noch völlig die Idee! Bin neu im DB Bereich.
Kann mir jemand helfen? :?:
Grüßle, Klarabella

baff 28. Sep 2004 15:18

Re: Zwei SQL-Datenbanken abgleichen, WIE?
 
Hi,

Zitat:

Außerdem soll es ständig zur Laufzeit passieren
.

da mußt du dich mal belesen, ob es für Sybase bzw. MYSQL möglich ist,
Trigger zu erstellen wie bei Oracle. Ich glaube aber schon, auch wenn nicht
so umfangreich.

Mit so einem Trigger kann auf Ereignisse reagiert werden, z.b update oder
insert einer Tabelle.

Bei dem Trigger selbst können Funktionen, Packages oder direkt SQl-Code
aufgerufen werden, welche dann z.b. Updates auf eine andere DB ausführen.

Mußt natürlich einen Database-Link erstellen auf der DB, die den Zugriff machen
soll. In deinem Fall Sybase. Ob und wie das bei Sybase geht und vor allem im Zusammenspiel mit MYSQL must du dich mal noch weiter informieren.

gruss
marcel


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:54 Uhr.
Seite 1 von 2  1 2      

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