Mysql
 sql >> Database >  >> RDS >> Mysql

Query dinamica che utilizza un numero variabile di argomenti IN (p1, p2, p3).

Dai commenti:

depToDelete e otherToDelete sono list(of string) che passa da una chiamata di funzione. Questi contengono 1 o più guid che desidero eliminare

Per questo, il tuo codice non lo formatta correttamente per SQL. Per un elenco di 2 Guid String, dopo il join ottieni questo:

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

Quindi, strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77) a quanto pare vuole provare a rimuovere la citazione e sostituirla con un segno di spunta. Il problema è che la stringa stessa non include un preventivo. Lo vedi nell'IDE perché questo è il modo in cui VS ti dice che è una stringa.

La SubString il passaggio consiste nel tagliare i caratteri Guid validi dal risultato (e un numero magico di 77 gli consente di arrestarsi in modo anomalo quando non ce n'è il numero giusto):

Prima:"9b842f14-7932-4e3d-8483-07790ccc674c, ...
&Dopo:"b842f14-7932-4e3d-8483-07790ccc674c,...

Questo non funzionerà perché i contenuti non sono un Guid molto lungo. Ogni elemento nella List deve essere spuntato. Per spuntare ogni elemento nell'elenco è necessario eseguire un ciclo e creare una stringa, oppure utilizzare linq.

Ma neanche questo funzionerà. A MySQL semplicemente non piace la stringa risultante dal provider NET in questo modo e non fa array di parametri quindi...

Quindi costruiamo un motore di parametri:

Non ha senso lavorare con 2 set di Guid, quindi concateli (questi sono un vero List(of String) contenente guid, non qualcos'altro, non 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

L'output di debug è sintatticamente corretto:

...e le 3 righe con quei GUID vengono eliminate!

Inoltre:

  • I blocchi di cattura vuoti sono dannosi perché nascondono i problemi all'unica persona che può risolverli (tu).
  • Dovresti usare Option Strict per evitare che VB indovini cosa intendi con determinate cose.