MySQL neuen Datensatz anlegen und zum Bearbeiten anzeigen

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von INOPIAE.

    MySQL neuen Datensatz anlegen und zum Bearbeiten anzeigen

    Es werden in folgender Art beim Laden des Form Daten aus einer MySQL Tabelle abgerufen und in Textboxen übernommen:

    [code=vbnet]cmd.CommandText = "select*from a"

    reader = cmd.ExecuteReader()
    Do While reader.Read()
    TextBox1.Text = reader("ID_a")
    TextBox2.Text = reader("Art_des_DS")
    TextBox3.Text = reader("Plz")
    TextBox4.Text = reader("Ort")
    TextBox5.Text = reader("Strasse")
    TextBox6.Text = reader("Hausnr")[/code]

    Beim Ereignis wird ein neuer Datensatz in der Tabelle a angelegt:

    [code=vbnet] 'legt neuen Datensatz in Tabelle a an

    Try
    cmd.CommandText = String.Format("Insert a set plz='00000'")
    cmd.ExecuteNonQuery()
    MsgBox("Es wurde ein neuer Datensatz angelegt")
    Catch ex As Exception
    MsgBox(ex.Message)
    End Try[/code]

    Die Bearbeitung eines vorhandenen DS realisiere ich z.zt. folgendermaßen:

    [code=vbnet]cmd.CommandText = String.Format("UPDATE a SET Art_des_DS = '{0}'", Me.TextBox2.Text)
    cmd.ExecuteNonQuery()[/code]

    [b]Aufgabe[/b]:

    Dieser neu angelegte Datensatz soll geöffnet werden um ihn zu bearbeiten. In meinen Worten klingt das folgendermaßen:

    "Aktualisere das bereits geöffnete Form, zeige den zuletzt angelegten Datensatz an"

    Wie geht das mit SQL bzw. vb?
    Wie muß der ComandText aussehen?
    Ich weiß nicht genau wo das Problem liegt, ich denke du willst wissen wie du den letzten Datensatz auslesen kannst und in die Textboxen einfügen kannst. Dafür ließt du einfach die Datenbank so lange aus bis die Do While reader.Read() schleife aufhört. Dann hast du den letzten Datensatz.

    Oder habe ich dich falsch verstanden?
    Hoffenlich verstehen wir uns nicht falsch.

    In der Datenbank befindet sich eine Tabelle mit Spalten. TextBox1 bis 6 sind ein zusammengehörender Datensatz.

    [quote]Dafür ließt du einfach die Datenbank so lange aus bis die Do While reader.Read() schleife aufhört. Dann hast du den letzten Datensatz.
    [/quote]

    Und wie geht das? Ich dachte es reicht wenn ich die Abfrage einfach nach dem Anlegen des neuen Datesatzes wiederhole und dabei die Bedingung "zeige den zuletzt angelegten Datensatz" ergänze.

    Wie könnte die Anweisung return@@identity funktionieren?
    Dafür hast du eine ID(Bei anscheinend ID_a)
    "SELECT S1,S2,S3,S4,S5,S6 FROM tabelle1 WHERE ID = 1" gibt nur einen (oder keinen, wenn die Bedingung nicht zutrifft) Datensatz her. Und zwar den, mit der eindeutigen ID: 1

    //EDIT: Das da oben ist ein Schmarrn mit dem reader.Read und die Textboxen jedesmal füllen, bis zum letzten Datensatz.

    Fehler/Probleme die dabei entstehen:
    Wie schon so gut bemerkt, wird bei 5000 Datensätzen 5000 mal in den Textboxen geschrieben. -> Geht garnicht.
    Wer sagt, dass der zuletzt hinzugefügte Datensatz auch am Ende steht? (ORDER)
    Ressourcenverschwendung.
    Unnötige Schleifen.
    Performance.
    Keine OOP Struktur

    //EDIT2: Das könnte noch interessant für dich sein:
    forums.mysql.com/read.php?20,125996,125998#msg-125998
    "Wenn jemand in einem Betrieb unverzichtbar ist, dann ist dieser Betrieb falsch organisiert." - Roberto Niederer

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

    Milaim hat ja schon viele richtige Kritikpunkte gebracht.

    Das sequentielle Durchlaufen ist wirklich der schlechtest mögliche Ansatz, ohne jemanden zu beleidigen :D
    Aber ich sehe sowas leider auch auf der Arbeit oft. (Da heisst es dann Cursor und sollte das letzte Mittel sein)

    Das widerspircht ja auch total dem mengenorientierten Ansatz der relationalen Datenbankwelt.

    Wenn du weißt, daß du oft den letzten DS brauchst, dann nimm lieber ne auto increment Spalte und suche direkt nach dem letzten mit

    Quellcode

    1. WHERE inc_Spalte = MAX(inc_Spalte)
    Mensch ist das eine einfache Lösung. Der vollständigkeit halber hier noch einmal mein code:

    'Abfrage: letzten Datensatz der Tabelle a anzeigen lassen
    cmd.CommandText = "select*from a order by 'id_a' desc"

    'Abfrage:bestimmten Datensatz der Tabelle a anzeigen lassen:
    cmd.CommandText = "select*from a where ID_a =1"

    'Abfrage:ersten Datensatz der Tabelle a anzeigen lassen:
    ?

    Kannst Du mir auch die letzte Abfrage beantworten?

    Mit freundlichem Gruß
    Thomas

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thomas2705“ () aus folgendem Grund: Nachtrag: 'Abfrage: maximalen Datensatz "ID_a aus tabelle a anzeigen lassen cmd.CommandText = "select*from a WHERE ID_a = MAX(ID_a)" geht leider nicht.? ID_a ist das Primärschlüsselfeld und Autoincrement

    "SELECT TOP 1 * FROM tabelle1 ORDER BY ID_a ASC"
    //Edit: natürlich nur wenn eine fortlaufende Logik dahinter steckt.
    "Wenn jemand in einem Betrieb unverzichtbar ist, dann ist dieser Betrieb falsch organisiert." - Roberto Niederer
    Geht es um die ID, die direkt nach dem Speichern des neuen Datensatzes zurückgegeben werden soll, wird direkt nach dem Insert der folgende Befehl genutzt:

    VB.NET-Quellcode

    1. sqlstr = "Select @@identity From Tabelle"
    2. sqlcmd = New SqlCommand(sqlstr, Connection)
    3. Wert= sqlcmd.ExecuteScalar
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Ich nutze jetzt folgenden Code:

    [code=vbnet]

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Try
    cmd.CommandText = String.Format("Insert a set plz='00000'")
    cmd.ExecuteNonQuery()

    cmd.CommandText = "select * FROM a ORDER BY ID_a ASC"

    reader = cmd.ExecuteReader()

    Do While reader.Read()
    TextBox1.Text = reader("ID_a")
    TextBox2.Text = reader("Art_des_DS")
    TextBox3.Text = reader("Plz")
    TextBox4.Text = reader("Ort")
    TextBox5.Text = reader("Strasse")
    TextBox6.Text = reader("Hausnr")
    Loop
    reader.Close()

    Catch ex As MySql.Data.MySqlClient.MySqlException
    MsgBox(ex.Message)
    End Try

    MsgBox("Es wurde ein neuer Datensatz angelegt")

    End Sub

    [/code]

    Beim einmaligen ausführen funktioniert das Ganze recht gut. Beim zweiten Ausführen ohne das Form zwischendurch zu schließen wird mir folgender Fehler angezeigt:

    "Connection must be valid an open"

    cmd.ExecuteNonQuery() ist dabe als Fehler markiert. Was mache ich falsch?

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

    Zu deiner Frage:
    Wo steht denn ein connection.open in Deinem Code? Wenn die Verbindung geschlossen wird, kann Sie nicht genutzt werden.
    Des Weiteren musst Du mit deinem Code ja immer noch die 5000 Datensätze durchlaufen. Du solltest in dem SQL-Befehl einen Filter setzen siehe hierzu den ersten Code von Miliam
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Hallo

    connection open steht beim laden des Form. con.close befindet sich beim schließen des Form.
    Die Verbindung ist beim Anlegen des DS noch offen. Erst bei "cmd.ExecuteNonQuery()" schließt sie sich offensichtlich.

    Ich habe jetzt folgende Lösung:

    [code=vbnet] Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Try
    cmd.CommandText = String.Format("Insert a set plz='00000'")
    cmd.ExecuteNonQuery()

    MsgBox("Es wurde ein neuer Datensatz angelegt")

    con.Open()

    cmd.CommandText = "select * FROM a ORDER BY ID_a ASC"

    reader = cmd.ExecuteReader()

    Do While reader.Read()
    TextBox1.Text = reader("ID_a")
    TextBox2.Text = reader("Art_des_DS")
    TextBox3.Text = reader("Plz")
    TextBox4.Text = reader("Ort")
    TextBox5.Text = reader("Strasse")
    TextBox6.Text = reader("Hausnr")
    Loop

    reader.Close()

    Catch ex As Exception
    MsgBox(ex.Message)
    End Try

    End Sub[/code]

    Nach dem Anlegen des neuen Datensatzes öffne ich die Verbindung jetzt noch einmal (con.open). Danach wird mir der zuletzt angelegte Datensatz angezeigt. Ich nehme an "Order By ASC" ist dafür die richtige Anweisung. Ich habe nicht vor tausende Datensätze durchlaufen zu lassen.

    Gibt es eine bessere Lösung?

    Thomas2705 schrieb:

    Ich nehme an "Order By ASC" ist dafür die richtige Anweisung.

    Falsch damit sortierst Du die Werte aufsteigend. Fürs absteigende musst Du DESC verwenden.

    Eigentlich verwendet man den SQL-Befehl "SELECT @@Identity FROM Tabelle", um nach dem Erstellen eines neuen Datensatzes dessen ID-Wert zu erhalten.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Ersten: Zeig mal etwas mehr Code. Eigentlich muss er dass machen. Siehe auch support.microsoft.com/kb/815629
    oder [Allgemein] Auslesen des neuen Wertes der Schlüsselspalte nach dem Erstellen eines neuen Datensatzes mit @@Identity

    Zweitens: Bitte benutze doch die richtigen VB-Tags für den Code.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

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

    Mehr Code:

    a ist die Tabelle
    Id_a ist Primärschlüsselfeld
    [u]Nachtrag[/u]: MySQL Datenbank

    [code=vbnet] 'legt neuen Datensatz in Tabelle a an

    Try
    cmd.CommandText = String.Format("Insert a set name_der_firma ='Name der Firma'")

    cmd.ExecuteNonQuery()

    MsgBox("Es wurde ein neuer Datensatz angelegt. Bitte überarbeiten Sie die Werte!")

    cmd.CommandText = "SELECT @@Identity FROM a"


    reader = cmd.ExecuteReader()

    Do While reader.Read()
    TextBox1.Text = reader("ID_a")
    TextBox2.Text = reader("Name_der_Firma")
    TextBox3.Text = reader("Branche")
    TextBox4.Text = reader("Unternehmensform")
    Loop

    reader.Close()

    Catch ex As Exception
    MsgBox(ex.Message)
    End Try[/code]