2

これに対する答えを検索して検索しましたが、見つかりません。ユーザーが自分のコンピューターで発生している問題を選択するチェックボックスがあります。チェックされたリスト ボックスには、低速、ウイルス、不良ハード ドライブなどの項目が表示されます。選択内容に基づいて、修理の見積もり費用を伝えます。現在、これがクエリの作成方法です。

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

上記のコードは、選択した課題の数を確認します。問題を 1 つだけ選択すると、次のような文字列が返されます: IssueName = 'Whatever they selected'. 複数の問題を選択した場合は、IssueName = 'Whatever they selected' OR IssueName = 'The second selection' のような文字列が返されます。したがって、基本的に、複数の問題を選択した場合は、すべての選択の間に 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;"

ご覧のとおり、where 句はコードの最初のセクションから来ています。私の質問はこれです、これを行うためのより良い方法はありますか??? 動的な where 句クエリを構築するためのより良い方法が必要であることはわかっています。その方法を知りたいと思っています。あなたが私を助けることができるガイダンスをありがとう.

4

2 に答える 2

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

これにより、ループ内の IF が削除され、余分な OR を削除するには、ループを終了するときに StringBuilder インスタンスの長さを減らすだけで十分です。
クエリ テキストでは、StringBuilder は次を使用して内部文字列を返すことができます

mIssues.ToString

このようなコードで 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(")")
于 2013-05-28T22:00:20.117 に答える