Parameter richtig anwenden

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Mad Andy.

    Parameter richtig anwenden

    Hallo

    zu nachfolgendem Code habe ich folgendes Problem
    Ich habe eine Nummer in der Anwendungsdatei hinterlegt diese sollte nach jeder INSERT INTO Anweisung automatisch mit in die Datenbank wandern in die Spalte ArtNr und anschliessend soll diese Nummer in der Anwendungsdatei um 1 hochgezählt werden, funktioniert bis hierher auch alles super, aber nur wenn es sich um ein Datensatz handelt der von SELECT gefunden wurde dann ist für diesen Aufruf die Nr. z.B. 500, beim nächsten aufruf 501 usw. sind es jetzt aber zwei oder mehr Datensätze dann haben alle datensätze in diesem Aufruf die Nummer 500, beim nächsten Aufruf haben dann alle 501. Wie kann ich das Problem lösen?

    Quellcode

    1. Imports System.Data.SqlClient
    2. Public Class Form1
    3. Private connserver As String = My.Settings.connserver
    4. Private connclient As String = My.Settings.connclient
    5. Private sql1 As String = "SELECT * FROM cArtikel WHERE (erstellt = 'True')"
    6. Private sql2 As String = "UPDATE cArtikel SET erstellt = 'False'"
    7. Private sql3 As String = "INSERT INTO sArtikel(Artikel, Beschreibung, ArtNr) VALUES (@p2, @p3, @p4)"
    8. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    9. Dim conn1 As New SqlConnection(connclient & ";MultipleActiveResultSets=True")
    10. Dim conn2 As New SqlConnection(connserver & ";MultipleActiveResultSets=True")
    11. conn1.Open()
    12. conn2.Open()
    13. Dim cmd1 As New SqlCommand(sql1, conn1)
    14. Dim cmd2 As New SqlCommand(sql3, conn2)
    15. Dim cmd3 As New SqlCommand(sql2, conn1)
    16. cmd2.Parameters.Add("@p2", SqlDbType.VarChar)
    17. cmd2.Parameters.Add("@p3", SqlDbType.Text)
    18. Dim p4 As New SqlParameter("@p4", SqlDbType.VarChar)
    19. p4.Value = (My.Settings.Artikelnummer)
    20. My.Settings.Artikelnummer = My.Settings.Artikelnummer + 1
    21. cmd2.Parameters.Add(p4)
    22. Using reader As SqlDataReader = cmd1.ExecuteReader()
    23. While reader.Read()
    24. cmd2.Parameters("@p2").Value = reader("Artikel")
    25. cmd2.Parameters("@p3").Value = reader("Beschreibung")
    26. My.Settings.Artikelnummer = My.Settings.Artikelnummer + 1
    27. cmd2.ExecuteNonQuery()
    28. cmd3.ExecuteNonQuery()
    29. End While
    30. End Using
    31. conn1.Close()
    32. conn2.Close()
    33. End Sub
    Hi!

    cmd2.Parameters.Add(p4) und das davor gehört natürlich in die While-Schleife rein, da du sonst immer den gleichen p4 verwendest ;)

    Zu deinem restlichen Code: Die Parameter direkt in die Query zu schreiben (mit &) ist u.U. übersichtlicher und vermutlich auch schneller (habs noch nicht getestet) als @Parameter zu verwenden. Wahrscheinlich sogar in deinem Fall, da du hier die Parameter instanzieren und setzen musst und nachher das Framework das ganze auch noch umsetzen muss.


    mfG Andy

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

    Hey Danke für deine Tipps
    das (p4) in die While-Schleife gehört ist mir dann gestern abend auch noch eingefallen.

    Den Rest probiere ich mal aus ob ich das so umsetzen kann. sicherlich werde ich derzeit kein Geschwindigkeitsunterschied spüren da dafür die Datensätze zu wenig sind, aber man muss es ja auch nicht erst darauf ankommen lassen.

    --------

    Da unter Umständen sehr viele Daten abgefragt, geändert und gelöscht bzw. auch ständig irgendwelche Nummern aktualisiert und abgefragt werden, sollte man da die Verbindung nicht in eine Transaction stellen bzw. wenn das geht das wenn aktuell ne Verbindung besteht man einfach andere die ebenfalls eine Verbindung herstellen in eine Warteschleife packt um somit jede Anfrage nacheinander abarbeitet? Oder wird es eh schon so gemacht


    Edit by Mad Andy:
    Doppelposts zusammengeführt. In Zukunft wieder Beiträge bearbeiten.

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

    Hi!

    Ich hab leider keine Ahnung... aber du kannst pro Thread, den der DB-Server hat nur eine Abfrage auf einmal behandeln, die anderen müssen warten. Ich denk mal, dass das intern so gelöst wurde, dass das geht ^^
    Du kannst ja evntl. eine Testreihe starten, wenns dir um Leistung geht ;)


    mfG Andy
    Mir gehts eher darum das nicht ein Datensatz der von jemand anders bearbeitet wurde von einem zweiten bearbeitet werden kann.

    Wenn viele Datensätze bearbeitet werden und es kommt während dessen zum Abbruch der Konnectivität zum Server sollte ein Reject oder Rollback-Ereignis ausgelöst werden.

    Das dritte ist wenn mehrere aufeinmal auf Datensätze zugreifen das die Nummer in den Anwendungseinstellung auch tatsächlich nur einmal vergeben wird
    Hi!

    Du kannst einen Server schreiben, der die Datenbank behandelt. Alle Client-Programme senden dann die gewünschten Änderungen an den Server und der führt nachher erst die Operation in der Datenbank durch (nacheinander). Wenn er fertig ist, sendet er dann ein 'OK' zurück. Damit sparst du dir auch den Datenbanktreiber bei den Clients.

    Zu der Sache mit dem Abbruch: Ich kenne zwar MSSQL nicht, aber der hat sicherlich dafür auch ein TimeOut, dass sich einstellen lässt?
    Ansonsten hald in kleineren Portionen (mehrere Queries) aktuallisieren. Beim Select kannst du LIMIT verwenden. (z.B. "SELECT * FROM xxx WHERE blablabla LIMIT 0 , 99", "... LIMIT 100 , 199", ...)


    mfG Andy

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

    Falls du noch nen einfachen weg suchst die Einträge in einer Tabelle zu zählen:

    VB.NET-Quellcode

    1. sql = "SELECT COUNT(*) FROM table"
    2. Dim cmd as SqlCommand = new SqlCommand(sql, con)
    3. Dim c as Long = Convert.ToLong(cmd.ExecuteScalar())


    Bei Count kannst du genauso wie bei jedem anderen SELECT auch "WHERE" verwenden.


    mfG Andy