Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Dynamische Abfrage mit variabler Anzahl von IN-Argumenten (p1, p2, p3).

Aus Kommentaren:

depToDelete und otherToDelete sind eine Liste (von Strings), die von einem Funktionsaufruf übergeben werden. Diese enthalten eine oder mehrere Anleitungen, die ich löschen möchte

Dafür formatiert Ihr Code es nicht richtig für SQL. Für eine Liste mit 2 Guid-Strings erhalten Sie nach dem Join Folgendes:

"af489fbf-982a-49de-b73e-2ac3f3192225, 0feab28d-4f96-456a-9f36-0a0376627128"

Dann strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77) will anscheinend versuchen das Anführungszeichen zu entfernen und durch ein Häkchen zu ersetzen. Das Problem ist, dass die Zeichenfolge selbst kein Zitat enthält. Sie sehen es in der IDE, weil VS Ihnen so mitteilt, dass es sich um einen String handelt.

Der SubString Schritt ist das Trimmen gültiger Guid-Zeichen aus dem Ergebnis (und einer magischen Zahl von 77 lässt es abstürzen, wenn nicht gerade die richtige Anzahl vorhanden ist):

Vorher:"9b842f14-7932-4e3d-8483-07790ccc674c, ...
&Nachher:​​"b842f14-7932-4e3d-8483-07790ccc674c,...

Dies wird nicht funktionieren, da der Inhalt nicht eine sehr lange Guid ist. Jedes Element in der List muss angekreuzt werden. Um jedes Element in der Liste anzukreuzen, müssen Sie eine Schleife ausführen und einen String erstellen oder linq verwenden.

Aber das wird auch nicht funktionieren. MySQL mag den resultierenden String vom NET-Provider einfach nicht auf diese Weise und es macht keine Parameter-Arrays, also ...

Also bauen wir eine Parameter-Engine:

Es macht keinen Sinn, mit 2 Sätzen von Guids zu arbeiten, also verketten Sie sie (diese sind eine tatsächliche List(of String)). enthält guids, nicht etwas anderes, nicht json):

Dim depVals = depToDelete.Concat(otherToDelete).ToList

' your sql here
Dim sql = "DELETE FROM DEMO WHERE GuidString IN (@magic)"
' param storage
Dim gvalues As New List(Of String)

' create a list of "@g" param placeholders
Dim ndx As Int32 = 0
For ndx = 0 To depVals.Count - 1
    ' adds a "@gN" value to the List
    gvalues.Add(String.Format("@g{0}", (ndx + 1).ToString))
Next

' insert them into the SQL string
sql = sql.Replace("@magic", String.Join(", ", gvalues))
' '@magic' replaced with "@g1, @g2, @g3..." 

Using cmd As New MySqlCommand(sql, dbcon)
    dbcon.Open()

    ' create an equal number of Paramerters, set the value of each
    For n As Int32 = 0 To gvalues.Count - 1
       ' add parm "@gN", assign value from 'depVals`
       cmd.Parameters.Add(gvalues(n), MySqlDbType.String).Value = depVals(n)
    Next

   ' debug:
   Dim fullSQL = GetFullCommandSQL(cmd)
   Console.WriteLine(fullSQL)

   Dim rows = cmd.ExecuteNonQuery()
End Using

Die Debug-Ausgabe ist syntaktisch korrekt:

...und die 3 Zeilen mit diesen GUIDs werden gelöscht!

Auch:

  • Leere Catch-Blöcke sind schlecht, weil sie Probleme vor der einzigen Person verbergen, die sie beheben kann (dir).
  • Sie sollten Option Strict verwenden, um zu vermeiden, dass VB errät, was Sie mit bestimmten Dingen meinen.