SQL Insert ins Access mit Hilfe von Schleifen

  • VB.NET

Es gibt 38 Antworten in diesem Thema. Der letzte Beitrag () ist von rawneblade.

    SQL Insert ins Access mit Hilfe von Schleifen

    Hi,

    schön das es so ein Forum gibt. Ich bin neu hier und hoffe auf Hilfe eines kleinem Problems in Visual Basic. Nach einer Stunde suchen im Forum dachte ich es ist besser es direkt hier zu posten.
    Folgender Hintergrund: Ich erzeuge mit Hilfe einer Schleife neue TextBoxen, Labels und Checkboxen Aufgaben, jede Aufgabe wird mit einer Nummer identifiziert. Die Anzahl ergibt sich aus der Access Datenbank und wird per Select ausgelesen. Das klappt soweit wunderbar. Mein Problem ist wie schaffe ich es das per Schleife alle Aufgaben mit Hilfe von Insert wieder in die Datenbank geschrieben werden.
    Habe es folgenden Code probiert:

    For i = 1 To anzahl
    Try
    con.Open()
    cmd.CommandText = "INSERT INTO Abschluss (PruefungNummer, FrageNummer, C1, C2, C3, C4) VALUES ('" & TxtFreigabe1.Text & "', '" & FrageNummer.Text &
    "', '" & C1.Text & "', '" & C2.Text & "', '" & C3.Text & "', '" & C4.Text & "') "
    cmd.ExecuteNonQuery()
    MessageBox.Show("Abgeschlossen")
    Catch ex As Exception
    MessageBox.Show(ex.Message)
    con.Close()
    End Try
    Next


    Die anzahl wird durch das select bekannt. Das Problem ist das hier nur die letzte Aufgabe wieder in die Access Datenbank geschrieben wird.
    Primärschlüssel ist übrigens "FrageNummer". Kann mir jemand helfen oder einen Tipp geben?

    Danke und Gruß
    rawneblade
    Willkommen im Forum.
    Wo wird i in Deiner Schleife verwendet? Wo wird festgelegt, dass die ite Frage abgespeichert werden soll? Nirgends. Das ist das Problem. Sind die Fragen in irgendeiner List(Of Frage) abgespeichert? Oder zumindest in einem Array? Wenn sie nur in CEs wie Textboxen rumliegen, dann liegt dort das Problem. Denn sie sollten nur dort angezeigt, aber nicht abgelegt/"abgespeichert" werden.
    Schau auch mal nach den Stichwort SQL-Injection. Wenn kein anderer User als Du das Programm benutzt, dann mach ruhig. Das Sicherheitsrisiko sollte aber trotzdem ausgeräumt werden, denn irgendwann kommt doch jemand mal vorbei und probiert Blödsinn aus ...

    Außerdem: Fange nur Exceptions ab, die Du kennst und sinnvoll bearbeiten kannst.

    btw: bitte CodeTags verwenden
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed
    Was meinst du mit Array, ich will doch nur Daten in die Datenbank zurückschreiben. Wenn ich drei Fragen habe sollen die drei Fragen zurück in die Datenbank geschrieben werden. Wozu brauche ich da ein Array? SQL Injection interessiert mich erstmal weniger, da das nichts mit dem Thema zu tun hat. Das ist ja nur
    ein Sicherheits Thema.

    @frifri
    C1, C2, C3 und C4 sind die Checkboxen. Die werden angehakt.

    Also ich habe ein Programm wo man beliebig viele Aufgaben erstellt. Eine Aufgabe besteht jeweils aus einer Frage, vier Antworten und vier Checkboxen. Habe ich zum Beispiel fünf Aufgaben erstellt, werden diese in einer Form per SQL aus der Datenbank angezeigt, das funktioniert auch.
    Nun will hacke ich jeweils eine Antwort pro Frage an und danach sollen diese fünf Aufgaben zurück in die Datenbank geschrieben werden.
    Die Frage ist wie bekomme ich die 5 per Schleife rein. Die Nummer der jeweiligen Frage nutze ich als Primärschlüssel und somit ist die Anzahl der Aufgaben bekannt.
    Nutze ich da eine For Schleife?

    Gruß rawneblade
    Irgendwo musst Du ja die Fragen drinhaben. Wo sind die? In welcher Datenstruktur? Oder allgemein: Wie in Deinem Programm kannst Du quasi zu jeder Zeit auf alle Fragen zugreifen? Sobald wir die Antwort auf diese Frage wissen, können wir Dir sagen, wie Du die wieder in die DB reinbekommst.
    Zu Deiner SQL-Injection-Aussage schweige ich mich aus, da überlasse ich das Feld der Mahnungen den SQL- und DB-Experten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ok ich habe die DB Struktur mal angehangen. Ich hoffe du kannst damit was anfangen, die erste Tabelle "Frage" wird durch manuelle Eingabe der Aufgaben
    an einen anderen Ort des Quellcodes eingetragen. Von dieser Tabelle wird per Select rausgeholt. Dann hakt man einfach die jeweiligen Aufgaben an und es soll per Insert
    in die Tabelle "Abschluss" eingetragen werden.

    rawneblade schrieb:

    ich habe die DB Struktur mal angehangen
    Hab ich was verpasst? Wo hast Du die denn angehangen/gepostet?

    rawneblade schrieb:

    Habe ich zum Beispiel fünf Aufgaben erstellt, werden diese in einer Form per SQL aus der Datenbank angezeigt
    Hm ... irgendwie hab ich das Gefühl, dass das der Hinweis auf meine Fragen ist. Ist es richtig, dass Du diese Daten/Aufgaben mit ihren Fragen nur irgendwo auf dem Formular anzeigst und nirgends zwischenspeicherst? Dann müsstest Du die Fragen ja wieder aus den CEs rauspuhlen. Aber dann stellt sich immer noch meine Frage als unbeantwortet heraus: Wo stehen die Aufgaben drin? In nem DGV? In ner ListBox, ListView, ComboBox? Dass Du Deine Fragen in CheckBoxen steckst, ist mir jetzt klar. Aber in welchem CE stehen die Aufgaben? Oder wird immer nur eine Aufgabe angezeigt und wenn Du die nächste Aufgabe haben willst, musst Du eine neue SQL-Anfrage stellen?

    frifri schrieb:

    was ist denn "anzahl"für eine Variable, woher bekommst du den Wert?

    rawneblade schrieb:

    Die anzahl wird durch das select bekannt.
    -> Kommt also wohl durch eine SQL-Anfrage zu ihrem Wert.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    Dein Insert macht in jedem Schleifendurchlauf das exakt gleiche.
    Wenn du es so machen möchtest müsstest du auch das i aus deiner Schleife verwenden um deine erzeugten Controls anzusprechen.
    Also Me.Controls("TextBox" & i) zum Beispiel

    LG

    //1 zu i editiert..
    Das ist meine Signatur und sie wird wunderbar sein!

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

    @VaporiZed
    Die Fragen werden aus der DB per Select geholt und jeweils in TextBoxen geschrieben. Dort stehen sie normal als Text drin.
    Diese TextBoxen sind nicht editierbar und die vier Checkboxen pro Aufgabe kann man anhaken. Beim Insert will ich eigentlich nur
    die Frage-Nummer und die dazugehörigen Checkboxen importieren, denn die brauche ich zum späteren Vergleich. Der Text der
    Fragen und Antworten brauche ich nicht
    Bin ich blind oder kann man hier nichts anhängen?

    @Mono
    Ok ich versuche es mal auf diesen Weg.

    Mono schrieb:

    Also Me.Controls("TextBox" & 1) zum Beispiel
    Ich bin mal so frei und wage zu behaupten, dass Mono meinte

    VB.NET-Quellcode

    1. Me.Controls("TextBox" & i)
    .

    Das Hochladen von Dateien o.ä. geht über [+ Erweiterte Antwort]. Kannst Du das bitte gleich mal für nen Screenshot Deiner App benutzen? Denn ich kann mir immer noch nicht vorstellen, ob Du bei 5 Fragen 5 TextBoxen mit den Fragen und 20 CheckBoxen für die insgesamt 20 Antworten hast. Und wo wird die Fragenummer in Deinem Programm angezeigt oder in eine Variablen abgespeichert? Noch(mal?) der Hinweis: Die TextBoxen und andere CEs sind nicht zum Abspeichern der Daten, sondern nur zum Anzeigen von Daten da. Packe Deine Daten, die aus der DB kommen, in passende Datenstrukturen, dann geht das alles super einfach. Aber das scheint wohl kein angbarer Weg zu sein, denn das hatten wir ja sschon in Post#2 und #4.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Grundsätzlich hast du Recht @VaporiZed. Auf diese Themen bin ich gar nicht eingegangen weil du es eh schon gesagt hast.
    Im Normalfall lernt man sowas halt oder nicht.
    Das konkrete Problem ist auf jeden Fall das das Insert unabhängig von der Schleife ist was sicher nicht in seinem Sinne war.
    Danke für den Hinweis. War natürlich i statt 1 ;)
    Das ist meine Signatur und sie wird wunderbar sein!

    Überblick was mit SQL-Insert getan werden soll

    Ok ich glaube ich habe mich etwas falsch ausgedrückt. Im Anhang findet ihr zwei Auszüge der beiden betroffenen Tabellen. In der ersten Tabelle "Frage"
    sind die Fragen und Antworten plus Prüferungsnummer und Fragenummer enthalten. Diese werden per Select abgerufen und Anhand der zahl der Fragenummern
    als Fragen und Antworten im Programm in TextBoxen angezeigt, siehe Anhang: Ansicht

    Die Fragen und Antworten stehen in den TextBoxen nur zur Ansicht, mit denen soll nichts weiter geschehen, das einzigste was man tun kann ist die Checkboxen
    anzuhaken. Mit den Insert sollen diese dann der jeweiligen Prüfungsnummer und Fragenummer und als C1, C2, C3 und C4 in die Access Tabelle "Abschluss" importiert werden.

    Dazu versuche ich folgenden Code, leider wird immer nur die Ergebnisse der Aufgabe importiert:

    VB.NET-Quellcode

    1. If Checkbox1Neu.Checked = True Then
    2. C1.Text = "Ja"
    3. Else
    4. C1.Text = "Nein"
    5. End If
    6. If Checkbox2Neu.Checked = True Then
    7. C2.Text = "Ja"
    8. Else
    9. C2.Text = "Nein"
    10. End If
    11. If Checkbox3Neu.Checked = True Then
    12. C3.Text = "Ja"
    13. Else
    14. C3.Text = "Nein"
    15. End If
    16. If Checkbox4Neu.Checked = True Then
    17. C4.Text = "Ja"
    18. Else
    19. C4.Text = "Nein"
    20. End If
    21.  
    22. Try
    23. con.Open()
    24. cmd.CommandText = "INSERT INTO Abschluss (PruefungNummer, FrageNummer, C1, C2, C3, C4) VALUES ('" & TxtFreigabe1.Text & "', '" & FrageNummer.Text &
    25. "', '" & C1.Text & "', '" & C2.Text & "', '" & C3.Text & "', '" & C4.Text & "')"
    26. cmd.Parameters.AddWithValue("TxtFreigabe1", SqlDbType.Text)
    27. cmd.Parameters.AddWithValue("FrageNummer", SqlDbType.Text)
    28. cmd.Parameters.AddWithValue("C1", SqlDbType.Text)
    29. cmd.Parameters.AddWithValue("C2", SqlDbType.Text)
    30. cmd.Parameters.AddWithValue("C3", SqlDbType.Text)
    31. cmd.Parameters.AddWithValue("C4", SqlDbType.Text)
    32. For i = 1 To anzahl
    33. cmd.Parameters("TxtFreigabe1").Value = i.ToString
    34. cmd.Parameters("FrageNummer").Value = i.ToString
    35. cmd.Parameters("C1").Value = i.ToString
    36. cmd.Parameters("C2").Value = i.ToString
    37. cmd.Parameters("C3").Value = i.ToString
    38. cmd.Parameters("C4").Value = i.ToString
    39. i = i + 1
    40. Next i
    41. MessageBox.Show("Prüfung erfolgreich abgeschlossen")
    42. cmd.ExecuteNonQuery()
    43. Catch ex As Exception
    44. MessageBox.Show(ex.Message)
    45. End Try
    46. con.Close()
    Dateien
    • Aufgaben.docx

      (118,94 kB, 97 mal heruntergeladen, zuletzt: )
    Naja, meine Frage hast Du zwar immer noch nocht beantwortet, aber zumindest konnte ich die Infos aus Deinen Screenshots rausholen. Du hast die Fragenummern also in TextBoxen drinstehen.

    Das sind die rot markierten. Und wenn wir jetzt noch die Namen der TextBoxen wissen würden, dann wäre der Code auch schnell erledigt. Denn zusammen mit den Namen der blau markierten Antwortcheckboxen hat man alle relevanten Infos. Allerdings musst Du somit bei 5 Fragen 5 verschiedene TextBoxen und 20 CheckBox-Werte überprüfen bzw. in die DB eintragen. Ne Schleife ist zwar möglich, aber keine, die die CEs indiziert. Da musst Du dann eher mit sowas arbeiten wie:

    VB.NET-Quellcode

    1. For Each TextBox In {TextBoxMitFragenummer1, TextBoxMitFragenummer2, TextBoxMitFragenummer3, TextBoxMitFragenummer4, TextBoxMitFragenummer5}
    2. '...
    3. Next

    Das ist aber nicht sonderlich gut erweiterbar, wenn mehr Fragen dazukommen. Da wäre die Erzeugung eines UserControls oder die Verwendung eines DGVs mit CheckBox-Spalten sinnvoller.

    Aber 2 Sachen: Wie gut schätzt Du Deine Kenntnisse ein?
    1. Im Programmieren, denn

    VB.NET-Quellcode

    1. For i = 1 To anzahl
    2. '...
    3. i = i + 1
    4. Next i
    zeigt, dass Du wohl nicht genau weißt, was der Code macht.
    2. Im Allgemeinwissen, denn die Bundeskanzlerin heißt nicht Angelika Merkel. Aber dieser Punkt ist programmiertechnisch irrelevant.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi, also die Namen der neu generierten TextBoxen lauten wie folgt:

    FrageNeu, FrageNummer, Antwort1Neu, Antwort2Neu, Antwort3Neu, Antwort4Neu, Checkbox1Neu, Checkbox2Neu, Checkbox3Neu, Checkbox4Neu

    Die Checkboxen wandele ich dann in ein Text "ja" oder "nein" um und schreibe es jeweils in die vier Textboxen mit den Namen C1, C2, C3, C4

    VB.NET-Quellcode

    1. If Checkbox2Neu.Checked = True Then
    2. C1.Text = "Ja"
    3. Else
    4. C1.Text = "Nein"
    5. End If


    Welche Frage hatte ich nicht beantwortet?
    For each hatte ich auch versucht, aber kam auf das selbe Problem das immer nur der letzte Datensatz in die DB eingetragen wurde.
    Wen alles nichts hilft dann versuche ich deinen Vorschlag mit dem Datagriedview.

    Zu deinen zwei Fragen, ich habe mir erst seit kurzem Visual Basic selber beigebracht mit Hilfe eines Buches und Youtube Beispielen.
    Daher sei mit verziehen wenn ich noch Fehler drin habe. Bin aber froh das es Leute wie euch gibt die mir helfen können.

    Vielen Dank an alle hier die mir geantwortet haben.

    rawneblade schrieb:

    Hi, also die Namen der neu generierten TextBoxen lauten wie folgt:
    Wenn allerdings 3 neue Fragen dazukommen, dann kann pro Frage nicht die TextBox mit der 1. Antwort Antwort1Neu heißen. Jedes CE kann nur einen eindeutigen Namen haben. Also nochmal: Wie heißt die TextBox für die 1. Antwort für Frage 1, wie heißt die TextBox für die 1. Antwort für Frage 2, wie heißt die TextBox für die 1. Antwort für Frage 3?

    btw: Dein letztgenanntes CodeKonstrukt kannst Du zusammenfassen zu:

    VB.NET-Quellcode

    1. C1.Text = If(Checkbox2Neu.Checked, "Ja", "Nein")

    Nicht nur das DGV im Kopf behalten. Um Dein Programm effizient und erweiterbar zu machen, aber das generelle Aussehen beizubehalten, nutze UserControls (Benutzersteuerlement). Das sind Boxen, wo Du dann z.B. die TextBoxen und CheckBoxen für eine Frage reinhaust. Und wenn Du dann eine neue UserControl-Instanz erzeugst (D.h. Du selber musst nur 1 neues Element erstellen), kommen eben alle Einzelteile für 1 Frage zusammen auf Dein Formular.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Die TextBoxen werden über eine Funktion "Fragehinzufuegen" erzeugt die in folgender Schleife aufgerufen wird:

    VB.NET-Quellcode

    1. Do While reader.Read()
    2. Fragehinzufuegen()
    3. FrageNeu.Text = reader("Fragen")
    4. FrageNummer.Text = reader("FrageNummer")
    5. Antwort1Neu.Text = reader("Antwort1")
    6. Antwort2Neu.Text = reader("Antwort2")
    7. Antwort3Neu.Text = reader("Antwort3")
    8. Antwort4Neu.Text = reader("Antwort4")
    9. anzahl = anzahl + 1
    10. TxtAnzahl.Text = anzahl
    11. Loop

    Also werden sie erst auf den Klick eines Button erzeugt und zwar so oft wie Fragen in der DB stehen, somit keine direkte Namensvergabe.
    Das funktioniert auch problemlos.

    Der Tipp mit den Benutzersteuerelementen ist gut, hatte auch schon überlegt dafür eine Groupbox zu verwenden, werde dies auch ausprobieren.
    Habe aber immer noch das ursprüngliche Problem, wie bekomme ich die Haken so einer Groupbox bei einer dynamischen Anzahl in die
    Datenbank zurückgeschrieben?
    Ich muss es wohl drastisch machen: Ich frage zum letzten Mal: Wie heißen die Controls? Um diese sehr einfache Frage zu beantworten, braucht es wohl eine Anleitung.
    Bitte Screenshot vom Form posten, wenn das Programm nicht läuft, also sowas

    Dann die TextBox anklicken, die die 1. Fragenummer enthalten wird, dann in das Eigenschaftenfenster wechseln, einen Screenshot machen und den posten. Dort ist nämlich der Name der TextBox ganz oben und in der Zeile (Name) zu sehen. Und diesen Namen brauchen wir - wie schon zig mal geschrieben. Also das hier:

    Desweiteren Screenshots von den Namen (oder die Namen selbst, falls Du sie schreiben willst) der TextBoxen, wo zur Laufzeit die 2. Fragenummer, die 3. Fragenummer die 4. und die 5. drin sein werden.
    Schaffst Du das?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    Ok nochmal ich kann dir nicht die Namen der Controls sagen, da sie im Quellcode nicht vorhanden sind, sondern erst zur Laufzeit über eine Schleife erzeugt werden.

    Ich starte das Programm und lege als Beispiel 20 Fragen an, und speichere diese in die Datenbank. Als zweite Hauptfunktion rufe ich die 20 Fragen von der
    Datenbank ab (ich sehe also Fragenummer, Frage und vier Antwortmöglichkeiten jeweils für alle 20 Fragen) und sehe sie als Text vor mir, hinter jeder der
    4 Antwortmöglichkeiten pro Frage ist eine Checkbox. Pro Frage markiere ich eine Checkbox.

    Jetzt ist mein Ziel und mein großes Problem das ich die angehakten Checkboxen in verbidnung mit der Fragenmmer nicht mehr in meine Access Datenbank
    importiert bekomme. Es importiert mir immer nur die letzte Frage.

    Das muss doch möglich sein dies einfach zu tun, wenn nicht ist Visual Basic für mich nutzlos.