使用可变数量的IN(p1,p2,p3)参数进行动态查询

时间:2016-01-12 17:35:22

标签: mysql vb.net

我有以下内容:

Dim strdepToDelete As String
Dim strOtherToDelete As String
strdepToDelete = String.Join(",", depToDelete)
strOtherToDelete = String.Join(",", otherToDelete)
strdepToDelete = strdepToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77)
strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77)

cmd.CommandText = "delete from database.tableA where guid in(@strdepToDelete, @strOtherToDelete);"
cmd.Parameters.Add("@strdepToDelete", MySql.Data.MySqlClient.MySqlDbType.String)
cmd.Parameters("@strdepToDelete").Value = strdepToDelete
cmd.Parameters.Add("@strOtherToDelete", MySql.Data.MySqlClient.MySqlDbType.String)
cmd.Parameters("@strOtherToDelete").Value = strOtherToDelete
Dim answer = MsgBox("Data will be deleted if you continue", MsgBoxStyle.YesNo + MsgBoxStyle.DefaultButton2, "Are You Sure")
If answer = vbYes Then
    Try
        cmd.ExecuteNonQuery()
        success = True
    Catch ex As Exception

    End Try
    Return success
End If

我将鼠标悬停在

cmd.Parameters("@strdepToDelete").Value = strdepToDelete 

cmd.Parameters("@strOtherToDelete").Value = strOtherToDelete

并且具有MySql正在寻找的格式的字符串值。为什么记录没有从表中删除?

1 个答案:

答案 0 :(得分:2)

来自评论:

depToDelete和otherToDelete是从函数调用传递的list(of string)。这些包含我想要删除的1个或多个guid

为此,您的代码不会为SQL正确格式化它。对于2个Guid字符串的列表,在加入之后你会得到这个:

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

然后,strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77)显然想要尝试删除引号并替换为勾号。问题是字符串本身不包含Quote。你在IDE中看到它,因为这是VS告诉你它是一个字符串的方式。

SubString步骤正在从结果中修剪有效的Guid字符(而77的幻数允许它在没有恰当数量的情况下崩溃):

之前:"9b842f14-7932-4e3d-8483-07790ccc674c, ...
&安培;之后:"b842f14-7932-4e3d-8483-07790ccc674c,...

这不会起作用,因为内容不是一个很长的Guid。需要勾选List中的每个元素。要勾选列表中的每个元素,您需要循环并构建一个字符串,或使用linq。

但是那也无法正常工作。 MySQL只是不喜欢NET提供商的结果字符串那样,它不会做参数数组所以......

因此,让我们构建一个参数引擎:

使用2套Guids是没有意义的,所以将它们连接起来(这些是包含guid的实际List(of String),而不是其他东西,而不是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

调试输出在语法上是正确的:

  

在GuidString IN('2abfa4c4-36e2-47ea-8218-6f568a31fa88','fd02865e-5da2-4d4e-ba4b-84bf5b5f1444','7376d9a3-35c9-4b44-8b85-4cd663b31d5e')的DEMO中删除

...并删除包含这些GUID的3行!

此外:

  • 空Catch块很糟糕,因为它们可以隐藏唯一可以修复它的人(你)。
  • 你应该选择Strict以避免VB猜测你的意思。