sql >> Base de Datos >  >> RDS >> Mysql

Consulta dinámica usando un número variable de argumentos IN (p1, p2, p3)

De los comentarios:

depToDelete y otherToDelete son listas (de cadenas) que pasan de una llamada de función. Estos contienen uno o varios GUID que deseo eliminar

Para eso, su código no lo formatea correctamente para el SQL. Para obtener una lista de 2 Guid Strings, después de la unión obtienes esto:

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

Entonces, strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77) aparentemente quiere intentar eliminar la cita y reemplazarla con una marca. El problema es que la cadena en sí no incluye una cotización. Lo ves en el IDE porque esa es la forma en que VS te dice que es una cadena.

La SubString El paso es recortar los caracteres Guid válidos del resultado (y un número mágico de 77 permite que se bloquee cuando no hay el número correcto de ellos):

Antes:"9b842f14-7932-4e3d-8483-07790ccc674c, ...
y después:"b842f14-7932-4e3d-8483-07790ccc674c,...

Esto no funcionará porque el contenido no es un Guid muy largo. Cada elemento en la List necesita ser marcado. Para marcar cada elemento de la lista, debe hacer un bucle y crear una cadena, o usar linq.

Pero eso tampoco funcionará. A MySQL simplemente no le gusta la cadena resultante del proveedor NET de esa manera y no hace arreglos de parámetros, así que...

Así que construyamos un motor de parámetros:

No tiene sentido trabajar con 2 conjuntos de Guids, así que únalos (estos son una List(of String) real que contiene guids, no otra cosa, no 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 salida de depuración es sintácticamente correcta:

... ¡y las 3 filas con esos GUID se eliminan!

También:

  • Los bloques Catch vacíos son malos porque ocultan los problemas de la única persona que puede solucionarlos (usted).
  • Debe usar Option Strict para evitar que VB adivine lo que quiere decir con ciertas cosas.