从VB.NET构建动态sql查询

Dav*_*ram 2 sql vb.net

我搜索并搜索了一个答案,我找不到一个.我有一个选中的列表框,用户可以选择他们在计算机上遇到的问题.在选中的列表框中,您将看到诸如......慢,病毒,坏硬盘......以及根据他们选择的内容,我将告诉他们估计的维修费用.目前这是我构建查询的方式:

Dim mIssues As String = ""

For i = 0 To lstIssues.CheckedItemsCount - 1
 If mIssues = "" Then
  mIssues = String.Format("IssueName = '{0}'", lstIssues.CheckedItems(i))
 Else
  mIssues = String.Format("{0} OR IssueName = '{1}'", mIssues, lstIssues.CheckedItems(i))               
 End If
Next
Run Code Online (Sandbox Code Playgroud)

上面的代码将查看他们选择了多少问题.如果他们只选择一个问题,那么它将返回如下字符串:IssueName ='无论他们选择什么'.如果他们选择了多个问题,它将返回如下字符串:IssueName ='无论选择何种'或IssueName ='第二个选择'.因此,如果他们选择多个问题,我会在所有选项之间附加一个OR.我这样做是为了在我的查询中动态构建我的where子句.

这是我的查询:

Dim mySQL As String = "SELECT IssueID, IssueTypeID, IssueName, IssueDescription, " _
  & "CustomerID, IndividualCost, GroupCost, Active, ChargeType " _
  & "FROM (SELECT IssueID, IssueTypeID, IssueName, IssueDescription, " _
  & "CustomerID, IndividualCost, GroupCost, Active, ChargeType " _
  & "FROM(cfg_Issues) " _
  & "WHERE " & mIssues & " " _
  & "GROUP BY IssueID, IssueTypeID, IssueName, IssueDescription, CustomerID, " _
  & "IndividualCost, GroupCost, Active) " _
  & "ORDER BY IndividualCost DESC, GroupCost ASC;"
Run Code Online (Sandbox Code Playgroud)

正如您可以看到我的where子句来自第一部分代码.我的问题是,有没有更好的方法来做到这一点?我知道必须有一个更好的方法来构建动态where子句查询,我想看看如何.感谢您提供的任何可以帮助我的指导.

Ste*_*eve 7

这里的第一个问题是SQL注入的大门.我希望您可以完全控制插入的内容,lstIssues因为在为数据库引擎创建命令时,字符串连接始终是一个危险的事情.

使用StringBuilder类实例可以减少代码,当有许多元素在字符串中连接时,它会有所帮助

Dim mIssues As StringBuilder  = new StringBuilder()

For i = 0 To lstIssues.CheckedItemsCount - 1
  mIssues.AppendFormat("IssueName = '{0}' OR ", lstIssues.CheckedItems(i))
Next

' I suppose that you have a check in place to not allow to run this query if you don't have at 
' least one element checked in the list (if not the WHERE condition will fail)'
mIssues.Length -= 4
Run Code Online (Sandbox Code Playgroud)

这将删除循环中的IF,并且为了删除额外的OR,在退出循环时足以减少StringBuilder实例的长度.
在您的查询文本中,StringBuilder可以使用返回其内部字符串

mIssues.ToString
Run Code Online (Sandbox Code Playgroud)

您也可以尝试将IN sql子句与此类代码一起使用

Dim mIssues As StringBuilder  = new StringBuilder()

For i = 0 To lstIssues.CheckedItemsCount - 1
  mIssues.AppendFormat("'{0}', ", lstIssues.CheckedItems(i))
Next

' I suppose that you have a check in place to not allow this query if you don't have at 
' least one element checked in the list (if not the WHERE condition will fail)'  
mIssues.Length -= 2
mIssues.Insert(0, "IssueName IN(")
mIssues.Append(")")
Run Code Online (Sandbox Code Playgroud)