Ein Update-Befehl, mehrere Updates?

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Ein Update-Befehl, mehrere Updates?

    Hi Leute,

    ich habe beim Export einer Tabelle gesehen, dass man anstatt mehrerer INSERT's ...

    SQL-Abfrage

    1. INSERT INTO `foo` (`blub`, `blab`, `bleb`) VALUES ('ruff', 'raff', 'reff');
    2. INSERT INTO `foo` (`blub`, `blab`, `bleb`) VALUES ('tuff', 'taff', 'teff');
    3. INSERT INTO `foo` (`blub`, `blab`, `bleb`) VALUES ('suff', 'saff', 'seff');

    ... ein INSERT mit mehreren VALUES-Zeilen nutzen kann ...

    SQL-Abfrage

    1. INSERT INTO `foo` (`blub`, `blab`, `bleb`) VALUES
    2. ('ruff', 'raff', 'reff'),
    3. ('tuff', 'taff', 'teff'),
    4. ('suff', 'saff', 'seff');

    ... was eine Abfrage mit mehreren Tausend INSERTs von ca. 20sek. auf 0,6sek. bringt.

    Jetzt habe ich aber eben so viele UPDATE's (in eine andere Tabelle) wie INSERT's.
    Gibt es für UPDATE eine vergleichbare Notation?
    Wow - sehr interessant!
    Ich weiß zu deiner Frage nicht die Antwort, aber ich hänge gleich mal paar eigene Fragen an:
    1. Welcher Sql-Dialekt ist das?
    2. Gibts iwo eine Dokumentation dazu?
    3. Falls sich wer damit auskennt: gibts weitere Sql-Dialekte, die das unterstützen, oder ist das gar im allgemeinen Standard-Sql enthalten?
    @ErfinderDesRades
    Hier: blog.martinhey.de/de/post/2009…T-Statement-einfugen.aspx

    Ist wohl Standard-SQL ( supportnet.de/stat/2004/9/id198347.asp )

    @hirnwunde
    1keydata.com/de/sql/sql-update.php

    Es ist auch möglich, mit dem Befehl UPDATE mehrere Spalten gleichzeitig zu aktualisieren. In diesem Fall würde die Syntax folgendermaßen aussehen:

    SQL-Abfrage

    1. UPDATE "Tabellen_Name"
    2. SET Spalte1 = [Wert1], Spalte2 = [Wert2]
    3. WHERE "Bedingung";


    ErfinderDesRades schrieb:

    Wow - sehr interessant!


    Kannst ja mal selbst bisserl testen, @ErfinderDesRades. Hier meine Test-Funktionen:
    Diese müssen natürlich noch Deinen Gegebenheiten angepasst werden ;)
    Spoiler anzeigen

    mit einem INSERT

    VB.NET-Quellcode

    1. Private Sub btn_one_insert_Click(sender As System.Object, e As System.EventArgs) Handles btn_one_insert.Click
    2. Dim sql As String = ""
    3. Static start_time As DateTime
    4. Static stop_time As DateTime
    5. Dim elapsed_time As TimeSpan
    6. For i = 1 To 10000
    7. If i = 1 Then
    8. sql = "INSERT INTO `3040test`(`txlcode`) VALUES "
    9. End If
    10. If i < 10000 Then
    11. sql = sql + "('asdf2" + i.ToString("00000") + "')," + vbCrLf
    12. Else
    13. sql = sql + "('asdf2" + i.ToString("00000") + "');" + vbCrLf
    14. End If
    15. Next
    16. start_time = Now
    17. MySQLSachen.InsertTest(sql)
    18. stop_time = Now
    19. elapsed_time = stop_time.Subtract(start_time)
    20. Label6.Text = elapsed_time.TotalSeconds.ToString("0.00000")
    21. End Sub

    mit vielen INSERTs (auf 1000 INSERTs begrenzt)

    VB.NET-Quellcode

    1. Private Sub btn_many_inserts_Click(sender As System.Object, e As System.EventArgs) Handles btn_many_inserts.Click
    2. Dim sql As String = ""
    3. Dim startINS As String = ""
    4. Static start_time As DateTime
    5. Static stop_time As DateTime
    6. Dim elapsed_time As TimeSpan
    7. startINS = "INSERT INTO `3040test`(`txlcode`) VALUES ('asdf2"
    8. For i = 1 To 1000
    9. sql = sql + startINS + i.ToString("0000") + "');" + vbCrLf
    10. Next
    11. start_time = Now
    12. MySQLSachen.InsertTest(sql)
    13. stop_time = Now
    14. elapsed_time = stop_time.Subtract(start_time)
    15. Label5.Text = elapsed_time.TotalSeconds.ToString("0.00000")
    16. End Sub

    Die dazugehörige InsertTest()
    Diese benötigt eine vorhandene Verbindung. Die Comments entfernen, um eine eigene Verbindung aufzubauen

    VB.NET-Quellcode

    1. Public Function InsertTest(ByVal SQLs As String) As Boolean
    2. Dim iReturn As Boolean
    3. 'Using SQLConnection As New MySqlConnection(connstrNew)
    4. Using sqlCommand As New MySqlCommand()
    5. With sqlCommand
    6. .CommandText = SQLs
    7. .Connection = connNew
    8. .CommandType = CommandType.Text
    9. End With
    10. Try
    11. 'SQLConnection.Open()
    12. sqlCommand.ExecuteNonQuery()
    13. iReturn = True
    14. Catch ex As MySqlException
    15. 'MsgBox("Fehler beim INSERT eines Bauteils." + vbCrLf + "Funktion: MysqlSachen.InsertBauteil" + vbCrLf + vbCrLf + ex.Message.ToString)
    16. iReturn = False
    17. Finally
    18. 'SQLConnection.Close()
    19. End Try
    20. End Using
    21. 'End Using
    22. Return iReturn
    23. End Function



    @WhitePage:
    Ok, das kenn ich und nutze ich auch heute schon, wenn ich in einer Zeile mehrere Änderungen vornehme.
    Hier hingegen möchte ich mehrere UPDATEs auf mehreren Zeilen mit einem UPDATE-Befehl abdecken, eben wie der INSERT-Befehl oben mehrere Zeilen abdeckt. ;)
    @WhitePage
    Erfüllen alle deine Zeilen dieselbe Bedingung?

    Das wäre ja zu einfach. ;)
    Nein, jede Zeile ist ein eigenes Bauteil mit eigenen Daten.
    Meine UPDATEs sehen eher folgendermassen aus:

    SQL-Abfrage

    1. UPDATE 3040_info SET Messdatum = 'Vorabeintrag Messmaske3040 27.05.2014 08:45:47' WHERE TXLCode = 'GW100990000';
    2. UPDATE 3040_info SET Messdatum = 'importiert am 08.04.2014 09:39:44' WHERE TXLCode = 'GW101020036';
    3. UPDATE 3040_info SET Messdatum = 'importiert am 08.04.2014 09:39:02' WHERE TXLCode = 'GW101020043';
    4. UPDATE 3040_info SET Messdatum = 'importiert am 08.04.2014 09:36:09' WHERE TXLCode = 'GW101020139';

    Und eben dies hätte ich gern mal mit einem einzelnen UPDATE;)

    @ErfinderDesRades
    zum testen - und NUR zum testen - nutze ich sowas schonmal.

    Im Produkt sehen meine MySQL-Funktionen eher folgendermassen aus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function CreateNewMess(ByVal werte() As String, type As String) As Boolean
    2. Dim Returnvalue As Boolean = False
    3. Using conn As New MySqlConnection(connectstring), comm As New MySqlCommand
    4. Select Case type
    5. Case "3040"
    6. With comm
    7. .CommandText = "INSERT INTO 3040_messdaten" _
    8. + " (`TXLCode`, `ol1`, `ol2`, `ow1`, `ow2`, `r11`, `r12`, `r13`, `r21`, `r22`, `r23`, `r31`, `r32`, `r33`, `r41`, `r42`, `r43`, `comment`)" _
    9. + "VALUES" _
    10. + " ( @TXLCode , @ol1 , @ol2 , @ow1 , @ow2 , @r11 , @r12 , @r13 , @r21 , @r22 , @r23 , @r31 , @r32 , @r33 , @r41 , @r42 , @r43 , @comment );"
    11. .Connection = conn
    12. .CommandType = CommandType.Text
    13. .Parameters.AddWithValue("TXLCode", werte(0))
    14. .Parameters.AddWithValue("ol1", werte(1))
    15. .Parameters.AddWithValue("ol2", werte(2))
    16. .Parameters.AddWithValue("ow1", werte(3))
    17. .Parameters.AddWithValue("ow2", werte(4))
    18. .Parameters.AddWithValue("r11", werte(5))
    19. .Parameters.AddWithValue("r12", werte(6))
    20. .Parameters.AddWithValue("r13", werte(7))
    21. .Parameters.AddWithValue("r21", werte(8))
    22. .Parameters.AddWithValue("r22", werte(9))
    23. .Parameters.AddWithValue("r23", werte(10))
    24. .Parameters.AddWithValue("r31", werte(11))
    25. .Parameters.AddWithValue("r32", werte(12))
    26. .Parameters.AddWithValue("r33", werte(13))
    27. .Parameters.AddWithValue("r41", werte(14))
    28. .Parameters.AddWithValue("r42", werte(15))
    29. .Parameters.AddWithValue("r43", werte(16))
    30. .Parameters.AddWithValue("comment", werte(17))
    31. End With
    32. Case "2121"
    33. With comm
    34. .CommandText = "INSERT INTO 2121_messdaten" _
    35. + " (`TXLCode`, `ol1`, `ow1`, `r11`, `r12`, `r21`, `r22`, `r31`, `r32`, `r41`, `r42`, `comment`)" _
    36. + "VALUES" _
    37. + " ( @TXLCode , @ol1 , @ow1 , @r11 , @r12 , @r21 , @r22, @r31 , @r32, @r41 , @r42 , @comment );"
    38. .Connection = conn
    39. .CommandType = CommandType.Text
    40. .Parameters.AddWithValue("TXLCode", werte(0))
    41. .Parameters.AddWithValue("ol1", werte(1))
    42. .Parameters.AddWithValue("ow1", werte(2))
    43. .Parameters.AddWithValue("r11", werte(3))
    44. .Parameters.AddWithValue("r12", werte(4))
    45. .Parameters.AddWithValue("r21", werte(5))
    46. .Parameters.AddWithValue("r22", werte(6))
    47. .Parameters.AddWithValue("r31", werte(7))
    48. .Parameters.AddWithValue("r32", werte(8))
    49. .Parameters.AddWithValue("r41", werte(9))
    50. .Parameters.AddWithValue("r42", werte(10))
    51. .Parameters.AddWithValue("comment", werte(11))
    52. End With
    53. Case "2121C"
    54. With comm
    55. .CommandText = "INSERT INTO 2121C_messdaten" _
    56. + " (`TXLCode`, `ol1`, `ow1`, `r11`, `r12`, `r21`, `r22`, `r31`, `r32`, `r41`, `r42`, `comment`)" _
    57. + "VALUES" _
    58. + " ( @TXLCode , @ol1 , @ow1 , @r11 , @r12 , @r21 , @r22, @r31 , @r32, @r41 , @r42 , @comment );"
    59. .Connection = conn
    60. .CommandType = CommandType.Text
    61. .Parameters.AddWithValue("TXLCode", werte(0))
    62. .Parameters.AddWithValue("ol1", werte(1))
    63. .Parameters.AddWithValue("ow1", werte(2))
    64. .Parameters.AddWithValue("r11", werte(3))
    65. .Parameters.AddWithValue("r12", werte(4))
    66. .Parameters.AddWithValue("r21", werte(5))
    67. .Parameters.AddWithValue("r22", werte(6))
    68. .Parameters.AddWithValue("r31", werte(7))
    69. .Parameters.AddWithValue("r32", werte(8))
    70. .Parameters.AddWithValue("r41", werte(9))
    71. .Parameters.AddWithValue("r42", werte(10))
    72. .Parameters.AddWithValue("comment", werte(11))
    73. End With
    74. End Select
    75. Try
    76. conn.Open()
    77. comm.ExecuteNonQuery()
    78. Returnvalue = True
    79. Catch ex As Exception
    80. Hilfssachen.ShowError(funcinfo.GetCurrentMethod.Name, ex.Message)
    81. Finally
    82. comm.Dispose()
    83. conn.Close()
    84. End Try
    85. End Using
    86. Return Returnvalue
    87. End Function


    Aber dies laesst sich bei eben dieser Art von Query nicht bewerkstelligen, da Du dann ja jede VALUES-Zeile Parametrisieren müsstest.
    Da wünsch ich Dir viel Spass bei ;)

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

    hirnwunde schrieb:

    Das wäre ja zu einfach.


    Dann ist die Antwort ganz einfach. Es geht nicht!
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."
    Also ich habs jetzt mit SqlCe probiert und ging nicht.
    Gegoogelt hab ich auch bischen.
    Zu SqlServer fand ich zusätzlich zu WhitePages Link einen Post, der behauptet, das sei Standard-Sql, aber im betreffenden Thread hat es niemand dann auch auch tatsächlich hingekriegt.
    Ebenso Access.

    Also ich schätze das jetzt mal ein als Bonbon für MySql, und mag sein auch für SqlServer. In WhitePages Link wird es für letzteren ja auch als Bonbon vorgestellt.

    Sehr schade, denn Inserts erlebe ich wirklich immer als zum Weinen langsam.
    Zwar gibt es für viele Provider Optimierungen - Bulk-Insert und Kram, aber alles Dialekt-abhängig, und daher nicht wirklich und allgemeingültig in .Net zu integrieren, in dem Sinne, dass man egal welche DataTable ordentlich flott inserten kann.
    Und ebensowenig wirds für EntityFramework da was geben.

    Sql ist einfach eine gammelige Gurken-Sprache. :thumbdown: