theunreal
Goto Top

Aktualisierungsabfrage nur für geänderte Werte?

Hallo zusammen,

ich habe da mal eine Frage - bisher waren meine Datenmengen immer recht überschaubar. Mit den Projekten wachsen aber auch Anforderungen und bei mir manchmal die Fragezeichen.

Ich habe eine Tabelle mit knapp einer Million Datensätzen, Tendenz stark steigend. Bisher habe ich mich nur ums Anfügen der Daten gekümmert - aber da es sich um eine Schnittstelle handelt können sich die vorhandenen Daten natürlich auch geändert haben.

Nun meine Preisfrage : Gibt es eine Möglichkeit nicht immer alle Werte der ganzen Tabelle aktualisieren zu müssen, die ich vielleicht nicht kenne?

Mein erster Gedanke war es, einen Hashwert vom Tupel zu ziehen und den zu vergleichen - aber ganz überzeugt bin ich da noch nicht von mir.
Mein zweiter Gedanke war die Idee das mit 3-4 Abfragen auf unterschiedliche, zu erwartende Änderungsfelder zu setzen und diese einfach 1:1 zu vergleichen.
Mein dritter Gedanke war, einen Post hier abzusetzen bevor ich Zeit mit der Umsetzung einer zum Scheitern verurteilten Idee verschwende.

Wie würdet Ihr sowas lösen?

Ich freue mich über Anregungen!
Solong, Sascha

Content-Key: 3122731355

Url: https://administrator.de/contentid/3122731355

Ausgedruckt am: 28.03.2024 um 13:03 Uhr

Mitglied: akretschmer
akretschmer 20.06.2022 um 09:39:48 Uhr
Goto Top
Keine hier kennt Deine Anwendung, keiner weiß, welche Werte Du aktualisieren willst. Ich kann Dir aber eines sagen: UPDATE kann man mit WHERE verfeinern.
Mitglied: maretz
maretz 20.06.2022 um 12:30:03 Uhr
Goto Top
und hier kommt es auch drauf an was für daten es sind... im dümmsten Fall machst halt (da keiner deine anwendung kennt kann man nur grobe Ideen geben) nen zusätzliches feld rein: "Last update" mit nem Timestamp. Wenn du jetzt also nur Daten aktuallisieren willst die nicht in den letzten 24h schon gemacht wurden: where lastupdate <= now - 24h (genaue syntax kannst du dir ja raussuchen)

geht natürlich auch andersrum - da hängt es einfach von deiner Anwendung ab was da Sinn macht...
Mitglied: it-frosch
it-frosch 20.06.2022 um 13:03:10 Uhr
Goto Top
Hallo Sascha,

ich habe das Thema für mich so gelöst.

Entweder ich kann den Daten ein zusätzliches Feld als "Flag" mitgeben, dass ich entsprechend setzen kann oder wenn ich sehr viele Daten verarbeiten muss (egal ob Update oder Insert), dann lese ich diese zuerst in ein temporäre Tabelle und verarbeitet diese dann paketweise (modifiziere rowcount - z.B. set rowcount=100).

Das hat die Verarbeitungsgeschwindigkeit schon deutlich verbessert.
Mitglied: Crusher79
Crusher79 20.06.2022 um 23:42:56 Uhr
Goto Top
Hi,

ich verstehe es irgendwie nicht. Daten anfügen - ok. Wie sollen wir uns den Rest vorstellen? Ins blaue hinein wird irgendwas upgedated?

Was für eine Schnittstelle? Protkolliert sie die Änderungen? Normal mach sowas z.B. das ERP System dahinter. Anlege- und Änderungsdatum etc. sind Standard.

https://stackoverflow.com/questions/6344413/sql-server-row-date-last-mod ...

Da siehst du auch ein paar Ansätze. Aber welche DB hast du überhaupt? Was für Daten? Was soll denn aktualisiert werden? Bzw. was nicht.

Felder vergleichen geht. Es gibt Scripte/ Tools etc. die sowas machen. Du kannst auch 1 Mio in DB A und 1 Mio in DB B speichern und vergleichen. Frage nach den Sinn/ Geschwindigkeit/ Ressourcen kommen nur dann.....

https://docs.microsoft.com/de-de/sql/t-sql/functions/columns-updated-tra ...

Sowas geht bei MS SQL. Nach den Testen Aktion XY ausführen. .....
Mitglied: TheUnreal
TheUnreal 21.06.2022 aktualisiert um 07:43:01 Uhr
Goto Top
Moin zusammen,
danke für die Beteiligung.Ich dachte ehrlich gesagt nicht, dass die Anwendung interessiert - warum auch, es gibt keine?
Es handelt sich um eine Schnittstelle zwischen einem alten (selbstentwickelten) ERP und einem neuen ERP.

SQL Dialekt - Okay face-smile
Und irgendwie dachte ich auch, ich hätte meine Frage präzise genug gestellt, aber so ist das mit dem Denken im eigenen Kreisel :D.

Da ist MsSQL auf der einen und Postgres per ODBC auf der anderen.
Ich habe Daten (was auch immer - Text,Datum, Zahl -- is doch wurscht?!) in einer Tabelle und füge stumpf jeden Datensatz von MsTabelle an PostgresTabelle an.

MsTabelle ---> PostgresTabelle

Nun ergibt sich aber, dass nach dem anfügen die Daten in MsTabelle modifiziert werden (Wieder ist es für die Frage egal ob Datum usw.) sodass ich in PostgresTabelle im Grunde immer auch ALLE Felder ALLER Datensätze aktualisieren müsste die ich vorher angefügt habe. Schließlich weiß ich ja nicht, wo sich etwas geändert haben könnte.

Das kostet aber unnötig Zeit, sodass ich nach Möglichkeiten zur Optimierung suche - ich brauche keinen speziellen SQL Code.

@it-frosch kommt meiner Frage mit seinem Ansatz schon am nächsten face-smile

Ich hoffe ich konnte etwas Licht ins Dunkel bringen.
Mitglied: Crusher79
Crusher79 21.06.2022 aktualisiert um 08:41:57 Uhr
Goto Top
Zitat von @TheUnreal:

Moin zusammen,
danke für die Beteiligung.Ich dachte ehrlich gesagt nicht, dass die Anwendung interessiert - warum auch, es gibt keine?
Es handelt sich um eine Schnittstelle zwischen einem alten (selbstentwickelten) ERP und einem neuen ERP.

Weil eine Schnittstelle alles sein kann. Einige bieten auch Log-Features ....

SQL Dialekt - Okay face-smile

Naja Nein. SQL 2000, 2008, etc... Gerade bei alten Systemen ist das Problem, dass es früher einige nützliche Funktionen nicht gab.

Da ist MsSQL auf der einen und Postgres per ODBC auf der anderen.

Schön. Wir haben einen Namen. Zwar noch keine Versionsnummer, aber immerhin.

Ich habe Daten (was auch immer - Text,Datum, Zahl -- is doch wurscht?!) in einer Tabelle und füge stumpf jeden Datensatz von MsTabelle an PostgresTabelle an.

Nein. Wenn man stumpf versucht 2x Zeilen - aucht mit Binäredaten o.ä. zu vergleichen gibt es Fehler. Die Art ist schon wichtig, je nachdem was man vergleichen möchte.

Trigger?

Es sollte festgestellt werden, wo Dokumente beim "Abzeichnen" liegen bleiben. Im System wurde Datum und Kürzel hinterlegt. Würde man die Daten nacheinander aufreihen so kann man die Zeitendifferenzen sichtbar machen. Mitarbeiter A und B tragen am 20.06.2022 umd 9:13 Uhr und um 11:20 Uhr was ein. Mitarbeiter C aber erst am 21.06.2022 um 08:15 Uhr.

Also lag der Vorgang über 12 Std. da rum.

Ist aus den Links oben zusammengeklaut. Server war hier MS SQL 2012.

Warum wichtig? Später verwendete ich zum Aufberreiten der Datensätze LAG Funktion. Damit war alles sauber sortiert und ich konnte die Zeiten vergleichen.

LAG:
Greift im selben Resultset auf Daten in einer vorherigen Zeile zu, ohne dass ein Selbstjoin ab SQL Server 2012 (11.x) verwendet wird.


Ab Server 2012... Nicht 2000 oder 2008 - darum auch immer die Frage welchen SQL Server die Leute einsetzen und in welcher Version.

Für Abgleiche ggf. noch welche Sprache/ Datumsformat. Sonst gehen Vergleiche in die Hose.

Log Tabelle die Änderungen protokolliert

use TolleDB
GO
DROP TABLE intern.dbo.auditE_BerichtHz;
DROP TRIGGER updE_Bericht;

CREATE TABLE intern.dbo.auditE_BerichtHz (
   
   --audit_log_id uniqueidentifier DEFAULT NEWID() PRIMARY KEY,  
   audit_log_id              INT           NOT NULL    IDENTITY    PRIMARY KEY,
   audit_log_type char (3) NOT NULL,  
   audit_pat_num int NOT NULL,  
   audit_kurz_sd char (5) NOT NULL,
   audit_verlauf1 char (20) NOT NULL,  
   audit_verlauf2 char (20) NOT NULL,  
   audit_verlauf3 char (20) NOT NULL,  
   audit_verlauf4 char (20) NOT NULL,  
   audit_verlauf5 char (20) NOT NULL,  
   audit_verlauf6 char (20) NOT NULL,  
   audit_user sysname DEFAULT SUSER_SNAME(),  
   audit_changed datetime DEFAULT GETDATE()  
   );  
   GO
      


CREATE TRIGGER updE_Bericht ON [dbo].[e_bericht]
AFTER UPDATE AS  
    IF ( 1+2=3
	--(SUBSTRING(COLUMNS_UPDATED(), 6, 1) & 31 > 0)   
        )   

      BEGIN  
-- Audit OLD record.  

      INSERT INTO intern.dbo.auditE_BerichtHz 
         (audit_log_type,  audit_pat_num, 
		 audit_kurz_sd,
         audit_verlauf1,  
         audit_verlauf2,  
         audit_verlauf3,
		 audit_verlauf4,      
         audit_verlauf5,
		 audit_verlauf6)  
         SELECT 'OLD',     
		    del.pat_num,
			del.kurz_sd,
            del.verlauf1,
            del.verlauf2,  
            del.verlauf3,  
            del.verlauf4,
			del.verlauf5,
			del.verlauf6
         FROM deleted del
		 INNER JOIN inserted ins ON del.pat_num=ins.pat_num 
		 WHERE ins.verlauf1<>del.verlauf1 OR
		 ins.verlauf2<>del.verlauf2 OR
		 ins.verlauf3<>del.verlauf3 OR
		 ins.verlauf4<>del.verlauf4 OR
		 ins.verlauf5<>del.verlauf5 OR
		 ins.verlauf6<>del.verlauf6 OR
		 ins.kurz_sd<>del.kurz_sd;  

-- Audit NEW record.  
      INSERT INTO intern.dbo.auditE_BerichtHz 
         (audit_log_type,audit_pat_num,  
		 audit_kurz_sd, 
         audit_verlauf1,  
         audit_verlauf2,  
         audit_verlauf3,
		 audit_verlauf4,      
         audit_verlauf5,
		 audit_verlauf6)  
         SELECT 'NEW',     
		    ins.pat_num,
			ins.kurz_sd,
            ins.verlauf1,  
            ins.verlauf2,  
            ins.verlauf3,  
            ins.verlauf4,
			ins.verlauf5,
			ins.verlauf6
         FROM deleted del
		 INNER JOIN inserted ins ON del.pat_num=ins.pat_num 
		 WHERE ins.verlauf1<>del.verlauf1 OR
		 ins.verlauf2<>del.verlauf2 OR
		 ins.verlauf3<>del.verlauf3 OR
		 ins.verlauf4<>del.verlauf4 OR
		 ins.verlauf5<>del.verlauf5 OR
		 ins.verlauf6<>del.verlauf6 OR
		 ins.kurz_sd<>del.kurz_sd;  

   END;  
GO  
Mitglied: TheUnreal
TheUnreal 21.06.2022 um 09:13:53 Uhr
Goto Top
Zitat von @Crusher79:

Weil eine Schnittstelle alles sein kann. Einige bieten auch Log-Features ....

Okay, die Schnittstelle ist nur eine Ansammlung von Abfragen und Funktionen die meiner Feder entspringen.

Da ist MsSQL auf der einen und Postgres per ODBC auf der anderen.
Schön. Wir haben einen Namen. Zwar noch keine Versionsnummer, aber immerhin.

Dann korrigiere ich mal wie folgt : AccessSQL 97 zu Postgres 12.
Als Schnittstellenbasis nutze ich Access2003, da ich so problemlos auf pSQL und Acc97 DB zugreifen kann.

Ich habe Daten (was auch immer - Text,Datum, Zahl -- is doch wurscht?!) in einer Tabelle und füge stumpf jeden Datensatz von MsTabelle an PostgresTabelle an.

Nein. Wenn man stumpf versucht 2x Zeilen - aucht mit Binäredaten o.ä. zu vergleichen gibt es Fehler. Die Art ist schon wichtig, je nachdem was man vergleichen möchte.

Ah okay, danke . Es ist also nicht mehr Wurst, sobald ich meine Ziele verfolgen möchte. Nun hab ichs kapiert.

//LAG:
Ab Server 2012... Nicht 2000 oder 2008 - darum auch immer die Frage welchen SQL Server die Leute einsetzen und > in welcher Version.

Damit fällt das schonmal weg. Aber ich lese mir jetzt erstmal den MS Link in Ruhe durch, danke !
Mitglied: Crusher79
Crusher79 21.06.2022 um 09:23:21 Uhr
Goto Top
AccessSQL?

Oben hast du MS-SQL geschrieben! Mein Beispiel: MS SQL Server ab 2012......
Mitglied: TheUnreal
TheUnreal 21.06.2022 um 10:11:38 Uhr
Goto Top
Jupp, hab ich geschrieben weil ich warum auch immer im GEdankenkarussel "Microsoft" war.

Aber Access hat ja seinen eigenen Dialekt. Ich versuche da nächstes mal vom Start präziser zu sein face-sad
Mitglied: Crusher79
Crusher79 21.06.2022 um 10:17:22 Uhr
Goto Top
Problem: mache nichts mit Acces. Ka ob es diese Feldverglecihe (vorher/ nachher) da auch so gibt.

Oder hast du noch Zugriff aut die ERP Quellen? Eine Spalte anfügen geht ja meist. Wenn im SELECT explizit Spalten stehen, fällt die am Ende einfach runter.

Ggf. könnte man so "Modified" Field ncoh einfügen und nur die Tagesdatensätze abgleichen. Das wäre am elegantesten. Mit zusätzlichen Index auf das neue Datumsfeld sollte es dann auch schnell gehen mit dem Abgleich.
Mitglied: MadMax
MadMax 21.06.2022 um 17:04:24 Uhr
Goto Top
Hallo Sascha,

was ich jetzt noch nicht so ganz verstanden habe: warum brauchst Du das überhaupt?

Wenn ich von einem alten zu einem neuen System migriere, dann mache ich einen Probelauf bzw. auch mehrere, bis es eben paßt, und dann gibt es einen Zeitpunkt X, zu dem dann der Umzug erfolgt.

Warum willst Du die Daten abgleichen? Willst Du eine Replikation zwischen verschiedenen Systemen einrichten? Nicht wirklich, oder?

Gruß, Mad Max
Mitglied: TheUnreal
TheUnreal 21.06.2022 um 18:40:55 Uhr
Goto Top
Hallo MadMax,

auch das neue System ist eine hauseigene Entwicklung. Im Grunde steht die Datenbank Struktur und Ziel ist es es, Zug um Zug umzuziehen.
Um aber in einzelnen Bereichen bereits mit dem neuen System zu arbeiten müssen die Daten des alten vorhanden sein.
Das ganze ist One-Way alt zu neu.
Das bedeutet, ich möchte nicht direkt replizieren, sondern nur die PostgreSQL auf Stand der Access Datenbank halten.
Nur fürs Protokoll, das steht und läuft auxh schon - aber mir mit 22 Minuten für einen kompletten Durchlauf einfach zu langsam.
Gruß Sascha
Mitglied: MadMax
MadMax 21.06.2022 um 20:42:43 Uhr
Goto Top
Hallo Sascha,

seit Access 2010 gibt es "event-driven data macro", die kann man wohl als Trigger verwenden. Also kannst Du in alle Tabellen in Access, oder zumindest die großen, zeitkritischen, ein UpdateFlag einfügen, ob was geändert wurde. Das setzt Du per Trigger und setzt es wieder zurück, wenn Du die Daten nach Postgre übertragen hast. Dann brauchst Du immer nur die Daten aktualisieren, die das Flag gesetzt haben.

Problem: gelöschte Zeilen. Entweder das Feststellen der gelöschten Zeilen geht flott genug (delete ... where not exists (...)), oder Du legst statt der Flags in den einzelnen Tabellen eine zusätzliche Tabelle an, wo Du die geänderten Datensätze einträgst.

Aber wenn Du das Update in Postgre flott hinbekommen willst, wirst Du Dir die in Access geänderten Daten merken müssen. Und da Access keinen Datentyp "rowversion" kennt, dürfte das nur über Trigger gehen.

Gruß, Mad Max
Mitglied: maretz
maretz 22.06.2022 um 06:04:57 Uhr
Goto Top
Moin,

für so eine Anwendung würde ich dann den ENTWICKLER für den Migrationspfad fragen. Wenns eh ne hauseigene Entwicklung ist dann sollten die das ja wissen (oder die haben schwachsinnig entwickelt - wenn beides selbst entwickelt wird aber kein Daten migriert werden...).

Als Entwickler hast du ja auch noch andere Möglichkeiten - zum Beispiel einfach die Schreibzugriffe auf die DB einfach auf 2 Datenbanken zu machen.

Wenn du sowas per Hand baust kannst du eben auch ne Menge zerlegen - je nach Grösse und Nutzung des Systems. In der DB gibt es ja ggf. für einige Aktionen Transaktionen - blöd wenn dein Migrationstool die nicht beachtet und danach in der DB unterschiedliche Daten sind. Dann hast du ggf. irgendwelche Auto-Increment werte (z.B. IDs) - wenn du die nicht in der richtigen Reihenfolge überträgst wirds dir dein System auch vor die Füsse werfen.

Von daher würde ich das immer nur über die Applikation migrieren lassen. Und falls irgend möglich z.B. an nem WE die alte DB ausser Funktion setzen, die Daten übertragen und die alte dann auf Read-Only setzen (bzw. in der Applikation dafür sorgen das Save-Buttons abgeschaltet sind). Es ist jetzt nix ungewöhnliches das bei so einer Umstellung eben irgendwann das System mal für 1-2 Tage off ist. Besser so als irgendwann falsche Inhalte oder fehlende Inhalte zu haben.
Mitglied: TheJoker2305
TheJoker2305 01.07.2022 um 11:43:21 Uhr
Goto Top
Hallo zusammen,

ich würde hier einem Update- und einem Insert-Trigger arbeiten.
Die Trigger aktualisieren entweder in der eigentlichen Datentabelle zwei neu anzulegende Spalten

inserted_at (BIT)
updated_at (BIT)

Sobal ein neuer Datensatz eingetragen wird wird das Feld inserted_at mit dem aktuellen Timestamp befüllt.
Beim Update erfolgt der Eintrag in das updated_at-Feld.

Anschließend kannst du, je nachdem wie häufig die Daten auf die andere Datenbank transferiert werden sollen die Datensätze übertragen:

Hole neue Datensätze
Select * from MAIN where inserted_at = 1
anschließend
update MAIN set inserted_at = 0 where inserted_at = 1

Hole geänderte Datensätze
delete from ZIEL
WHERE id in (Select id from MAIN where updated_at =1)

Insert into ZIEL ....
Select * from MAIN where updated_at = 1
update MAIN set updated_at = 0 where updated_at = 1

Greetz,
thejoker2305
Mitglied: TheUnreal
TheUnreal 06.07.2022 um 10:14:19 Uhr
Goto Top
Vielen Dank für die vielen Anregungen !

Tatsächlich scheint mir der Ansatz eines Update-Schalters die einfachste Variante. Ich werde mich (leider erst) jetzt tiefer damit auseinandersetzen und dann eine Lösung erarbeiten.
Da die Schnittstelle prinzipiell läuft ist der Druck nicht so hoch wie mein Anspruch face-smile.