Mysql
 sql >> Base de données >  >> RDS >> Mysql

Requête dynamique utilisant un nombre variable d'arguments IN (p1, p2, p3)

À partir des commentaires :

depToDelete et otherToDelete sont des listes (de chaînes) qui passent à partir d'un appel de fonction. Ceux-ci contiennent le 1 ou plusieurs guids que je souhaite supprimer

Pour cela, votre code ne le formate pas correctement pour le SQL. Pour une liste de 2 Guid Strings, après la jointure vous obtenez ceci :

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

Ensuite, strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77) veut apparemment essayer de supprimer la citation et de la remplacer par une coche. Le problème est que la chaîne elle-même n'inclut pas de devis. Vous le voyez dans l'IDE parce que c'est la façon dont VS vous dit qu'il s'agit d'une chaîne.

La SubString l'étape supprime les caractères Guid valides du résultat (et un nombre magique de 77 lui permet de planter quand il n'y en a pas juste le bon nombre) :

Avant :"9b842f14-7932-4e3d-8483-07790ccc674c, ...
&Après :"b842f14-7932-4e3d-8483-07790ccc674c,...

Cela ne fonctionnera pas car le contenu n'est pas un Guid très long. Chaque élément dans la List doit être coché. Pour cocher chaque élément de la liste, vous devez boucler et créer une chaîne, ou utiliser linq.

Mais ça ne marchera pas non plus. MySQL n'aime tout simplement pas la chaîne résultante du fournisseur NET de cette façon et il ne fait pas de tableaux de paramètres donc...

Construisons donc un moteur de paramètres :

Cela n'a aucun sens de travailler avec 2 ensembles de Guids, alors concatez-les (ce sont une véritable List(of String) contenant des guids, pas autre chose, pas 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

La sortie de débogage est syntaxiquement correcte :

... et les 3 lignes avec ces GUID sont supprimées !

Aussi :

  • Les blocs Catch vides sont mauvais car ils cachent les problèmes à la seule personne qui peut les résoudre (vous).
  • Vous devriez utiliser Option Strict pour éviter que VB ne devine ce que vous entendez par certaines choses.