Unstimmigkeit Tabellenschlüssel und Programmablauf

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Unstimmigkeit Tabellenschlüssel und Programmablauf

    Hallo,

    ich bin im Moment in der Planung für ein Programm, der Hauptpunkt ist eine Anbindung von zwei Datenbanken an eine DataTable.
    Aus der einen Datenbank werden nur Werte geholt. Aus der anderen Datenbank können auch Werte geholt werden, überwiegend werden jedoch nur die Werte dorthin geschrieben.

    Das Schreiben war gedacht passiert per .Update-Befehl.
    Hier ist nun das Problem, dass dieser Automatismus auf den Schlüssel der geupdateten Tabelle wirkt. Zum Updaten möchte ich aber gerne einen anderen Schlüssel verwenden.

    Ein Beispiel:
    LeseDB Tabelle: (LeseID, SchreibID, Wert), der Datensatz (22, 1, "ABC") wird gelesen.
    SchreibDB Tabelle: (LeseID, SchreibID, Wert), angenommen es existiert hier bereits ein Datensatz (14, 1, "AAA") und nur dieser.
    In beiden DBs ist der Tabellenschlüssel momentan LeseID
    Bei einem Update wird daher in der SchreibTabelle der Datensatz (22, 1, "ABC") hinzugefügt.
    Beabsichtigt wäre allerdings das überschreiben von (14, 1, "AAA")
    Dazu sei auch gesagt es gibt zwischen LeseID und SchreibID keinerlei Beziehung, das sind zwei vollständig unabhägige Zahlen, die beide für sich Schlüsselfunktionalität für einen Datensatz erfüllen könnten.

    Ich würde gerne mal wissen was ihr dazu zu sagen habt. Kann man da was machen mit dem Automatismus?
    Ich könnte natürlich ein Updatecommand auch selbst schreiben.

    Viele Grüße

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Wie ist denn die bisherige Anbindung an die DBs? Dazu steht nix. Ich vermute, dass Du ein tDS dazwischengeschaltet hast, aber spekulieren ist ja bekanntlich risikobehaftet.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Haudruferzappeltnoch schrieb:

    LeseDB Tabelle: (LeseID, SchreibID, Wert), der Datensatz (22, 1, "ABC") wird gelesen.
    SchreibDB Tabelle: (LeseID, SchreibID, Wert), angenommen es existiert hier bereits ein Datensatz (14, 1, "AAA") und nur dieser.
    In beiden DBs ist der Tabellenschlüssel momentan LeseID

    Das ist ja unlogisch. Wenn der Datensatz anhand von SchreibID geupdatet wird, dann ist SchreibID der PK, nicht LeseID.

    Haudruferzappeltnoch schrieb:

    Bei einem Update wird daher in der SchreibTabelle der Datensatz (22, 1, "ABC") hinzugefügt.
    Beabsichtigt wäre allerdings das überschreiben von (14, 1, "AAA")

    Ich kann da nicht weiterhelfen, weil ich nicht weiß, ob ein Anschluss eines tDS an 2 DBs mit DB-abhängiger Angabe des PKs überhaupt möglich ist.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Haudruferzappeltnoch schrieb:

    Eigentlich muss ich die Möglichkeit haben anhand beider IDs Updates vornehmen zu können.
    aber nur in der SchreibDb, oder?

    Was heisst updaten "anhand beider IDs" ? Du meinst vmtl. die Where-Clausel des UpdateCommands.
    Und da ist doch egal, ob da die SchreibId drinsteht oder die LeseID. Beide sind ja wohl unique, und werden im DS auch nicht verändert.
    Ja ich schreibe nur in die SchreibDB

    Die SchreibID ist unique wenn anhand ihr geupdatet wird, sie ist nicht generell unique.
    Ja theoretisch wäre es die Where-Clausel, aber ich möchte den Command ja nicht selbst schreiben, wenn möglich. Das kann ja der Adapter automatisch für jeden geänderten Datensatz per .Update.

    Gerade in dem Fall wo SchreibID nicht unique ist, muss ich die LeseID verwenden. Diese Fälle kann ich klar im Vorfeld unterscheiden, nur ob ich dann im DataAdapter das anpassen kann ist die Frage.
    Was ist denn überhaupt der Sinn hinter 2 Datenbanken (also das könnte ich noch verstehen, wenn eine davon eine Art "Archiv-Datenbank" wäre mit Daten < aktuelles Jahr oder so)?
    Ich versteh nicht, warum man eine DB zum Lesen und eine zum Schreiben braucht. So wie ich das kenne läuft das in einer einzigen DB ab ?(
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Ok, seltsame Konstellation - aber wenn's nötig ist, ists wohl nötig.
    Wenn das mal funzt, würde ich mich über ein Beispiel freuen. Ich werde wohl irgendwann
    an den Punkt kommen, an dem ich mit einer Archiv-Datenbank zusätzlich arbeiten muss - dann wären es auch 2 DB's an einem DataSet :)
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    tragl schrieb:

    2 DB's an einem DataSe
    jo, damit ist wohl eine gravierende Problematik auf den Punkt gebracht.

    Man muss sich da klar machen, dasss damit die Änderungs-Verfolgung des Datasets nicht klarkommt:
    ZB ein frisch von der DB geholter Datensatz erhält RowState.Unchanged.
    Wendest du dich damit an die andere Db, so ist der RowState für die andere DB wahrscheinlich falsch, aber möglicherweise auch richtig.
    nämlich wenns denselben Datensatz mit allen Werten identisch gibt, dann wäre er richtig.
    Gibts den Datensatz aber mit anderen Werten, so müsste RowState.Modified gesetzt sein.
    Und gibts den Datensatz dort ühaupt nicht, wäre RowState.Added richtig.
    Soweit nur mit frisch gezogenen Datensätzen.
    Ziehst du nun einen Datensatz, und modifizierst, oder löschst ihn, und wendest dich dann an die andere Db, entstehen jeweils nochmal drei Unwägbarkeiten.

    Also da müssen sehr spezielle Umstände vorliegen, die es mit sich bringen, dass all diese Unwägbarkeiten ausgeschlossen werden können.
    @ErfinderDesRades:

    Bei mir gäbe es diese Datensätze dann nicht in der "Live-Datenbank", denn es handelt sich um eine Archiv-Datenbank - ggf. kommt das auch nie in Frage, kommt drauf an was der Datenbankserver nach 2-3 Jahren Daten sammeln
    zu den Mengen sagt ;)
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Das ist nun das Problem. Das was aus der LeseDB kommt macht gleichzeitig das zugehörige in der SchreibDB ungültig.
    Das heißt ich kann erst den SchreibDB Anteil laden, löschen, updaten und dann den LeseDB Anteil laden. Da ist jetzt also der RowState Unchanged
    Dann werden die Datensätze aber auch irgendwo verändert, das heißt ich hab dann überall RowState Modified.
    Ich muss aber alle auf Added setzen, die Property ist aber ReadOnly. Schon gefunden: DataRow.SetAdded

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Habe nun diesen Code, der funktioniert aber nicht wenn sich RowState.Modified Zeilen mit in der Tabelle befinden.

    VB.NET-Quellcode

    1. Private Sub ErzeugeDBEinträge()
    2. SchreibeAdapter.Fill(DS1.Test)
    3. For Each row In DS1.Test
    4. row.Delete()
    5. Next
    6. SchreibeAdapter.Update(DS1.Test)
    7. LeseAdapter.Fill(DS1.Test)
    8. DS1.Test(0).SetModified 'Der Datensatz sollte definitiv in der SchreibDB vorhanden sein
    9. For Each row In DS1.Test.Skip(1)
    10. row.SetAdded() 'Die hier sollten definitiv nicht in der SchreibDB vorhanden sein
    11. Next
    12. KonvertiereFelder()
    13. SchreibeAdapter.Update(DS1.Test)
    14. End Sub

    Ich bekomme eine Parallelitätsverletzung für den Modified Datensatz.

    Beim Updaten wird nach zuvielen Spalten gesucht, das scheint was mit Mehrfachzugriff auf eine Datenbank zutun zu haben.
    Wenn ich den zugehörigen CommandBuilder mit .ConflictOptions = ConflictOptions.OverwriteChanges intialisiere, dann kommt keine Fehlermeldung mehr. (Dann nimmt er beim Updaten in der Where Klausel wirklich nur den Schlüssel)
    Allerdings ist das Ergebnis auch nicht richtig, denn er hat nur Spalten verändert, die auch in meinem DataSet angepasst wurden.
    Offenbar hat jede Spalte ihren eigenen Modified Flag.
    Und wenn der nicht gesetzt ist, prüft er bei Standard ConflictOptions die zugehörige Spalte in der Where Klausel

    Dann braucht der CommandBuilder außerdem noch .SetAllValues = True
    Damit geht der obige Code dann.

    Mehr als Einer darf an so einer DB aber nicht schreiben. Die ConflictOptions gewinnen gegen jeden anderen, was nicht gut wäre.


    Dieser Beitrag wurde bereits 14 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()