Tabelleninhalt differentiell in andere Tabelle schreiben
Hallo zusammen,
ich habe zwei Datenbanken (A und B) und möchte von DB A den Inhalt einer Tabelle regelmäßig in DB B kopieren.
Da sich die Tabelle in DB A regelmäßig ändert (es kommen Datensätze hinzu oder werden entfernt) möchte ich nur die neuen Datensätze in die Tabelle der DB B hinzufügen. Wenn Datensätze aus der DB A gelöscht werden sollen diese weiterhin in DB B erhalten bleiben.
Dies soll ca. alle 5 Minuten passieren.
Ich verwende eine SQL2005 Server mit Windows 2003.
Über die Assistenten im SQL-Server bekomme ich das nicht hin. Hat jemand eine Idee?
MfG
ich habe zwei Datenbanken (A und B) und möchte von DB A den Inhalt einer Tabelle regelmäßig in DB B kopieren.
Da sich die Tabelle in DB A regelmäßig ändert (es kommen Datensätze hinzu oder werden entfernt) möchte ich nur die neuen Datensätze in die Tabelle der DB B hinzufügen. Wenn Datensätze aus der DB A gelöscht werden sollen diese weiterhin in DB B erhalten bleiben.
Dies soll ca. alle 5 Minuten passieren.
Ich verwende eine SQL2005 Server mit Windows 2003.
Über die Assistenten im SQL-Server bekomme ich das nicht hin. Hat jemand eine Idee?
MfG
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 147826
Url: https://administrator.de/contentid/147826
Ausgedruckt am: 04.11.2024 um 22:11 Uhr
6 Kommentare
Neuester Kommentar
Hallo,
einen Primärschlüssel hast du ja sicher, sei der Spaltenname id, dann sollte:
INSERT INTO B SELECT * FROM A WHERE A.id NOT IN (SELECT B.id FROM B)
das gewünschte tun.
Zur IN-Klausel schreibt MS "Wenn eine IN-Klausel eine extrem hohe Anzahl von Werten (viele Tausende) enthält, können die Ressourcen überbeansprucht werden" http://msdn.microsoft.com/de-de/library/ms177682.aspx
Ist der primärschlüssel streng monoton steigend (also jeder neue größer als jeder vorherige), dann dürfte auch
INSERT INTO B SELECT * FROM A WHERE A.id > (SELECT MAX(B.id) FROM B)
funktionieren und wäre vermutlich performanter.
Gruß
Filipp
einen Primärschlüssel hast du ja sicher, sei der Spaltenname id, dann sollte:
INSERT INTO B SELECT * FROM A WHERE A.id NOT IN (SELECT B.id FROM B)
das gewünschte tun.
Zur IN-Klausel schreibt MS "Wenn eine IN-Klausel eine extrem hohe Anzahl von Werten (viele Tausende) enthält, können die Ressourcen überbeansprucht werden" http://msdn.microsoft.com/de-de/library/ms177682.aspx
Ist der primärschlüssel streng monoton steigend (also jeder neue größer als jeder vorherige), dann dürfte auch
INSERT INTO B SELECT * FROM A WHERE A.id > (SELECT MAX(B.id) FROM B)
funktionieren und wäre vermutlich performanter.
Gruß
Filipp
Hallo,
hast du a) Zwei Datenbanken innerhalb einer MS SQL-Instanz oder b) zwei DBs in zwei unterschiedlichen MS SQL-Instanzen (meinetwegen auch auf unterschiedlichen physikalischen Servern)?
a) sollte ganz eifnach gehen: INSERT INTO dbB..B SELECT * FROM dbA..A WHERE dbA..A.id NOT IN (SELECT dbB..B.id FROM dbB..B)
sprich: DB-Name.. vor jede Tabelle voranstellen.
b) puh... Mir ist nicht klar, was das VIEW in deinem Statement soll. Aber ob man OPENQUERY jetzt schachteln darf... performant ist das sicher nicht. Was bestimmt funktioniert, wenngleich auch nicht performant, ist die Produktivtabelle erst auf Server B zu kopieren, und dann dort eingangs von mir genannten Query auszuführen.
Gruß
Filipp
hast du a) Zwei Datenbanken innerhalb einer MS SQL-Instanz oder b) zwei DBs in zwei unterschiedlichen MS SQL-Instanzen (meinetwegen auch auf unterschiedlichen physikalischen Servern)?
a) sollte ganz eifnach gehen: INSERT INTO dbB..B SELECT * FROM dbA..A WHERE dbA..A.id NOT IN (SELECT dbB..B.id FROM dbB..B)
sprich: DB-Name.. vor jede Tabelle voranstellen.
b) puh... Mir ist nicht klar, was das VIEW in deinem Statement soll. Aber ob man OPENQUERY jetzt schachteln darf... performant ist das sicher nicht. Was bestimmt funktioniert, wenngleich auch nicht performant, ist die Produktivtabelle erst auf Server B zu kopieren, und dann dort eingangs von mir genannten Query auszuführen.
Gruß
Filipp
Moin dondy,
ich verstehe den Plan auch nicht ganz und möchte mal nachfragen.
Verstanden habe ich den Plan aus Datensicht -> nur die "neuen" Datensätze von Server A/TabelleA sollen alle 5 Minuten auch in TabelleB auf Server B eingefügt werden. Was auch immer fachlich dahinterstehen mag.
Nicht verstanden habe ich, wen oder was du du denn mit der 5minütlichen Abgleicherei beauftragen oder beschäftigen willst.
Den DB-Server A (am dem ja wohl auch eine produktive Datenerfassungs-Appz rödelt) ?
Den Nur-Lese-DB-Clone auf DB-Server ?
Oder macht das der "man in the middle", der Verbindungsserver?
Oder beide/alle drei?
Wäre es nicht sinnvoller, wenn sich finanziell keine ETL-Applikation rechnet, den CPU-und Netzwerkaufwand ein bisschen zu minimieren dadurch, dass
Grüße
Biber
ich verstehe den Plan auch nicht ganz und möchte mal nachfragen.
Verstanden habe ich den Plan aus Datensicht -> nur die "neuen" Datensätze von Server A/TabelleA sollen alle 5 Minuten auch in TabelleB auf Server B eingefügt werden. Was auch immer fachlich dahinterstehen mag.
Nicht verstanden habe ich, wen oder was du du denn mit der 5minütlichen Abgleicherei beauftragen oder beschäftigen willst.
Den DB-Server A (am dem ja wohl auch eine produktive Datenerfassungs-Appz rödelt) ?
Den Nur-Lese-DB-Clone auf DB-Server ?
Oder macht das der "man in the middle", der Verbindungsserver?
Oder beide/alle drei?
Wäre es nicht sinnvoller, wenn sich finanziell keine ETL-Applikation rechnet, den CPU-und Netzwerkaufwand ein bisschen zu minimieren dadurch, dass
- Server A per Trigger jeden neuen Datensatz in eine Tabelle auf seinem Server A (oder auf dem Verbindungsserver) INSERTed sofort wenn ein neuer Satz eingegeben wird (der KANN noch nicht da sein)
- der Empfangsserver alle x Minuten alle diese Sätze liest, alle inserted und die Zwischentabelle C komplett löscht?
Grüße
Biber
Hallo,
Allerdings sind die Trigger ein bisschen tückisch, insbesondere, wenn man sich nicht damit auskennt. Z.b. Auslösen des INSERT-Triggers auch bei UPDATE-Vorgängen; Trigger-Aufruf bedeutet nicht, dass genau _eine_ Zeile eingefügt wurde, Trigger kann zum Rollback der ganzen Transaktion führen...
Gruß
Filipp
* Server A per Trigger jeden neuen Datensatz in eine Tabelle auf seinem Server A (oder auf dem Verbindungsserver) INSERTed sofort
wenn ein neuer Satz eingegeben wird (der KANN noch nicht da sein)
das ist natürlich der eleganteste Weg, das ist mir nicht eingefallen!wenn ein neuer Satz eingegeben wird (der KANN noch nicht da sein)
Allerdings sind die Trigger ein bisschen tückisch, insbesondere, wenn man sich nicht damit auskennt. Z.b. Auslösen des INSERT-Triggers auch bei UPDATE-Vorgängen; Trigger-Aufruf bedeutet nicht, dass genau _eine_ Zeile eingefügt wurde, Trigger kann zum Rollback der ganzen Transaktion führen...
Gruß
Filipp
Moin filippg,
Aber WTF kann bei einem Trigger schiefgehen, der einen drömeligen Satz als Kopie in eine DB-Tabelle schreibt, die nicht mal einen PK haben muss (keine Constraint-Verletzungen möglich)?
Und er braucht keinen DELETE- und keinen UPDATE-Trigger (außer die, die er vielleicht schon drin hat).
Die Alternative ist doch -verbessere mich, wenn ich irre-, dass irgendein anspruchsloser Prozess alle gatesverdammten 5 Minuten die komplette Datei zum Lesen sperren muss...
für die Dauer eines INTERSECT-JOINs (wie auch immer M$ den nennt).
Dabei geht die DB-Performance für alle Normal-Anwender runter... jeden Tag.. 365x im Jahr.
Wenn schon so eine Bypass-Schmuddellösung, dann wenigstens umwelt- und ressourcenschonend
Grüße
Biber
P.S. @dondy: Du hast übrigens ein sehr sympathisches Profilbildchen.
...sind die Trigger ein bisschen tückisch
Ja schon, ich hatte mal eine Desiree Trigger als Praktikantin, ich weiss es wirklich... und ihre Mutti erst!Aber WTF kann bei einem Trigger schiefgehen, der einen drömeligen Satz als Kopie in eine DB-Tabelle schreibt, die nicht mal einen PK haben muss (keine Constraint-Verletzungen möglich)?
Und er braucht keinen DELETE- und keinen UPDATE-Trigger (außer die, die er vielleicht schon drin hat).
Die Alternative ist doch -verbessere mich, wenn ich irre-, dass irgendein anspruchsloser Prozess alle gatesverdammten 5 Minuten die komplette Datei zum Lesen sperren muss...
für die Dauer eines INTERSECT-JOINs (wie auch immer M$ den nennt).
Dabei geht die DB-Performance für alle Normal-Anwender runter... jeden Tag.. 365x im Jahr.
Wenn schon so eine Bypass-Schmuddellösung, dann wenigstens umwelt- und ressourcenschonend
Grüße
Biber
P.S. @dondy: Du hast übrigens ein sehr sympathisches Profilbildchen.