Announcement

Collapse
No announcement yet.

Datensätze in Access Datenbank schreiben

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

  • Datensätze in Access Datenbank schreiben

    Hallo,

    bin neu hier und hab gerad erst mit VB.NET angefangen.
    Jetzt steh ich gerad vor einem Problem und komme nicht weiter.
    Ich möchte für Geschwindigkeitstests eine riesige Menge an Datensätzen über eine Schleife in eine Access Datenbank schreiben lassen, nur bricht die Schleife das Schreiben immer zufällig an unterschiedlichen Stellen ab.
    Mal beim 1072 Datensatz, oder schon beim 12.
    Ich kann mir das nicht erklären, hab auch schon ein bischen mit Threadbefehlen rumprobiert, aber bis jetzt hat noch nix funktioniert.
    Könnte mir vielleicht jemand erklären wo mein Fehler liegt?

    Hier der Code:

    [highlight=vbnet]
    Imports System.Data.OleDb
    Imports System.Threading

    Public Class Form1

    Private Shared dbpath As String = System.IO.Path.Combine(Application.StartupPath, _
    "C:\Visual Studio 2010\Projects\Lizenzformular\lizenz_test_db.mdb")
    Private Shared conn As New OleDbConnection(_
    "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & dbpath & ";")
    Private sql As String = "SELECT * FROM Lizenz;"
    Private cmd As New OleDbCommand(sql, conn)
    Private da As New OleDbDataAdapter(cmd)
    Private ds As New DataSet



    Private Sub Load_Table() Handles MyBase.Load


    Try
    'Verbindung zur Datenbank öffnen
    conn.Open()
    'Inhalte des Dataset zunächst löschen
    ds.Clear()
    'Dataset mit der Tabelle Users füllen
    da.Fill(ds, "Lizenz")
    da.Fill(ds, sql)
    'Datagrid anbinden
    DataGridView1.DataSource = ds.Tables("Lizenz")
    'Combobox anbinden

    Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
    Dim dt2 As DataTable = ds.Tables("Lizenz")

    Catch ex As OleDbException
    MessageBox.Show(ex.Message, "Fehler", _
    MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    Finally
    'Verbindung zur Datenbank auf jeden Fall wieder schließen
    conn.Close()
    End Try
    End Sub


    Private Sub Zählen()
    '
    Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
    Dim rZahl As New System.Random
    Dim rZahl1 As New System.Random
    Dim rZahl2 As New System.Random
    Dim rZahl3 As New System.Random
    Dim rZahl4 As New System.Random
    Dim rZahl5 As New System.Random
    Dim rZahl6 As New System.Random
    Dim row2 As DataRow
    Dim dt As DataTable = ds.Tables("Lizenz")
    Dim control As Integer
    Dim zahl As Integer
    Dim strUser As Integer, strNr As Integer, strVar As Integer, _
    strZahl As Integer, strFrei As Integer
    Try

    'Im DataSet einen neuen Datensatz hinzufügen
    'Der Tabelle eine neue DataRow hinzufügen

    For i As Integer = 1 To 10000

    Dim row As DataRow = ds.Tables("Lizenz").NewRow

    'Werte übergeben KNr

    Do
    strUser = rZahl.Next(500000, 1500000)
    For Each row2 In dt.Rows
    If row2!KNr = strUser Then
    control = 1
    Exit For
    End If
    Next
    If Not control = 1 Then
    row("KNr") = strUser
    Exit Do
    End If

    Loop

    'Werte übergeben ProgrammNr

    strNr = rZahl2.Next(0, 3)
    row("ProgrammNr") = strNr

    'Werte übergeben ProgrammVariante

    strVar = rZahl3.Next(0, 5)
    row("ProgrammVariante") = strVar

    'Werte übergeben Programm

    zahl = rZahl4.Next(0, 4)
    Select Case (zahl)
    Case 0
    row("Programm") = "CC 1"
    Case 1
    row("Programm") = "CC 2"
    Case 2
    row("Programm") = "CC 3"
    Case 3
    row("Programm") = "CC 4"
    End Select

    'Werte übergeben Prüfzahl

    strZahl = rZahl5.Next(0, 10000000)
    row("Prüfzahl") = strZahl

    'Werte übergeben Freigabe

    strFrei = rZahl6.Next(0, 10000000)
    row("Freigabe") = strFrei


    ds.Tables("Lizenz").Rows.Add(row)

    'Datenbank updaten
    da.Update(ds, "Lizenz")
    Debug.WriteLine("Datensatz " + i.ToString + "eingefügt!")
    Thread.Sleep(100)
    Next

    MessageBox.Show("Datensätze hinzugefügt!", "Neuer Datensatz", _
    MessageBoxButtons.OK, MessageBoxIcon.Information)
    Catch e As Exception
    MessageBox.Show(e.ToString)
    Finally
    conn.Close()
    End Try


    End Sub

    Private Sub Hinzufuegen_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles btnInsert.Click

    Dim Thread As New Threading.Thread(AddressOf Zählen)
    Thread.Priority = ThreadPriority.Normal
    Thread.Start()

    End Sub

    End Class
    [/highlight]
    Zuletzt editiert von Jürgen Thomas; 01.06.2010, 15:55. Reason: [code] durch [highlight=vbnet] ersetzt, das liest sich besser. Viel zu lange Zeilen umbrochen.

  • #2
    Hallo und willkommen,

    auf den ersten Blick sieht es fehlerfrei aus, aber dein Vorgehen ist ziemlich unpraktisch - gerade bei Access, das nur behauptet, ein DBMS zu sein, es aber nicht wirklich ist.

    Falsch (im Sinne eines ungeeigneten Vorgehens) ist:

    1. Die DbConnection sollte nicht ständig vorhanden sein, sondern nur bei Bedarf. Am besten ist sie in einen Using-Block zu packen, damit sie automatisch nach Benutzung aufgelöst wird.

    2. DbDataAdapter.Update sollte keinesfalls für jede einzelne Zeile ausgeführt werden. Jedesmal wird die Verbindung geöffnet; alle Zeilen werden geprüft, was zu ändern ist; die Änderungen werden an die DB geschickt; die Verbindung wird geschlossen. Richtig ist, dass eine Menge von Datensätzen "am Stück" zu verarbeiten ist.

    Du solltest also die Programmstruktur ändern: zuerst eine Menge von Zeilen erzeugen, dann eine Menge speichern (auch wenn das deine Überlegung zum Geschwindigkeitstest beeinträchtigt). Das Auslagern in einen eigenen Thread sorgt nur dafür, dass du im Formular weiterarbeiten kannst, hat aber keine Auswirkung auf die Geschwindigkeit (allenfalls negativ, aber das ist zu vernachlässigen).

    Hinzu kommt:
    3. Eine Random-Instanz genügt, die kannst du mehrfach benutzen.
    4. Benutze Code mit Zeilenumbruch; lange Zeilen lesen sich schlecht.
    5. Was nicht zum Problem gehört, muss nicht zitiert werden (z.B. das Einlesen der Daten, eigentlich auch das Erstellen der einzelnen Zeilen).

    Gruß Jürgen

    // Nachtrag
    Wenn ich nicht bei der "Schönheitsoperation" in deinem Beitrag etwas kaputt gemacht habe (bitte überprüfen), dann ist bei dbpath etwas überflüssig. Du kombinierst einen vollständigen Pfad mit einem vollständigen Pfad+Dateinamen. Siehe SDK-Doku/MSDN/Hilfe:
    If path2 contains an absolute path, this method returns path2.
    Zuletzt editiert von Jürgen Thomas; 01.06.2010, 15:59.

    Comment


    • #3
      Ja, wie gesagt hab viel hin und her pobiert deshalb is vielleicht etwas ein bischen überflüssiges hängengeblieben im Code.
      Hatte vorher auch nur eine Random Instanz hab dann aber mehrere angelegt, weil ich dachte das er eventuell Schwierigkeiten bekommt bei so vielen Schleifendurchläufen mit dem ständigen neuen Aufrufen von der gleichen Instanz.

      Die Kommentare sind nur für jemand anders bestimmt, hab sie jetzt nicht alle extra rausgenommen.

      Ich verstehe im Prinzip was du meinst, aber bei der Umsetzung hackt es noch.
      Könntest du mir vielleicht ein kleines Beispiel schreiben wie das aussehen könnte, wenn es nich zu viel Zeit kostet?

      Comment


      • #4
        Originally posted by hebel View Post
        Könntest du mir vielleicht ein kleines Beispiel schreiben wie das aussehen könnte, wenn es nich zu viel Zeit kostet?
        Nö, das solltest du selbst umsetzen können. Ich dachte es etwa so:
        Code:
        For i1 = 0 to 10000 Step 1000
           For i2 = 0 to 1000
              neue Zeile anlegen
           Next i2
           adapter.Update
        Next i1
        Zu den Ergänzungen mit Connection und Using benutze die Forumssuche (aber nicht nur nach OledbConnection suchen, sondern auch nach SqlConnection und DbConnection).

        Jürgen

        Comment


        • #5
          Da überschätzt du mich ganz gewaltig wenn du sagst ich sollte das allein umsetzen können.
          Das Problem ist ich krieg das nicht gelehrt und soll mich da auch nich so gross mit beschäftigen, sondern nur den geraden Weg zum Ziel nehmen, also nur das aller nötigste nachschauen damit es nicht zu lange dauert.
          Sagt der Cheffe, und der is ziemlich ungeduldig.
          Das man Step noch hinten anfügen kann wusste ich noch nich mal.

          Aber trotzdem vielen Dank, hab jetzt zumindest das kapiert was du willst.

          Comment


          • #6
            OK, wenn das so ist, gebe ich dir zum Selbstlernen noch ein paar Hinweise:
            * openbook visualbasic
            * [wikibooks] Visual Basic .NET
            Ich weiß, dass ein Chef sehr ungeduldig ist (ich war fast immer in meinem Berufsleben selbständig und dabei selbst Chef). Aber wenn man nicht richtig lernen darf, wird man die Arbeit niemals so gut, fehlerfrei und zügig erledigen können, wie es angebracht ist.

            Trotzdem viel Erfolg! Jürgen

            PS. Ich selbst kann kein VB, sondern arbeite mit C# und habe nur nebenbei etwas über VB erfahren. Wenn ich dadurch so einen Tipp geben kann wie mit Step, freut es mich.

            Comment

            Working...
            X