vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Zippen wie die Profis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

ADO.NET / Datenbanken
DataTable.Merge führt zu falschem Ergebnis 
Autor: Achim 49
Datum: 06.02.18 18:46

Vorgabe: Access Datenbank mit einer Tabelle 'Pegel' mit 3 Feldern 'Datum' [DateTime], 'Ort' [String 50] und 'Hoehe' [Integer]; Primärschlüssel auf 'Datum' und 'Ort'.
Ziel: Mit Daten aus verarbeiteten .CSV-Dateien vereinen (nur hinzufügen; geänderte Daten nicht übernehmen).
Realisierung: Tabelle 'Pegel' clonen; .CSV-Daten zu Clone-Tabelle hinzufügen; beide Tabellen 'Mergen'.

Mit 'table.GetChanges(DataRowState.Added)' sollten die neu hinzugefügten Datensätze zurückgegeben werden. Statt dessen erhalte ich diese Datensätze + die bereits vorher vorhandenen Datensätze über 'DT.GetChanges(DataRowState.Unchanged)' gelistet.
Dadurch werden auch keine Daten mit der Update-Funktion zurückgeschrieben.

Wer kann mir helfen?

    Private Dateiname As String = _
      "c:\users\achim\desktop\rheinpegel\Test#1_W-N.csv"
    Private DbName As String = "c:\users\achim\desktop\rheinpegel\db1.mdb"
    Private Conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data" _
      & _
      "Source=" & DbName)
    Private DA As New OleDbDataAdapter("SELECT * FROM Pegel;", Conn)
    Private CB As New OleDbCommandBuilder(DA)
    Private DT As New DataTable
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            Conn.Open()
            DA.Fill(DT)
            Conn.Close()
 
            DT.PrimaryKey = New DataColumn() {DT.Columns("Datum"), DT.Columns( _
              "Ort")}
            Grid1.DataSource = DT
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
 
    Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles _
      btnStart.Click
        Dim dt2 As DataTable = CSV2Table(DT.Clone)
        DT.Merge(dt2, True)
 
        'Nur zur Überprüfung des Ergebnisses:
        Dim s As String = ""
        Dim DTt As DataTable
        DTt = DT.GetChanges(DataRowState.Unchanged) : If Not IsNothing(DTt) _
          Then s += "  Unv.: " & DTt.Rows.Count.ToString
        DTt = DT.GetChanges(DataRowState.Added) : If Not IsNothing(DTt) Then s _
        += "  Add.: " & DTt.Rows.Count.ToString
        DTt = DT.GetChanges(DataRowState.Modified) : If Not IsNothing(DTt) Then _
        s += "  Mod.: " & DTt.Rows.Count.ToString
        DTt = DT.GetChanges(DataRowState.Deleted) : If Not IsNothing(DTt) Then _
        s += "  Del.: " & DTt.Rows.Count.ToString
        MsgBox(s,, "Merged")
 
        Conn.Open()
        Dim i As Integer = DA.Update(DT)
        'Nur zur Überprüfung des Ergebnisses:
        MsgBox(i,, "Zurückgeschrieben")
        Conn.Close()
    End Sub
 
    Private Function CSV2Table(ByVal DT2 As DataTable) As DataTable
        :
        'In einer Schleife Datensätze (Anzahl > 3.000) einlesen
           DT2.Rows.Add({dDateTime, sOrt, iPegel})
 
        DT2.AcceptChanges()
        CSV2Table = DT2
    End Function
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Manfred X
Datum: 07.02.18 23:19

Hallo!

Die Ausführung der Methode "AcceptChanges" setzt die RowState-
Eigenschaft aller Datensätze der Table auf "unchanged".
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Franki
Datum: 09.02.18 04:13

Hallo,

du arbeitest ja mit einer Datenbank (mdb) Soweit so gut, aber dann verwendest du ein Select * im SQL Statement. Warum? Der Vorteil von SQL ist ja grade, dass man in er Lage ist schon dort festzulegen was für Daten man haben möchte. Stichwort: SQL = ... Where ... usw. Da kannst du doch schon auf nur die neuen Daten zugreifen...

Ich verstehe das seit Jahrzehnten nicht warum immer wieder Leute eine komplette Tabelle aus einer DB einlesen und dann erst im Grid ausfiltern wollen. SQL ist da viel mächtiger von den Möglichkeiten her und auch für die Anwendung ist es performanter nicht erst alles einzulesen und dann zu filtern. (Besonders dann wenn der Zugriff auf die DB über (langsames) Netzwerk erfolgt bzw. erfolten muss (DB im Internet z.B.)

Aber gut, ich muss nicht alles verstehen...

Gruß
Frank
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: effeff
Datum: 09.02.18 13:51

//Ich verstehe das seit Jahrzehnten nicht warum immer wieder Leute eine komplette Tabelle aus einer DB einlesen und dann erst im Grid ausfiltern wollen.//

Flatfilefetischisten? Gelernte Excel-Enthusiasten, die nur komplette Tabellen kennen, innehalb der man die Daten dann mit Filtern versehen kann...

Das befindet sich dann irgendwo auf Stufe 1,5.

Stufe 1: Wir verwalten unsere "Datenbanken" in Excel. Und das ist gut so!

Stufe 2: Mit Access geht das auch. Nach Möglichkeit behalten wir aber unsere Flatfilestruktur bei, damit wir uns nicht so umgewöhnen müssen. Was heißt eigentlich "relational"? Flatfile ist viel übersichtlicher...

Stufe 3: Oh, mit Access kann man auch relational...

Stufe 4: Wir entdecken die Welt richtiger Datenbanken...

Allerdings geht es ja hier darum, Daten aus einer Datenbank mit Daten aus einer CSV-Datei zu vereinen. Das ist etwas völlig anderes und von daher ist die Frage mehr als berechtigt!

EALA FREYA FRESENA

Beitrag wurde zuletzt am 09.02.18 um 14:15:22 editiert.

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Achim 49
Datum: 09.02.18 14:25

Hallo Franki,

der Hintergrund der Vorgehensweise ist folgender: Ich will in unregelmäßigen Abständen größere Datenmengen übernehmen, die im .CSV-Format vorliegen und einen Zeitraum von einem Monat abdecken. Dabei ist der Aufbau der Datenzeilen leider unterschiedlich, weswegen jede Zeile individuell ausgewertet und die relevanten Daten entnommen werden müssen. Da die Übernahme nicht immer im exakt gleichen zeitlichen Abstand erfolgt kommt es regelmäßig vor, dass sich Datensätze zeitlich mit bereits früher erfassten überlappen. Daher die Vorgehensweise: Einlesen der (neuen) Daten, anschließend 'mergen' mit den vorhandenen und abspeichern. Die Ergebnismenge (also alte UND neue Daten) wird dann in der Anwendung weiter ausgewertet (hier nur symbolisch als DGV).

Ich hoffe, ich konnte mich einigermaßen verständlich ausdrücken.

Gruß
Achim
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Achim 49
Datum: 09.02.18 14:41

Hallo Manfred,

ich habe deine Info befolgt und das AcceptChanges entfernt. Und siehe da: es funktioniert!

Aber: Mir fehlt der Zusammenhang. Ich ist bekannt, dass die Methode die State-Eigenschaft auf Unchanged zurücksetzt. Aber ich habe AcceptChanges auf die 2. Tabelle (DT2) angewendet, in die ich die neuen Datensätze eingelesen habe. Erst danach Merge ich diese Tabelle in die erste Tabelle (DT) und erwarte als Ergebnis des Mergens, dass in der Tabelle (DT) für jeden Datensatz die RowStat-Eigenschaft auf einen adäquaten Wert gesetzt ist.

Wo also ist mein Denkfehler?

Gruß
Achim
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Manfred X
Datum: 09.02.18 15:29

Es ist zu beachten, was sich die VB-Entwickler konzeptionell
für die Art der Verwendung der Merge-Methode überlegt haben - siehe z.B.
https://msdn.microsoft.com/de-de/library/wkk7s5zk(v=vs.110).aspx

So weit ich verstanden habe, wird das "Mergen" insbesondere zur Aktualisierung
von zuvor abgefragten und danach geänderten Zeilen eingesetzt - anhand des
Primärschlüssels unter Einbezug der RowState-Eigenschaft.
Die zusammengefasste Tabelle soll danach ein korrektes Datenbank-Update
ermöglichen. Dementsprechend wird die RowState-Eigenschaft der Sätze verarbeitet.

Das Zusammenfassen der Datenzeilen aus Tabellen unterschiedlicher Quellen
ist wohl eher als ein "nebensächlicher" Anwendungsfall einzuordnen.

Beitrag wurde zuletzt am 09.02.18 um 15:36:59 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Manfred X
Datum: 09.02.18 15:48

Hallo!

Datenbanken dienen dem geordneten Verwahren (relationaler,
normalisierter) Daten; Tabellenkalkulation der Aufbereitung
(aggregierter) Daten (Formeln, Diagramme, Sichten, ergänzende Texte usw.).

Kalkulations-Tabellen umfassen gewöhnlich nur wenige hundert
(aufbereitete) Datenzeilen. Es spricht nichts dagegen, solche
Quellen durch eine Anwendung komplett in den Hauptspeicher zu laden
und sie in-memory weiter zu bearbeiten.

Um Datensätze aus CSV-Dateien in einer Datenbank an eine Tabelle
anzuhängen, wird nur das Tabellenschema benötigt.
Es ist vor dem DB-Update sicher zu stellen, daß eindeutige Primärschlüssel
bei den CSV-Zeilen eingetragen sind.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Franki
Datum: 10.02.18 03:48

Hallo Achim,

grade dann wenn es sich um einen relativ seltenen Vorgang (monatlich) handelt und die Datenmenge groß ist, solltest du die entsprechenden Anpassungen einmalig beim Einlesen der neuen CSV Datei machen damit die bereinigten Daten in der DB stehen.

Du kannst dafür ja eine Wartung.exe erstellen, ein Unterprogramm oder was auch immer. Deiner Phantasie sind da keine Grenzen gesetzt.

Aber wie ManfredX ja schon schrieb ist es auch von Bedeutung um welche Datenmenge bzw. Anzahl Datensätze es sich handelt. Gib doch mal eine etwas genauere Angabe wie groß die jeweilige CSV Datei ist und wie viele Datensätze die DB enthält.

Es macht keinen Sinn alte und neu Daten erst in der Anwendung auszuwerten wenn diese nur monatlich verändert werden oder die Datenmenge sehr groß ist, bzw. die neuen Daten sehr gering im Verhältnis zur vorhandenen Datenmenge in der DB sind. Wenn eine einmalige Anpassung notwendig ist für neue Datensätze, dann solltest du sie auch nur genau einmalig durchführen und nicht bei jedem Start der Anwendung.

Gruß
Frank
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Franki
Datum: 10.02.18 03:58

Hallo,

du hast zu 100% recht, aber das ist halt "gefährliches Halbwissen" warum gewisse Leute so etwas machen.

Und du hast noch ein Argument vergessen:
Excel ist in allen preiswerten / kostenlosen Office Versionen enthalten, Access kostet zurätzliches Geld, also nehmen wir Excel.

Was die Leute halt nicht wissen, ist die Tatsache, dass sie wie in diesem Beispiel gar kein Acces brauchen um auf eine *.mdb zugreifen zu können. Die konnte man schon mit VB-Classic per Code erstellen und auch bis heute kann man daraus per ADO drauf zugreifen. Sowohl unter VBClassic, heutigem VBA als auch .NET ist das problemlos möglich.

Aber gut Excel ist bunter, schöner usw. Es bietet erweiterte Möglichkeiten wie z.B. Charts optisch ansprechend anzeigen zu können usw.

Aber den Aufwand bei einer eigenen Anwendung das auch machen zu könne scheuen viel, auch die Tatsache, dass es aus eigenen Programmen durchaus schon immer möglich war per Automation auch auf andere Programme wie Excel zugreifen zu können ist denen zu viel Aufwand gewesen.

Aber gut, jeder wie er mag, für eine private Anwendung ist das akzeptabel...

Gruß
Frank
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: effeff
Datum: 10.02.18 15:14

Ja, weiß ich doch...

Du hast schon das Smiley in meinem Text gesehen, ja?

EALA FREYA FRESENA

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: effeff
Datum: 10.02.18 15:20

Woran erkennst Du, dass ein Datensatz neuer ist als der Rest? Anhand des Feldes "Datum", welches Du als PrimaryKey definiert hast? Ist das nur ein Datumsfeld oder ein Date_/Time-Feld?

Ich würde schlicht die CSV durchgehen, sofern eine Zeile ein zu übernehmender Datensatz ist, gucken, ob in der Datenbank bereits ein Eintrag vorhanden ist und wenn nicht, diesen hinzufügen.

Danach würde ich die Datenbank zur Auswertung abfragen.

EALA FREYA FRESENA

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Achim 49
Datum: 10.02.18 17:23

Hallo zusammen,

zur Datenherkunft: Ich habe keinen Einfluss auf das Datenformat. Es wird im .CSV-Format geliefert. Es enthält die Daten für die letzten 30 Tage (~15.000 Zeilen). Die Struktur der Zeilen variiert. Deshalb muss Zeile für Zeile individuell ausgewertet werden und in ein Clone (DT2) der Muttertabelle (DT) geladen werden (angedeutet in Private Function CSV2Table | DT2.Rows.Add). Dieser Clone wird dann mit der Muttertabelle gemergt. Diese Vorgehensweise ist von der Ausführung schneller als beim dem von Effeff vorgeschlagenen Weg.
Das Datumsfeld ist immer vom Typ DateTime und wird auch so bedient.

Damit möchte ich gerne dieses Kapitel abschließen und noch mal auf den Kern meiner Frage zurück kommen: Ich ging davon aus, dass beim Mergen die RowState-Eigenschaften gesetzt werden. Wieso hat das AcceptChanges auf den Clone (DT2) VOR dem Mergen Einfluss auf die RowState-Eigenschaften in der Muttertabelle (DT)?

Gruß
Achim

Beitrag wurde zuletzt am 10.02.18 um 17:25:37 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Manfred X
Datum: 10.02.18 18:04

Hallo!

Der aktuelle Wert der Rowstate-Eigenschaft eines Datensatzes
entscheidet darüber, was beim Update der Datenbank geschehen soll.

Die aus der CSV geladenen Sätze werden als "Added" markiert.
Wenn Du "AcceptChanges" ausführst, wird die RowState-Eigenschaft zu
"unchanged", d.h. die Sätze werden beim Update nicht in die Datenbank
geschrieben.

Wenn Du diese Zeilen zuvor mit noch nicht vorhandenen Schlüsselwerten
versiehst, werden sie beim Mergen angehängt. Sie bleiben dabei "unchanged".
Ist eigentlich logisch - sie sind nicht geändert worden, sondern nur angehängt.

Dein Denkfehler liegt vermutlich darin, daß die Tabelle beim Mergen
verlängert wird durch neue Sätze. Das hat aber mit dem update-relevanten
Zustand dieser Sätze nichts zu tun.

Ein anderes Verhalten ergibt sich, wenn die geladenen Sätze anhand
des Primärschlüsselwertes bereits vorhandene Sätze in der Zieltabelle ersetzen.
In dem Fall wird die "RowState"-Eigenschaft der überschriebenen Sätze zu "modified".
Auch das ist logisch korrekt. Der Inhalt der Sätze ist durch das Mergen
geändert worden.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Manfred X
Datum: 10.02.18 18:23

Hallo!

Selbstverständlich ist mir klar, daß Du das alles weißt.
Ich war mir nicht sicher, ob das auch auf alle Mitlesenden zutrifft.

Wenn man eine überschaubare Datenmenge (normalisiert) verwalten möchte,
kann man - als Flatfile-Enthusiast oder wegen der Einfachheit -
auf eine Datenbank verzichten und statt dessen die XMLRead/Write-Methoden
des Dataset benutzen (mehrere Tabellen mit Spaltenschema und Relationen
werden dabei in einer XML-Datei zusammengefasst).

Selbstverständlich ist mir klar, daß Du das weißt.
Ich war mir wieder nicht sicher, ob das auch auf alle Mitlesenden zutrifft.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: DataTable.Merge führt zu falschem Ergebnis 
Autor: Achim 49
Datum: 11.02.18 09:30

Hallo Manfred,

Dank deiner Erklärungen habe ich meinen Denkfehler gefunden und kann jetzt das Verhalten der Merge-Methode genauer nachvollziehen.

Vielen Dank euch Alle für eure Unterstützung!

Viele Grüße und noch ein paar närrische Tage
Achim
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel