Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consulta dinâmica usando número variável de argumentos IN (p1, p2, p3)


Dos comentários:

depToDelete e otherToDelete são uma lista (de string) que passa de uma chamada de função. Eles contêm 1 ou muitos guids que desejo excluir

Para isso, seu código não o formata corretamente para o SQL. Para uma lista de 2 Guid Strings, após a junção, você obtém isso:
"af489fbf-982a-49de-b73e-2ac3f3192225, 0feab28d-4f96-456a-9f36-0a0376627128"

Então, strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77) aparentemente quer tentar remover a citação e substituir por um carrapato. O problema é que a string em si não inclui um Quote. Você o vê no IDE porque essa é a maneira do VS dizer que é uma string.

A SubString passo é cortar caracteres Guid válidos do resultado (e um Número Mágico de 77 permite que ele falhe quando não há apenas o número certo deles):

Antes:"9b842f14-7932-4e3d-8483-07790ccc674c, ...
&Depois:"b842f14-7932-4e3d-8483-07790ccc674c,...

Isso não funcionará porque o conteúdo não é um Guid muito longo. Cada elemento na List precisa ser marcado. Para marcar cada elemento na lista, você precisa fazer um loop e construir uma string ou usar linq.

Mas isso também não funcionará. O MySQL simplesmente não gosta da string resultante do provedor NET dessa maneira e não faz matrizes de parâmetros, então ...

Então vamos construir um mecanismo de parâmetros:


Não faz sentido trabalhar com 2 conjuntos de Guids, então concate-os (estes são uma List(of String) real contendo guids, não outra coisa, não 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

A saída de depuração está sintaticamente correta:

...e as 3 linhas com esses GUIDs são excluídas!

Também:
  • Os blocos de captura vazia são ruins porque ocultam problemas da única pessoa que pode corrigi-los (você).
  • Você deve usar Option Strict para evitar que o VB adivinhe o que você quer dizer com certas coisas.