Announcement

Collapse
No announcement yet.

SQL Tabelle mit Dataset vergleichen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SQL Tabelle mit Dataset vergleichen

    Hallo liebe Forumgemeinde,

    wie der Titel schon verrät, will ich eine SQL Tabelle mit einem Dataset vergleichen.

    Das Problem bei der Sache ist, das Ich die Änderungen des Datasets nicht während der Laufzeit mache, sondern die Änderungen in einem Excelsheet gemacht werden, dass ich zur Laufzeit einlese.

    Sprich ich muss ein "unverändertes" (zur Laufzeit unverändertes) Dataset mit der SQL Tabelle vergleichen, um Änderungen zu bemerken.

    Ist dies Überhaupt möglich? Ich habe viel Herumexperimentiert und Stundenlang gegoogelt, aber nichts gefunden..

    Ich hoffe es hat jemand eine Lösung für mich.

    Nachfolgend mein Code:

    [highlight=vbnet]Private Sub einlesenxls()
    Dim SQLservername_Text As String
    Dim antwort As DialogResult
    Dim conString As String
    Dim con As SqlConnection = Nothing

    SQLservername_Text = SQLservername.CurrentRow.Cells(0).Value & "\" & SQLservername.CurrentRow.Cells(1).Value
    antwort = MsgBox("Soll die Datei '" & Mid(Pfad.Text, InStrRev(Pfad.Text, "\") + 1, Len(Pfad.Text)) & "'" & vbCrLf & _
    "in die Tabelle '" & Tabelle.SelectedItem & "'" & vbCrLf & _
    "importiert werden?", MsgBoxStyle.YesNo, "Importieren?")
    If antwort = Windows.Forms.DialogResult.Yes Then
    Cursor.Current = Cursors.WaitCursor
    Dim constr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Pfad.Text & ";Extended Properties=text;HDR=Yes;FMT=Delimited;"
    Dim SQL As String = "Select * From " & Mid(Pfad.Text, InStrRev(Pfad.Text, "\") + 1, Len(Pfad.Text))
    Dim DT As New DataTable
    Dim conn As New OleDb.OleDbConnection(constr)
    Dim da As New OleDb.OleDbDataAdapter(SQL, conn)

    Try
    Dim anmeldung As String
    If SSPI.Checked = True Then
    anmeldung = ";Integrated Security=SSPI"
    Else
    anmeldung = ";User ID=" & Benutzername.Text & ";Pwd=" & Passwort.Text
    End If
    conString = "Server=" & SQLservername_Text & ";database=" & Datenbank.Text & anmeldung

    con = New SqlConnection(conString)


    Dim sConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Text;Data Source=" & Mid(Pfad.Text, 1, InStrRev(Pfad.Text, "\"))
    Dim objConn As New OleDbConnection(sConnectionString)
    objConn.Open()
    Dim strConnection As System.Data.OleDb.OleDbConnection = Nothing
    Dim myPath As String = Pfad.Text
    Dim objDataSet As System.Data.DataSet
    Dim objAdapter As System.Data.OleDb.OleDbDataAdapter
    strConnection = New System.Data.OleDb.OleDbConnection("Provider=Micros oft.Jet.OLEDB.4.0; Data Source='" & myPath & " '; " & "Extended Properties=Excel 8.0;")
    objAdapter = New System.Data.OleDb.OleDbDataAdapter("select * from [Tabelle1$]", strConnection)
    objDataSet = New System.Data.DataSet

    objAdapter.Fill(objDataSet)
    objConn.Close()

    con.Open()
    If Insert.Checked = True Then
    Dim oBulkCopy As New SqlBulkCopy(con)
    With oBulkCopy
    .DestinationTableName = "dbo." & Tabelle.SelectedItem
    .WriteToServer(objDataSet.Tables(0))
    End With
    End If

    If Update1.Checked = True Then

    Dim da1 As New SqlDataAdapter("SELECT * FROM " & Tabelle.SelectedItem, con)
    'Dim UpdRecords As DataTable = CType(objDataSet.Tables(0), DataTable).GetChanges(DataRowState.Modified)
    'Dim da1 As New SqlDataAdapter
    ' da1.SelectCommand = New SqlCommand("SELECT * FROM " & Tabelle.SelectedItem, con)
    'da1.SelectCommand.CommandText = "SELECT * FROM " & Tabelle.SelectedItem
    'da1.SelectCommand.CommandType = CommandType.Text
    'If Not UpdRecords Is Nothing Then
    'Dim cb As SqlCommandBuilder
    'cb = New SqlClient.SqlCommandBuilder(da1)
    ' da1.UpdateCommand = cb.GetUpdateCommand
    ' da1.Update(UpdRecords)
    ' UpdRecords.Dispose()
    ' End If
    'Dim dataSet As DataSet = New DataSet
    Dim cmdBuilder As SqlCommandBuilder = New SqlCommandBuilder(da1)

    da1.Fill(objDataSet, Tabelle.SelectedItem)

    ' Code to modify data in DataSet here

    cmdBuilder.GetUpdateCommand()

    ' Without the SqlCommandBuilder this line would fail.
    Dim betroffen As Integer
    betroffen = da1.Update(objDataSet)


    'Dim da1 As SqlDataAdapter
    'da1 = New SqlDataAdapter("", con)
    'da1.SelectCommand.CommandText = "SELECT * FROM " & Tabelle.SelectedItem
    'da1.SelectCommand.CommandType = CommandType.Text
    'Dim cmdBuilder As SqlCommandBuilder = New SqlCommandBuilder(da1)
    'da1.Update(objDataSet, Tabelle.SelectedItem)
    End If


    If Delete.Checked = True Then
    MsgBox("noch nicht fertig!")
    End If

    con.Close()
    Anzeige.Text = "Daten importiert!"
    Catch ex As Exception
    MsgBox(ex.Message, MessageBoxButtons.OK, _
    MessageBoxIcon.Exclamation)
    End Try

    Else
    Exit Sub
    End If

    End Sub[/highlight]

    Der im Code relevante Teil ist in Grün markiert. (Code Zeilen 54-89)
    (Wie man sieht hab ich einiges ausprobiert.)

    Ich hoffe es kann mir jemand helfen.

    Vielen Dank im Vorraus.

    Mit freundlichen Grüßen

    Thors Hamster
    Zuletzt editiert von Thors.Hamster; 03.12.2009, 10:05.

  • #2
    Hallo und willkommen,

    einen richtigen Rat kann ich nicht geben, weil ich VB zwar halbwegs lesen kann, aber den Zusammenhang nicht unbedingt verstehe. Mir sind folgende Gedanken gekommen:

    1. Du schreibst durchgehend von DataSet auf der einen Seite und Tabellen auf der anderen Seite. Mit einem DbDataAdapter bekommt man immer genau eine Tabelle, auch beim Einlesen eines Excel-Blattes. Dann musst du wohl auch immer genau eine Tabelle mit genau einer anderen vergleichen.

    2. Nach welchen Kriterien sollen die Vergleiche laufen? Geht es darum festzustellen, ob sich Zeilen unterscheiden, oder darum, wo sie sich genau unterscheiden?

    3. Mein Gedanke wäre, alles in einem DataSet zusammenzufassen und ingesamt drei DataTables zu vergleichen: eine aus der Datenbank, eine "originale" aus dem DataSet, eine aus Excel.

    4. Vielleicht helfen auch Methoden von DataTable weiter: Merge oder GetChanges, für die Vergleiche auch Select oder Compute. Weitere Erläuterungen dazu stehen unter DataColumn.Expression.

    Ich hoffe, ich habe ein paar sinnvolle Ideen beisteuern können. Jürgen

    Comment


    • #3
      Also so wie ichs verstanden habe hat er wohl eine Tabelle in einer Datenbank. Diese wird in ein Excel Sheet exportiert. Das wird irgendwo bearbeitet und er muss nun die geändert Daten zurück in die DB übernehmen.

      Comment


      • #4
        Hallo Jürgen, Hallo fanderlf,

        fanderlf hat den Sinn verstanden :-)
        Ich lese die Tabelle aus der SQL Datenbank aus. Diese wird dann Lokal vom Nutzer bearbeitet und soll dann zurück in die SQL Datenbank gespielt werden.

        zu Punkt 2 von Jürgen:
        An sich ist es nur wichtig, welche Zeile sich geändert hat, da ich ja dann die ganze Zeile überschreiben kann. Geht es nur mit einzelnen Zellen, ist dies auch kein Problem, da ich dann eben die Zellen überschreibe. Es geht nur darum, die Veränderung zu erkennen, und auszuführen.

        bei Punkt 3, verstehe ich nicht ganz, was du mit der "originalen" Dataset meinst. Ich habe ja nur 2 "Tabellen", die ich vergleichen will.

        Ich werde es mal mit deinen Tipps ausprobieren.

        Schonmal Vielen Dank an euch beide.

        Gruß

        Thors Hamster

        Comment


        • #5
          und es ist sicher dass die in Excel bearbeiteten Daten valide sind! Ist mir eine sehr suspekte Vorgehensweise ...
          Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

          Comment


          • #6
            Das Problem muss er halt beim Importieren berücksichtigen.

            Das kling alles nach so einer Chefmodus Geschichte. Weil Chef das Programm (was eigentlich nur online funktioniert, weils an einer DB hängt) nun plötzlich auch offline benutzen muss, wenn er mal mit seinem Laptop unterwegs ist.

            Comment


            • #7
              Nein, es hat nichts mit einem Chefmodus zu tun :-D

              Das Problem liegt darin, dass Daten, aus zwei unterschiedlichen Datenbanken (SAP und Dataportal von Eplan) !händisch! zusammengeführt werden müssen.

              Ich dachte mir, das ginge am leichtesten, wenn man dies in Excel macht, und dann wieder einliest.

              Anscheinend ist meine Vorgehensweise nicht ganz richtig...

              Wie würdet ihr denn soetwas gestalten? Ich bin für alle Vorschläge offen.

              Gruß

              Thors Hamster

              Comment


              • #8
                ich weiß nicht aber grundsätzlich musst du halt Validierungsalgorithmen haben. Ich denke dass die Fehlerquote in einer Winform geringer wären weil du da mehr Kontrolle hast in Excel kann halt jeder alles machen. Grundsätzlich kannst du so vorgehen nur die Validierung musst du berücksichtigen, denn du kannst nicht davon ausgehen das händische Eingaben gut und richtig sind.
                Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

                Comment


                • #9
                  Ok, ich kann ja eine Form in Excel erstellen.

                  Auf was muss ich bei der Validierung achten? Nur auf den Typ der Zelle (Integer, String etc), oder noch auf bestimmte Wertgrößen etc?
                  Was kann ich unter einer Validierungsalgorithme verstehen?

                  Und falls die Validierung dann korrekt sein sollte, stehe ich immer noch vor meinem altbekannten Problem, dass ich nicht weiß, welche Zellen/Zeilen ich überschreiben muss...

                  Gruß

                  Thors Hamster

                  Comment


                  • #10
                    Also das Thema Datenvalidierung kann Dir so keiner abnehmen, da wir nicht wissen was für Dich gültige Daten sind.

                    Wird denn jetzt faktisch jemand die Daten von Hand in dem Excel Sheet ändern oder nicht?

                    Verwendest Du Excel nur als "Mittelsmann", dann würde ich mir um Validierung nicht zu viele Gedanken machen, wenn die Formate in den Datenbanken übereinstimmen.

                    Warum musst Du denn Daten überschreiben, wenn Du momentan zwei verschiedene DBs zusammenführen möchtest (oder ich hab das Problem falsch verstanden).

                    Comment


                    • #11
                      Man kann sagen, dass ich Excel nur als "Mittelsmann" nutze.

                      Es werden Daten von den beiden Datenbanken kopiert, und in meine SQL Tabelle eingefügt.

                      Aber es soll nicht nur eingefügt, sondern auch aktualisiert werden, wo dann der Vergleich ins Spiel kommt. Der Vergleich zwischen der geänderten Exceltabelle und meiner Tabelle auf dem SQL Server. Die geänderten Daten sollen dann eben auch im SQL Server geändert werden.

                      Gruß

                      Thors Hamster

                      Comment


                      • #12
                        Hallo,

                        nach Kenntnisnahme aller Informationen empfehle ich, auf die Krücke Excel zu verzichten. Was angepasst werden soll, sollte typsicher innerhalb einer NET-Anwendung ablaufen.

                        1. Hole die "Fremddaten" in ein DataSet (also eine oder zwei DataTables).
                        2. Bearbeite die DataTable manuell (über ein DataGridView) oder halbautomatisch im Sinne deiner Validierung.
                        3. Erzeuge einen SqlCommand, der alle vorhandenen Datensätze anhand der ID durch "Insert or Update" in die DB überträgt, natürlich mit Parametern. Da MS-SQL keinen solchen Befehl kennt, muss das über einen INSTEAD OF-Trigger gesteuert werden.
                        4. Binde diesen SQL-Befehl in eine Transaktion ein und führe ihn in einer Schleife aus.

                        Es ginge wohl auch über DbDataAdapter.Update; aber in deiner Situation sollte die SQL-Datenbank entscheiden, ob es sich um INSERT oder UPDATE handelt. Sonst musst du erst lange rumfummeln (eben mit dem Abrufen von Daten aus der Datenbank, Vergleichen und Setzen von DataRowState).

                        Gruß Jürgen

                        Comment


                        • #13
                          Hallo Jürgen,

                          Ich werde deinen Lösungsvorschlag in Betracht ziehen, und wahrscheinlich auch ausführen.
                          Aber kann mir noch jemand sagen, wie ich die Datatables miteinander vergleichen, und die Änderungen in meine Datenbank spielen kann? Dann kann ich zumindest dieses Programm noch fertig machen.

                          Vielen Dank

                          Thors Hamster

                          Comment


                          • #14
                            Ich würde das manuell machen. Auf die Automatismen würde ich in so einem heiklen Fall verzichten.

                            Sprich:

                            Lade Dir alle Daten die sich in der Final DB finden in ein DataSet -> FinalDataset
                            Lade Dir alle Daten die von anderen Quellen kommen in ein DataSet -> TempDataSet

                            Für jeder Zeile in TempDataSet schaue nach ob in FinalDataSet ein PK existiert, wenn ja ändere die Daten, ansonsten erzeuge neuen Datensatz in FinalDataSet.

                            Das wäre meine Vorgehensweise.

                            Comment


                            • #15
                              Hallo fanderlf,

                              was meinst du mit PK? Personalkennziffer? Oder PID?

                              ich werde deine Lösung mal ausprobieren.

                              Gruß

                              Thors Hamster

                              Comment

                              Working...
                              X