Inhalt eines DataGridView in einer Datenbank speichern

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von HerrFrie.

    Inhalt eines DataGridView in einer Datenbank speichern

    Hallo,

    ich arbeite zur Zeit mit Visual Studio VB 2010 und habe ein DateGridView mit Daten gefüllt und möchte diese in eine Datenbank speichern mit dem SQL Insert Statement.
    Habe leider noch nichts dazu im Forum gefunden, was mir dazu weiterhilft.
    Ich dachte an einer for each Schleife:

    VB.NET-Quellcode

    1. For each [...Füge aus dem DGV jede Zeile in die Datenbank ein.. Next
    2. Connection.close()


    Ich bekomm es jedoch leider nicht hin, dass das Programm Eine Zeile nach der anderen, in die Datenbank schreibt.

    Es klappt mit einem Datensatz, wobei der Wert in einer Variable schon geschrieben wird und nicht aus dem DGV ausgelesen wird:

    VB.NET-Quellcode

    1. 'Neuen Datensatz, SQL Statement (TEST INSERT!):
    2. Dim StrSQLDatensatzEinfügen As String
    3. StrSQLDatensatzEinfügen = "INSERT INTO test VALUES('hallo','ok')"
    4. 'Verbindung öffnen
    5. OleDbConnectionSchreiben.Open()
    6. 'OleDb Commands
    7. Dim OleDbCommandDateierzeugen As New OleDbCommand(StrSQLNeueTabelle, OleDbConnectionSchreiben)
    8. Dim OleDbCommandDatensatzEinfügen As New OleDbCommand(StrSQLDatensatzEinfügen, OleDbConnectionSchreiben)
    9. OleDbCommandDateierzeugen.ExecuteNonQuery()
    10. 'Datensatz in die Tabelle schreiben
    11. OleDbCommandDatensatzEinfügen.CommandText = StrSQLDatensatzEinfügen
    12. OleDbCommandDatensatzEinfügen.ExecuteNonQuery()
    13. 'Verbindung beenden
    14. OleDbConnectionSchreiben.Close()


    Hat jemand ein Ratschlag und könnte mir helfen?


    Ich bedanke mich schonmal für s durchlesen.
    Hallo,

    Die "richtigen" Daten die zu übernehmen sind, sind bereits in einem DataTable enthalten und werden in einem DataGridView angezeigt.

    Ich bin nun gerade dabei das Tabellenschema zu kopieren und in der neuen Datenbankdatei einzufügen.

    Und Dabei häng ich gerade fest, Da VB die Datentypen zwar ausliest, die Typen sind jedoch in VB und nicht gleich wie in SQL. zB String (vb )und Text, char etc (sql).

    Kennt jemand ein "einfaches" Beispiel um das komplette Tabellstrukturschema in eine neue zu kopieren?
    Die Spaltenüberschriften lassen sich wie folgt auslesen und in einer neuen später einfügen:

    VB.NET-Quellcode

    1. 'Schleife um alle Anzahl der Columns aus dem Datatable auszulesen und anschließend in der neuen Datei zu schreiben:
    2. For i = 1 To columns
    3. StrSQLDatensatzEinfügen = "ALTER TABLE test ADD " + DataTable.Columns(i).ColumnName + " " + Datentyp
    4. 'SQL Befehl ausführen
    5. OleDbCommandDatensatzEinfügen.CommandText = StrSQLDatensatzEinfügen
    6. OleDbCommandDatensatzEinfügen.ExecuteNonQuery()
    7. Next


    Wie übernehme ich jedoch die Datentypen?
    Moin,

    um die Sachen in eine NEUE Datenbank zu übernehmen mußt du diese NEUE Datenbank erst einmal erstellen. Dieses Erstellen geht aber dann nicht über einen SQL Command, sondern über ADOX Befehle bei einer Acceess Datenbank.
    Hier mal als Beispiel eine Routine, womit ich eine kleine Tabelle erstellt habe.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub DBErstellen()
    2. Dim Catalog As ADOX.Catalog = New ADOX.Catalog()
    3. Dim Connn As ADODB.Connection = New ADODB.Connection()
    4. Dim table As ADOX.Table = New ADOX.Table()
    5. Dim Column As ADOX.Column
    6. Dim Index As ADOX.Index
    7. '
    8. Connn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Datenbank & ";"
    9. Catalog.Create("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Datenbank & ";Jet OLEDB:Engine Type=5")
    10. '
    11. Connn.Open(Nothing, Nothing, Nothing, 0)
    12. Catalog.ActiveConnection = Connn
    13. table.Name = "Rezepte"
    14. 'Primary Key Spalte erstellen
    15. Column = New ADOX.Column()
    16. With Column
    17. .ParentCatalog = Catalog
    18. .Name = "RezeptID"
    19. .Type = ADOX.DataTypeEnum.adInteger ' 3
    20. .Properties("Nullable").Value = False
    21. .Properties("Jet OLEDB:Allow Zero Length").Value = False
    22. .Properties("AutoIncrement").Value = True
    23. End With
    24. table.Columns.Append(Column, , )
    25. Index = New ADOX.Index()
    26. Index.Name = "PrimaryKey"
    27. Index.PrimaryKey = True
    28. Index.Columns.Append("RezeptID", table.Columns("RezeptID").Type, table.Columns("RezeptID").DefinedSize)
    29. table.Indexes.Append(Index, )
    30. 'Kategorie erstellen
    31. Column = New ADOX.Column()
    32. With Column
    33. .ParentCatalog = Catalog
    34. .Name = "Kategorie"
    35. .Type = ADOX.DataTypeEnum.adVarWChar ' 202
    36. .Properties("Jet OLEDB:Allow Zero Length").Value = True
    37. End With
    38. table.Columns.Append(Column, , )
    39. 'Schleife für die 10 Mengen & Zutaten zu erstellen
    40. Dim I As Integer
    41. For I = 1 To 10
    42. 'Menge
    43. Column = New ADOX.Column()
    44. With Column
    45. .ParentCatalog = Catalog
    46. .Name = "Menge" & I
    47. .Type = ADOX.DataTypeEnum.adVarWChar ' 202
    48. .Properties("Jet OLEDB:Allow Zero Length").Value = True
    49. End With
    50. table.Columns.Append(Column, , )
    51. 'Zutat
    52. Column = New ADOX.Column()
    53. With Column
    54. .ParentCatalog = Catalog
    55. .Name = "Zutat" & I
    56. .Type = ADOX.DataTypeEnum.adVarWChar ' 202
    57. .Properties("Jet OLEDB:Allow Zero Length").Value = True
    58. End With
    59. table.Columns.Append(Column, , )
    60. Next I
    61. 'Zubereitung erstellen
    62. Column = New ADOX.Column()
    63. With Column
    64. .ParentCatalog = Catalog
    65. .Name = "Zubereitung"
    66. .Type = ADOX.DataTypeEnum.adLongVarWChar ' 203
    67. .Properties("Jet OLEDB:Allow Zero Length").Value = True
    68. End With
    69. table.Columns.Append(Column, , )
    70. 'Bild erstellen
    71. Column = New ADOX.Column()
    72. With Column
    73. .ParentCatalog = Catalog
    74. .Name = "Bild"
    75. .Type = ADOX.DataTypeEnum.adVarWChar ' 202
    76. .Properties("Jet OLEDB:Allow Zero Length").Value = True
    77. End With
    78. table.Columns.Append(Column, , )
    79. 'Die Daten in die DB schreiben
    80. Catalog.Tables.Append(table)
    81. Connn.Close()
    82. End Sub


    Wenn du eine bestehende Datenbank einfach in eine neue leere kopieren möchtest, kannst du die alten Felder auch auslesen.
    Hier wäre eine Funktion, mit der du die Daten einer Tabelle auslesen kannst und in einem DataGridView anzeigen lassen kannst. Wenn du diese Daten z.B. in einen Array einlesen läßt, kannst du eine neue Datei einfach damit schreiben.

    Aufruf der Tabellenanzeige mit Tabellenstruktur("Datenbankname","Tabellenname"). Die Datenbank muß sich im Debug Ordner dieses Programms befinden, sonst muß man den Pfad ändern. Der Datenbankname bitte ohne '.accdb'.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function TabellenStruktur(ByVal Datenbank As String, ByVal Tabellenname As String) As DataTable
    2. Dim ConStr As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" ' für Access .accdb Datenbanken
    3. Dim Con As New OleDbConnection(ConStr & Datenbank & ".accdb;") ' Adresse/Kontakt zur Datenbank
    4. Con.Open()
    5. Dim DT As DataTable = Con.GetSchema("Tables")
    6. Dim SqlCmd As OleDbCommand = Con.CreateCommand()
    7. Dim sqldr As OleDbDataReader
    8. Dim O As Integer, Test As String = ""
    9. With SqlCmd
    10. .CommandText = "Select * From " & Tabellenname
    11. .CommandType = CommandType.Text
    12. sqldr = .ExecuteReader
    13. End With
    14. DT = sqldr.GetSchemaTable
    15. DB_Felderzahl = DT.Rows.Count
    16. For O = 1 To DB_Felderzahl
    17. DB_Felder(O - 1) = DT.Rows(O - 1).Item("ColumnName")
    18. DB_Type(O - 1) = DT.Rows(O - 1).Item("ProviderType")
    19. DB_Größe(O - 1) = DT.Rows(O - 1).Item("ColumnSize")
    20. Next
    21. Con.Close()
    22. DataGridView1.DataSource = DT
    23. Return DT
    24. End Function
    Moin HerrFrie,

    danke für deine schnelle Antwort!

    Ersteinmal vielen dank!

    Eine Frage noch dazu, bevor ich das nun ausprobiere: Geht das nur mit Access Datenbanken oder auch zB mit dBase Datenbanken (dass der Connection String dementsprechend angepasst werden muss ist mir bewusst).

    Ich denke der zweite Code ist ein Schritt in die richtige Richtung, den die Tabelle kann ich bereits erstellen, jedoch kann ich aus der "alten" Tabelle die Spaltennamen nicht und Typen übernehmen und mithelfe des "GetSchemaTable" dürfte es klappen.

    Ich habe die Spaltenüberschriften bis lang immer mit dem oben genannten Code eingefügt, jedoch nicht die Datentypen.
    Mir ist allerdings noch nicht ganz klar, wenn ich die Felder nun ausgelesen habe, die Spaltennamen in der neuen Tabelle bereits reingeschrieben habe wie ich ihm die Typen mitgeben kann?

    Ich hoffe ich habe mich verständlich ausgedrückt, ansonsten bitte eben benachrichten.
    Danke!
    Hi,

    wie das mit anderen Datenbanken funktioniert kann ich dir leider nicht sagen, müßtest du probieren. Wie du schon geschrieben hast, änderst du dementsprechend den Connection String.

    Du mußt beim Erstellen der Datenbank den Spaltennamen UND den Typ angeben. Ob, bzw. wie eine Änderung nachträglich funktioniert kann ich dir leider auch nicht sagen.


    Ich benutze z.B. das Datenbank-Schema beim Erstellen meiner UPDATE, INSERT, DELETE Befehle, damit ich dort keinen Fehler machen kann. Ich lese mir die Daten der jeweiligen Tabelle ein und erstelle daraus dann automatisch die 3 Befehle der jeweiligen Tabelle.
    Wenn du eine neue Tabelle ohne Vorlage erstellen willst, mußt du halt selber wissen, welche Felder und welcher Typ das sein soll.
    Beim Erstellen einer neuen Tabelle mit Vorlage ließt du die Tabelle mit deren Typen etc. ein und schreibst diese direkt in eine neue Tabelle. Aber nicht erst Spaltennamen erstellen und nachträglich den Rest sondern alles zusammen.