Datatable in MySQL Table kopieren

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

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von ronin269.

    Datatable in MySQL Table kopieren

    Hallo an alle,

    ich bin totaler Anfänger und komme nicht weiter und finde keinen richtigen Ansatz.

    Ich habe aus einer FIrebirddatenbank mir ein typisiertes Dataset mit einer Datatable erstellt. Diese Datetable möchte ich in eine MySQL Datenbank Tabelle kopieren. Beide Tabellen sind gleich aufgebaut. Es sind 82 Spalten, das macht ein Insert mit Spalten relativ aufwendig.

    Ich wollte SQLBULKCopy benutzen, das gibt es aber in MySQL nicht.

    Hat jemand eine Idee?

    Ronin269
    Hallo ErfinderDesRades,

    ich habe hier ein Buch Datenbank Programmierung mit VB 2008. Da werde ich mich mal einlesen. Ich denke das Insert bekomme ich hin. ich bin mir nur noch nicht sicher wie ich das Dataset Zeile für Zeile übertrage. Ich glaube der Primärindex der Ausgangstabelle ist nicht fortlaufend.

    ronin269 schrieb:

    Primärindex der Ausgangstabelle ist nicht fortlaufend.
    das ist kein Probem.
    Problematisch sind eher Datenbank-Bücher.

    Also ich hab die im Verdacht, dass die immer den Ansatz ohne typisiertes Datenmodell propagieren, und das wird die reinste Grotte.

    Vom Prinzip her musst du nur mit einem CommandBuilder einen DataAdapter erstellen zur MySql-Db.
    Der DataAdapter kann die DataTable dann mit einem Befehl updaten - vorrausgesetzt, die Tabellen sind wirklich absolut identisch strukturiert.

    Mehr Hirnschmalz muss man investieren, wenn die Ziel-Tabelle nicht leer ist, oder sogar Datensätze mit identischem Primkey enthält.

    Aber du willst wirklich nur rüber-kopieren?
    Das geht wie gesagt mit DataAdapter+CommandBuilder. Zuvor müssen die Datensätze aber auch auf RowStage.Added gesetzt werden, sonst erkennt der DataAdapter nicht, dass er das Insert-Command anwenden soll.

    Kannst du überhaupt schon das typDataset auf der FIrebirddatenbank befüllen?
    Das Dataset ist befüllt mit einer

    Quellcode

    1. "Select * from LIEFER"

    Anweisung.

    Das typisierte Dateset ist vorhanden, habe es auch auf 31 Spalten reduzieren können. Name ist LIEFERTableAdapter.

    Mein Versuch das Dataset zu füllen, geht aber schief

    Quellcode

    1. Sub Datenerneuern()
    2. conmy = Verbindungmy()
    3. Dim selcmd As New MySqlCommand("select * from LIEFER where LIEFERNR between '70000' and '79999'", conmy)
    4. Dim da As New MySqlDataAdapter(selcmd)
    5. Dim ds As New DataSet1
    6. Try
    7. conmy.Open()
    8. selcmd.ExecuteNonQuery()
    9. da.Fill(ds, "Liefer1")
    10. conmy.Close()
    11. Form3.dgv2.DataSource = ds
    12. Form3.dgv2.DataMember = "Liefer1"
    13. Form3.Show()
    14. Catch ex As Exception
    15. MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    16. End Try
    17. Verbindung:
    18. Function Verbindungmy() As MySqlConnection
    19. Dim conn As New MySqlConnection
    20. Dim myConnectionString As String
    21. myConnectionString = "server=192.168.***.***;uid=*************;pwd=***********c;database=**********"
    22. conn.ConnectionString = myConnectionString
    23. Try
    24. conn.Open()
    25. conn.Close()
    26. Catch ex As Exception
    27. MessageBox.Show(ex.Message)
    28. End Try
    29. Return conn
    30. End Function


    Fehlermeldung: Connection must be valid and open.


    Da gehen die Probleme los.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ronin269“ ()

    Habe es hinbekommen, habe 2 gefüllte Datatable´s "Liefer" aus Firebird und "Liefer1" aus Mysql.

    Wie bekomme ich jetzt die Daten von Liefer in die Liefer1? Mein Code bis hierhin:
    Module:

    Quellcode

    1. Imports FirebirdSql.Data.FirebirdClient
    2. Imports MySql
    3. Imports MySql.Data
    4. Imports MySql.Data.MySqlClient
    5. Module Moduleueberw
    6. Public con As FbConnection
    7. Public conmy As MySqlConnection
    8. Public cs As FbConnectionStringBuilder
    9. Private dt As DataTable
    10. Public server As Boolean
    11. Function Verbindung() As FbConnection
    12. cs = New FbConnectionStringBuilder
    13. cs.Database = "****"
    14. cs.ServerType = FbServerType.Default
    15. cs.UserID = "SYSDBA"
    16. cs.Password = "masterkey"
    17. cs.Charset = "WIN1252"
    18. cs.Dialect = "1"
    19. cs.ClientLibrary = "***"
    20. con = New FbConnection(cs.ToString)
    21. Return con
    22. End Function
    23. Sub Lieferabr()
    24. con = Verbindung()
    25. Dim sql As String
    26. sql = "select * from liefer where IBANNR <> ''"
    27. Dim dataset1 As New DataSet
    28. Dim da As FbDataAdapter = New FbDataAdapter(sql, con)
    29. Try
    30. con.Open()
    31. da.Fill(dataset1, "Liefer")
    32. Catch x As Exception
    33. MessageBox.Show(x.Message)
    34. End Try
    35. Form2.dgv1.DataSource = dataset1
    36. Form2.dgv1.DataMember = "Liefer"
    37. Form2.Show()
    38. con.Close()
    39. End Sub
    40. End Module


    Programm Form1

    Quellcode

    1. Imports MySql.Data.MySqlClient
    2. Public Class Form1
    3. Dim conmy As MySqlConnection
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Lieferabr()
    6. conmy = New MySqlConnection()
    7. conmy.ConnectionString = "***;"
    8. Dim selcmd As New MySqlCommand("select * from LIEFER where LIEFERNR between '70000' and '79999'", conmy)
    9. Dim da As New MySqlDataAdapter(selcmd)
    10. Dim ds As New DataSet1
    11. Try
    12. conmy.Open()
    13. selcmd.ExecuteNonQuery()
    14. da.Fill(ds, "Liefer1")
    15. conmy.Close()
    16. Form3.dgv2.DataSource = ds
    17. Form3.dgv2.DataMember = "Liefer1"
    18. Form3.Show()
    19. Catch ex As MySql.Data.MySqlClient.MySqlException
    20. MessageBox.Show(ex.Message)
    21. End Try
    22. conmy.Close()
    23. End Sub
    24. End Class

    ronin269 schrieb:

    Habe es hinbekommen, habe 2 gefüllte Datatable´s "Liefer" aus Firebird und "Liefer1" aus Mysql.

    Wie bekomme ich jetzt die Daten von Liefer in die Liefer1?
    Das ist evtl. problematisch.
    Weil Liefer und Liefer1 können ja Datensätze mit identischem Primkey enthalten - was soll in solchen Fällen passieren?
    Nochmals Danke für deine Hilfe!

    Ich würde sogar liefer1 teilweise löschen (innerhalb eines bestimmten Bereiches) und dann den gelöschten Bereich aus Liefer wieder hinzufügen!

    LIEFER darf nicht geändert werden. Liefer enthält die Daten einer Lieferantendatenbank, welche in einer Firma gepflegt wird.

    Ich möchte ein Programm schreiben, welches diese Daten verwendet. Zusätzlich möchte ich aber in Liefer1 eigene Einträge erfassen. Dies würde ich über einen eigenen Nummernbereich lösen.

    Der Plan war:

    1. 2 Datatable erstellen und Füllen (Liefer und Liefer1) - erledigt ;)
    2. Liefer1 Bereich der erneuert werden soll löschen
    3. Kopieren Liefer zu Liefer1
    Ich versteh die Frage nicht - was meinst du mit "damit"?

    Die beiden Methoden, die ich dir genannt habe?
    Aber ich hab doch gesagt, was sie machen: die eine löscht eine Datarow, und die andere fügt eine Datarow hinzu.

    Beides - DataRow löschen oder DataRows hinzufügen kann logischerweise nur eine DataTable betreffen.

    Weil Weder ein Datagridview noch eine Datenbank enthält DataRows.
    Alles klar, für mich war es nicht eindeutig, weil ich nicht wusste, dass eine Datarow nur in der DataTable gibt. Wie heißen dann die Zeilen in der Datenbank oder Datagridview?

    Ich werde mich morgen abend mal ran setzen und probieren im DataTable Liefer1 die nicht benötigten Zeilen löschen und aus DataTable liefer wieder in die liefer1 einfügen. Und danach in die Datenbank schreiben.

    Ich hoffe, daß ist der korrekte Weg.

    Kann ich beim Schreiben in die Datenbank dann update verwenden?
    Ja, so geht das.

    Betrachte die ADO-Architektur als 3 strikt getrennte Welten, mit klar definierten Verknüpfungen:
    1) die Datenbank: da ist das Datenmodell in einer wirklich ganz anderen Welt gespeichert, nämlich in Sql
    2) das typisierte Dataset: da ist das Datenmodell in vb.net gespeichert, und darin können wir per Code Daten manipulieren
    3) die Oberfläche: da werden Daten präsentiert, per Databinding. Niemals codeseitig an Controls rumfummeln, um Daten zu manipulieren! Zum Daten-Manipulieren ist das typDataset da.


    Jetzt noch die Verknüpfungen:
    1) DataAdapter: Verknüpfung zw. typDataset-DataTables und Datenbank-Tabellen
    2) Databinding: Verknüpfung zw. typDataset und Oberfläche

    Datenverarbeitung ist zu 95% Konfiguration, also es werden Controls angelegt, Databindings gesetzt, es werden mit Assistenten DataAdapter generiert - feddich.

    Zur Laufzeit sind oft nur noch in 2 Button-Klicks die DataAdapter anzustupsen, zum laden oder rückspeichern.

    Also wenn du schon fragst, wie die Zeilen im Datagridview heissen, denkst du schon inne falsche Richtung, weil mit diesen Zeilen hast du nix zu tun - ebensowenig wie mit den Zeilen inne DB.
    Der Datentyp der DGV-Zeilen ist übrigens DataGridviewRow, und die Zeilen inne Db haben ja gar keinen Datentyp, der sich in vb.net ausdrücken liesse. Das sind halt Datensätze, und manipuliert werden sie -wenn überhaupt - mit Sql.

    Aber in deim Fall gibts ja erst noch gar keine Oberfläche, und das mergen der DataTables ist mal doch ein bischen Datenverarbeitung, gehört also zu den 5% "richtiger" Datenverarbeitung, wo Code wirklich was tut mit die Daten.
    habe doch schon eher Zeit gehabt,

    Quellcode

    1. For Each DR In DT.Rows
    2. DT1.LoadDataRow(DR.ItemArray, System.Data.LoadOption.Upsert)
    3. Next
    4. da.Update(ds, "Liefer1")


    DR, DT ist Liefer Tabelle aus Firebird (original)
    DR1, DT1 ist Liefer1 in MySQL (Kopie)

    Es klappt bis jetzt:

    1. Beide Datasets abrufen und in Liefer und Liefer1 ablegen
    2. Löschen des Inhaltes aus Liefer1 (bestimmter Bereich)
    3. Update der Datenbank
    4. Kopieren der Daten von DT zu DT1 (siehe Code oben)

    Jetzt kommt es zu einem Fehler:

    5. Schreiben der Änderungen mit Update

    Fehlermeldung:
    Für ein Update ist ein gültiger InsertCommand erforderlich, wenn eine DataRow-Auflistung mit neuen Zeilen weitergegeben wird.


    Insert von TableAdapter zeigt folgendes an:

    INSERT INTO LIEFER
    (ADRESSNR, LIEFERNR, ADRESSGRP, BRANCHE, SUCHNAME, NAME1, NAME2, NAME3, STRASSE, LAND, PLZ, ORT, PROVINZ, ISOA2LAND, PLZPFACH, POSTFACH, TELEFAX, TELEFON, EMAIL, HANDY,
    HOMEPAGE, FIBUKTO, USTIDNR, STEUERNR, BEMERK1, BEMERK2, BANK, BLZ, KONTONR, KTOINHABER, IBANNR, SPRACHE, BESTELLSP, KREDLIMIT, RABATT, ZAHLZIEL, SKTOPROZ1, SKTOPROZ2,
    SKTOTAGE1, SKTOTAGE2, NETTOTAGE, VERSNDART, WARNFEN, WARNFENTXT, ZAHLART, SELEKTION, KUNDENNR, VERBUND, SAMMKTO, SAMMELKTO, KZADRART, LIEFERADR, ISOWAEHR, KZNETTO,
    STEUERBER, MINDBEST, HAUPTADR, STEUERSCHL, SWIFT, AZVAKTIV, UPSKDNR, ISVERKEHR, ISARTGESCH, KZKERN, ANLAGE, ADRUUID, CREATEBED, CREATEDATUM, AENDBED, AENDDATUM,
    OFFLINEDAT, OFFFILIALE, ANREDE, DOCTITEL, ANSCHRIFTZUSATZ, UPDFLAG, STATUS, FILIALE, VERTRNR, AZVKOSTEN)
    VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26, @p27, @p28, @p29, @p30, @p31,
    @p32, @p33, @p34, @p35, @p36, @p37, @p38, @p39, @p40, @p41, @p42, @p43, @p44, @p45, @p46, @p47, @p48, @p49, @p50, @p51, @p52, @p53, @p54, @p55, @p56, @p57, @p58, @p59, @p60,
    @p61, @p62, @p63, @p64, @p65, @p66, @p67, @p68, @p69, @p70, @p71, @p72, @p73, @p74, @p75, @p76, @p77, @p78, @p79, @p80)


    Wo kann ist der Fehler? Insert Command ist doch da und ich denke auch korrekt!