2009-07-30 107 views
0

我有一個高級的搜索,我需要實現一個網站使用C#和SQL Server。這裏的基本思想是:高級搜索使用CheckboxList

  1. 用戶選擇所需的搜索標準 - 城市,州,郵編
  2. 用戶可以選擇可選的搜索條件。這個搜索條件是一個複選框列表。複選框列表是數據綁定到來自sql server的條件列表。
  3. 搜索將針對所有必需的搜索條件進行,如果選擇了任何可選條件,則該條目需要匹配所有可選條件。

我有所需的搜索條件工作,但我無法弄清楚如何執行可選條件。問題在於用戶可以在複選框列表中選擇多個條件,並且所有這些條目都需要匹配。我還需要實現分頁和排序(我正在工作),但這意味着搜索需要在SQL中進行。

有沒有人做過這樣的事情,並有最好的辦法做到這一點的想法?

回答

0

動態建立你的SQL,如以下:

Private Sub LoadData() 
    'Initialize first 
    grdResults.DataSource = Nothing 
    grdResults.DataBind() 
    grdResults.Visible = False 

    grdResultsRequestedBy.DataSource = Nothing 
    grdResultsRequestedBy.DataBind() 
    grdResultsRequestedBy.Visible = False 

    grdResultsCallDate.DataSource = Nothing 
    grdResultsCallDate.DataBind() 
    grdResultsCallDate.Visible = False 

    btnExportToExcel.Visible = False 
    lblNoneFound.Visible = True 

    ' We have to include null values when no value for a given field is provided. 
    ' The like search "%" does not return rows with null values!! 
    Dim strShiftType As String 
    If (ddlShiftType.SelectedValue = "<- All ->") Then 
     strShiftType = "" 
    Else 
     strShiftType = " and sr.Shift_Type_ID = " & "'" & ddlShiftType.SelectedValue & "' " 
    End If 

    ' Only allow good dates 
    ' If one of Start or End is populated the other one will get the same value assigned. 
    ' This avoids unnecessary entry if you deal with a range of one day only! 
    If txtShiftDateRangeStart.Text <> "" And txtShiftDateRangeEnd.Text = "" Then 
     txtShiftDateRangeEnd.Text = txtShiftDateRangeStart.Text 
    End If 
    If txtShiftDateRangeStart.Text = "" And txtShiftDateRangeEnd.Text <> "" Then 
     txtShiftDateRangeStart.Text = txtShiftDateRangeEnd.Text 
    End If 
    Dim strShiftDate As String 
    If txtShiftDateRangeStart.Text <> "" And txtShiftDateRangeEnd.Text <> "" And IsDate(txtShiftDateRangeStart.Text) And IsDate(txtShiftDateRangeEnd.Text) Then 
     strShiftDate = " and (sr.shift_date between " & "'" & txtShiftDateRangeStart.Text & "' and '" & txtShiftDateRangeEnd.Text & "')" 
    Else 
     strShiftDate = "" 
     txtShiftDateRangeStart.Text = "" 
     txtShiftDateRangeEnd.Text = "" 
    End If 

    Dim strRequestedBy As String 
    If (ddlRequestedBy.SelectedValue = "<- All ->") Then 
     strRequestedBy = "" 
    Else 
     strRequestedBy = " and bi.Requested_By = " & "'" & ddlRequestedBy.SelectedValue & "' " 
    End If 

    Dim txtCallNumberlike As String 
    If (txtCallNumber.Text & "%" = "%") Then 
     txtCallNumberlike = "" 
    Else 
     txtCallNumberlike = " and (bi.Call_Number LIKE @CallNumber) " 
    End If 

    ' Only allow good dates 
    ' If one of Start or End is populated the other one will get the same value assigned. 
    ' This avoids unnecessary entry if you deal with a range of one day only! 
    If txtCallDateRangeStart.Text <> "" And txtCallDateRangeEnd.Text = "" Then 
     txtCallDateRangeEnd.Text = txtCallDateRangeStart.Text 
    End If 
    If txtCallDateRangeStart.Text = "" And txtCallDateRangeEnd.Text <> "" Then 
     txtCallDateRangeStart.Text = txtCallDateRangeEnd.Text 
    End If 
    Dim strCallDate As String 
    If txtCallDateRangeStart.Text <> "" And txtCallDateRangeEnd.Text <> "" And IsDate(txtCallDateRangeStart.Text) And IsDate(txtCallDateRangeEnd.Text) Then 
     strCallDate = " and (cast(bi.Call_date as datetime) between " & "'" & txtCallDateRangeStart.Text & "' and '" & txtCallDateRangeEnd.Text & "')" 
    Else 
     strCallDate = "" 
     txtCallDateRangeStart.Text = "" 
     txtCallDateRangeEnd.Text = "" 
    End If 

    Dim strDispatcher As String 
    If (ddlDispatcher.SelectedValue = "<- All ->") Then 
     strDispatcher = "" 
    Else 
     strDispatcher = " and bi.Dispatcher_ID = " & "'" & ddlDispatcher.SelectedValue & "' " 
    End If 

    Dim strEmployeeCompletingBillingInquiry As String 
    If (ddlEmployeeCompletingBillingInquiry.SelectedValue = "<- All ->") Then 
     strEmployeeCompletingBillingInquiry = "" 
    Else 
     strEmployeeCompletingBillingInquiry = " and bi.Employee_Completing_Billing_Inquiry_ID = " & "'" & ddlEmployeeCompletingBillingInquiry.SelectedValue & "' " 
    End If 

    ' Only allow good dates 
    Dim strWhenCreated As String 
    ' If one of Start or End is populated the other one will get the same value assigned. 
    ' This avoids unnecessary entry if you deal with a range of one day only! 
    If txtWhenCreatedRangeStart.Text <> "" And txtWhenCreatedRangeEnd.Text = "" Then 
     txtWhenCreatedRangeEnd.Text = txtWhenCreatedRangeStart.Text 
    End If 
    If txtWhenCreatedRangeStart.Text = "" And txtWhenCreatedRangeEnd.Text <> "" Then 
     txtWhenCreatedRangeStart.Text = txtWhenCreatedRangeEnd.Text 
    End If 
    If txtWhenCreatedRangeStart.Text <> "" And txtWhenCreatedRangeEnd.Text <> "" And IsDate(txtWhenCreatedRangeStart.Text) And IsDate(txtWhenCreatedRangeEnd.Text) Then 
     strWhenCreated = " and (cast(convert(char(10), bi.When_Created, 101) as datetime) between " & "'" & txtWhenCreatedRangeStart.Text & "' and '" & txtWhenCreatedRangeEnd.Text & "')" 
    Else 
     strWhenCreated = "" 
     txtWhenCreatedRangeStart.Text = "" 
     txtWhenCreatedRangeEnd.Text = "" 
    End If 

    Dim strWhoCreated As String 
    If (ddlWhoCreated.SelectedValue = "<- All ->") Then 
     strWhoCreated = "" 
    Else 
     strWhoCreated = " and bi.Who_Created = " & "'" & ddlWhoCreated.SelectedValue & "' " 
    End If 

    ' Only allow good dates 
    ' If one of Start or End is populated the other one will get the same value assigned. 
    ' This avoids unnecessary entry if you deal with a range of one day only! 
    If txtWhenUpdatedRangeStart.Text <> "" And txtWhenUpdatedRangeEnd.Text = "" Then 
     txtWhenUpdatedRangeEnd.Text = txtWhenUpdatedRangeStart.Text 
    End If 
    If txtWhenUpdatedRangeStart.Text = "" And txtWhenUpdatedRangeEnd.Text <> "" Then 
     txtWhenUpdatedRangeStart.Text = txtWhenUpdatedRangeEnd.Text 
    End If 
    Dim strWhenUpdated As String 
    If txtWhenUpdatedRangeStart.Text <> "" And txtWhenUpdatedRangeEnd.Text <> "" And IsDate(txtWhenUpdatedRangeStart.Text) And IsDate(txtWhenUpdatedRangeEnd.Text) Then 
     strWhenUpdated = " and (cast(convert(char(10), bi.When_Updated, 101) as datetime) between " & "'" & txtWhenUpdatedRangeStart.Text & "' and '" & txtWhenUpdatedRangeEnd.Text & "')" 
    Else 
     strWhenUpdated = "" 
     txtWhenUpdatedRangeStart.Text = "" 
     txtWhenUpdatedRangeEnd.Text = "" 
    End If 

    Dim strWhoUpdated As String 
    If (ddlWhoUpdated.SelectedValue = "<- All ->") Then 
     strWhoUpdated = "" 
    Else 
     strWhoUpdated = " and bi.Who_Updated = " & "'" & ddlWhoUpdated.SelectedValue & "' " 
    End If 

    Dim strIsDeleted As String 
    If (ddlIsDeleted.SelectedValue = "<- All ->") Then 
     strIsDeleted = "" 
    Else 
     If ddlIsDeleted.SelectedValue = "False" Then 
      strIsDeleted = " and (bi.IsDeleted = 'F' or bi.IsDeleted is null)" 
     Else 
      strIsDeleted = " and bi.IsDeleted = 'T'" 
     End If 
    End If 

    ' Only allow good dates 
    ' If one of Start or End is populated the other one will get the same value assigned. 
    ' This avoids unnecessary entry if you deal with a range of one day only! 
    If txtWhenDeletedRangeStart.Text <> "" And txtWhenDeletedRangeEnd.Text = "" Then 
     txtWhenDeletedRangeEnd.Text = txtWhenDeletedRangeStart.Text 
    End If 
    If txtWhenDeletedRangeStart.Text = "" And txtWhenDeletedRangeEnd.Text <> "" Then 
     txtWhenDeletedRangeStart.Text = txtWhenDeletedRangeEnd.Text 
    End If 
    Dim strWhenDeleted As String 
    If txtWhenDeletedRangeStart.Text <> "" And txtWhenDeletedRangeEnd.Text <> "" And IsDate(txtWhenDeletedRangeStart.Text) And IsDate(txtWhenDeletedRangeEnd.Text) Then 
     strWhenDeleted = " and (cast(convert(char(10), bi.When_Deleted, 101) as datetime) between " & "'" & txtWhenDeletedRangeStart.Text & "' and '" & txtWhenDeletedRangeEnd.Text & "')" 
    Else 
     strWhenDeleted = "" 
     txtWhenDeletedRangeStart.Text = "" 
     txtWhenDeletedRangeEnd.Text = "" 
    End If 

    Dim strWhoDeleted As String 
    If (ddlWhoDeleted.SelectedValue = "<- All ->") Then 
     strWhoDeleted = "" 
    Else 
     strWhoDeleted = " and bi.Who_Deleted = " & "'" & ddlWhoDeleted.SelectedValue & "' " 
    End If 

    Dim Parameters_Group_In As String 
    Dim Parameters_Effective_Date_In As String 
    Parameters_Group_In = "REQUESTEDBY" 
    Parameters_Effective_Date_In = Now() 

    Dim SelectString As String = "" 
    Dim Error_Message As String = "" 
    Error_Message = BuildSelectString(SelectString) 

    Dim strCommand As String = "" 
    If ViewState("Submit") = "Submit" Then 
     strCommand += " select " & SelectString 
     strCommand += " from " 
     strCommand += " (" 
     strCommand += " select convert(Char(10), sr.shift_date, 101) as ShiftDate, " 
     strCommand += "  case when st.Shift_Desc is null then '' else st.Shift_Desc end + '/' + case when st.Shift_Start_Time is null then '' else st.Shift_Start_Time end + '/' + case when st.Shift_End_Time is null then '' else st.Shift_End_Time end + '/' + cast(st.Shift_Type_ID as varchar) as ShiftType, " 
     strCommand += "  ParamRequestedBy.ParamRequestedByDesc as RequestedBy, " 
     strCommand += "  bi.Call_Number as CallNumber, " 
     strCommand += "  convert(Char(10), bi.Call_Date, 101) as CallDate, " 
     strCommand += "  case when dispatcher.Last_Name is null then '' else dispatcher.Last_Name end + ', ' + case when dispatcher.First_Name is null then '' else dispatcher.First_Name end + '/' + cast(dispatcher.Employee_ID as varchar) as Dispatcher, " 
     strCommand += "  (Select case when Employee.Last_Name is null then '' else Employee.Last_Name end + ', ' + case when Employee.First_Name is null then '' else Employee.First_Name end + '/' + cast(Employee.Employee_ID as varchar) from Employee where Employee.Employee_ID = bi.Dispatcher2_ID) as Dispatcher2, " 
     strCommand += "  (Select case when Employee.Last_Name is null then '' else Employee.Last_Name end + ', ' + case when Employee.First_Name is null then '' else Employee.First_Name end + '/' + cast(Employee.Employee_ID as varchar) from Employee where Employee.Employee_ID = bi.Dispatcher3_ID) as Dispatcher3, " 
     strCommand += "  bi.comments as Comments, " 
     strCommand += "  case when completing.Last_Name is null then '' else completing.Last_Name end + ', ' + case when completing.First_Name is null then '' else completing.First_Name end + '/' + cast(completing.Employee_ID as varchar) as EmployeeCompletingBillingInquiry, " 
     strCommand += "  bi.When_Created as WhenCreated, " 
     strCommand += "  case when Who_Created.Last_Name is null then '' else Who_Created.Last_Name end + ', ' + case when Who_Created.First_Name is null then '' else Who_Created.First_Name end + '/' + cast(Who_Created.Employee_ID as varchar) as WhoCreated, " 
     strCommand += "  bi.When_Updated as WhenUpdated, " 
     strCommand += "  case when Who_Updated.Last_Name is null then '' else Who_Updated.Last_Name end + ', ' + case when Who_Updated.First_Name is null then '' else Who_Updated.First_Name end + '/' + cast(Who_Updated.Employee_ID as varchar) as WhoUpdated, " 
     strCommand += "  case when bi.IsDeleted = 'F' or bi.IsDeleted is null then 'False' else 'True' end as IsDeleted, " 
     strCommand += "  bi.When_Deleted as WhenDeleted, " 
     strCommand += "  case when Who_Deleted.Last_Name is null then '' else Who_Deleted.Last_Name end + ', ' + case when Who_Deleted.First_Name is null then '' else Who_Deleted.First_Name end + '/' + cast(Who_Deleted.Employee_ID as varchar) as WhoDeleted " 
     strCommand += " from billing_inquiries bi " 
     strCommand += "  inner  join Shift_Report sr   on bi.Shift_Report_ID      = sr.Shift_Report_ID " 
     strCommand += "  inner  join Shift_Types st   on sr.Shift_Type_ID       = st.Shift_Type_ID " 
     strCommand += "  inner  join Employee  dispatcher on bi.Dispatcher_ID       = dispatcher.employee_id " 
     strCommand += "  inner  join Employee  completing on bi.Employee_Completing_Billing_Inquiry_ID = completing.employee_id " 
     strCommand += "  left outer join Employee  Who_Created on bi.Who_Created        = Who_Created.Employee_ID " 
     strCommand += "  left outer join Employee  Who_Updated on bi.Who_Updated        = Who_Updated.Employee_ID " 
     strCommand += "  left outer join Employee  Who_Deleted on bi.Who_Deleted        = Who_Deleted.Employee_ID " 
     strCommand += "  inner  join (" 
     strCommand += "      select Parameters_ID as ParamRequestedByID, Parameters_Value as ParamRequestedByDesc " 
     strCommand += "       from Parameters_Details pd1, Parameters_Header ph " 
     strCommand += "       where ph.parameters_group = pd1.parameters_group " 
     strCommand += "       And pd1.parameters_group = @Parameters_Group " 
     strCommand += "       And pd1.parameters_effective_date = " 
     strCommand += "        (select max(pd2.parameters_effective_date) " 
     strCommand += "         from parameters_details pd2 " 
     strCommand += "         where pd2.parameters_group   = pd1.parameters_group " 
     strCommand += "         and pd2.parameters_id    = pd1.parameters_id " 
     strCommand += "         and pd2.parameters_effective_date <= @Parameters_Effective_Date) " 
     strCommand += "      ) ParamRequestedBy on bi.Requested_By = ParamRequestedBy.ParamRequestedByID " 
     strCommand += " where 1=1 " 
     strCommand += strShiftType 
     strCommand += strShiftDate 
     strCommand += strRequestedBy 
     strCommand += txtCallNumberlike 
     strCommand += strCallDate 
     strCommand += strDispatcher 
     strCommand += strEmployeeCompletingBillingInquiry 
     strCommand += strWhenCreated 
     strCommand += strWhoCreated 
     strCommand += strWhenUpdated 
     strCommand += strWhoUpdated 
     strCommand += strIsDeleted 
     strCommand += strWhenDeleted 
     strCommand += strWhoDeleted 
     strCommand += ") as Details " 
    End If 

    If ViewState("Submit") = "SubmitRequestedBy" Then 
     strCommand += "select ParamRequestedBy.ParamRequestedByDesc as RequestedBy, " 
     strCommand += "  count(*) as Count " 
     strCommand += " from billing_inquiries bi " 
     strCommand += "  inner  join Shift_Report sr   on bi.Shift_Report_ID      = sr.Shift_Report_ID " 
     strCommand += "  inner  join Shift_Types st   on sr.Shift_Type_ID       = st.Shift_Type_ID " 
     strCommand += "  inner  join Employee  dispatcher on bi.Dispatcher_ID       = dispatcher.employee_id " 
     strCommand += "  inner  join Employee  completing on bi.Employee_Completing_Billing_Inquiry_ID = completing.employee_id " 
     strCommand += "  left outer join Employee  Who_Created on bi.Who_Created        = Who_Created.Employee_ID " 
     strCommand += "  left outer join Employee  Who_Updated on bi.Who_Updated        = Who_Updated.Employee_ID " 
     strCommand += "  left outer join Employee  Who_Deleted on bi.Who_Deleted        = Who_Deleted.Employee_ID " 
     strCommand += "  inner  join (" 
     strCommand += "      select Parameters_ID as ParamRequestedByID, Parameters_Value as ParamRequestedByDesc " 
     strCommand += "       from Parameters_Details pd1, Parameters_Header ph " 
     strCommand += "       where ph.parameters_group = pd1.parameters_group " 
     strCommand += "       And pd1.parameters_group = @Parameters_Group " 
     strCommand += "       And pd1.parameters_effective_date = " 
     strCommand += "        (select max(pd2.parameters_effective_date) " 
     strCommand += "         from parameters_details pd2 " 
     strCommand += "         where pd2.parameters_group   = pd1.parameters_group " 
     strCommand += "         and pd2.parameters_id    = pd1.parameters_id " 
     strCommand += "         and pd2.parameters_effective_date <= @Parameters_Effective_Date) " 
     strCommand += "      ) ParamRequestedBy on bi.Requested_By = ParamRequestedBy.ParamRequestedByID " 
     strCommand += " where 1=1 " 
     strCommand += strShiftType 
     strCommand += strShiftDate 
     strCommand += strRequestedBy 
     strCommand += txtCallNumberlike 
     strCommand += strCallDate 
     strCommand += strDispatcher 
     strCommand += strEmployeeCompletingBillingInquiry 
     strCommand += strWhenCreated 
     strCommand += strWhoCreated 
     strCommand += strWhenUpdated 
     strCommand += strWhoUpdated 
     strCommand += strIsDeleted 
     strCommand += strWhenDeleted 
     strCommand += strWhoDeleted 
     strCommand += " group by ParamRequestedBy.ParamRequestedByDesc " 
     strCommand += " order by ParamRequestedBy.ParamRequestedByDesc " 
    End If 

    If ViewState("Submit") = "SubmitCallDate" Then 
     strCommand += "select DATENAME(year, Call_Date) + ' ' + case when len(cast(month(Call_Date) as varchar)) = 1 then '0' + cast(month(Call_Date) as varchar) else cast(month(Call_Date) as varchar) end as YearMonth, " 
     strCommand += "  count(*) as Count " 
     strCommand += " from billing_inquiries bi " 
     strCommand += "  inner  join Shift_Report sr   on bi.Shift_Report_ID      = sr.Shift_Report_ID " 
     strCommand += "  inner  join Shift_Types st   on sr.Shift_Type_ID       = st.Shift_Type_ID " 
     strCommand += "  inner  join Employee  dispatcher on bi.Dispatcher_ID       = dispatcher.employee_id " 
     strCommand += "  inner  join Employee  completing on bi.Employee_Completing_Billing_Inquiry_ID = completing.employee_id " 
     strCommand += "  left outer join Employee  Who_Created on bi.Who_Created        = Who_Created.Employee_ID " 
     strCommand += "  left outer join Employee  Who_Updated on bi.Who_Updated        = Who_Updated.Employee_ID " 
     strCommand += "  left outer join Employee  Who_Deleted on bi.Who_Deleted        = Who_Deleted.Employee_ID " 
     strCommand += "  inner  join (" 
     strCommand += "      select Parameters_ID as ParamRequestedByID, Parameters_Value as ParamRequestedByDesc " 
     strCommand += "       from Parameters_Details pd1, Parameters_Header ph " 
     strCommand += "       where ph.parameters_group = pd1.parameters_group " 
     strCommand += "       And pd1.parameters_group = @Parameters_Group " 
     strCommand += "       And pd1.parameters_effective_date = " 
     strCommand += "        (select max(pd2.parameters_effective_date) " 
     strCommand += "         from parameters_details pd2 " 
     strCommand += "         where pd2.parameters_group   = pd1.parameters_group " 
     strCommand += "         and pd2.parameters_id    = pd1.parameters_id " 
     strCommand += "         and pd2.parameters_effective_date <= @Parameters_Effective_Date) " 
     strCommand += "      ) ParamRequestedBy on bi.Requested_By = ParamRequestedBy.ParamRequestedByID " 
     strCommand += " where 1=1 " 
     strCommand += strShiftType 
     strCommand += strShiftDate 
     strCommand += strRequestedBy 
     strCommand += txtCallNumberlike 
     strCommand += strCallDate 
     strCommand += strDispatcher 
     strCommand += strEmployeeCompletingBillingInquiry 
     strCommand += strWhenCreated 
     strCommand += strWhoCreated 
     strCommand += strWhenUpdated 
     strCommand += strWhoUpdated 
     strCommand += strIsDeleted 
     strCommand += strWhenDeleted 
     strCommand += strWhoDeleted 
     strCommand += " group by DATENAME(year, Call_Date) + ' ' + case when len(cast(month(Call_Date) as varchar)) = 1 then '0' + cast(month(Call_Date) as varchar) else cast(month(Call_Date) as varchar) end " 
     strCommand += " order by DATENAME(year, Call_Date) + ' ' + case when len(cast(month(Call_Date) as varchar)) = 1 then '0' + cast(month(Call_Date) as varchar) else cast(month(Call_Date) as varchar) end " 
    End If 

    Dim Parameters_Hashtable As New Hashtable 
    Parameters_Hashtable("@CallNumber") = txtCallNumber.Text & "%" 
    Parameters_Hashtable("@Parameters_Group") = Parameters_Group_In 
    Parameters_Hashtable("@Parameters_Effective_Date") = Parameters_Effective_Date_In 

    Dim dtBillingInquiries As DataTable = DataAccess.GetDataAsDataSet(_ 
               strCommand, _ 
               "BillingInquiries", _ 
               Parameters_Hashtable, _ 
               Error_Message _ 
              ).Tables("BillingInquiries") 
    If (Error_Message = "") Then 
     If ViewState("Submit") = "Submit" Then 
      grdResults.DataSource = dtBillingInquiries 
      If dtBillingInquiries.Rows.Count > 0 Then 
       grdResults.Visible = True 
       grdResults.DataBind() 
       lblNoneFound.Visible = False 
       btnExportToExcel.Visible = True 
      End If 
     End If 
     If ViewState("Submit") = "SubmitRequestedBy" Then 
      grdResultsRequestedBy.DataSource = dtBillingInquiries 
      If dtBillingInquiries.Rows.Count > 0 Then 
       grdResultsRequestedBy.Visible = True 
       grdResultsRequestedBy.DataBind() 

       SetGraph(dtBillingInquiries) 

       lblNoneFound.Visible = False 
       btnExportToExcel.Visible = True 
      End If 
     End If 
     If ViewState("Submit") = "SubmitCallDate" Then 
      grdResultsCallDate.DataSource = dtBillingInquiries 
      If dtBillingInquiries.Rows.Count > 0 Then 
       grdResultsCallDate.Visible = True 
       grdResultsCallDate.DataBind() 

       SetGraph(dtBillingInquiries) 

       lblNoneFound.Visible = False 
       btnExportToExcel.Visible = True 
      End If 
     End If 
    Else 
     lblMessage.Text = Error_Message 
    End If 

End Sub 
+0

你應該使用參數,因爲這樣你纔會被SQL注入攻擊所打開。 –

0

你會在列表中收集到具有循環並用它來修改你的where子句。

當然,除非這是一個絕對不使用敏感數據的應用程序,並且您用來連接到數據庫的用戶完全無法訪問敏感數據,您應該使用存儲過程而不是代碼中的查詢, and you should never use user input directly to build an SQL statement。這意味着您將不得不計劃在存儲過程中使用if語句。

你的存儲過程會是這個樣子:

CREATE PROCEDURE [dbo].[SearchProcedure] 

@FilterByLoginID bit, 
@LoginId varchar(10) 
AS 

DECLARE @SqlQuery varchar (250); 

SET @SqlQuery = 'Select FirstName, LastName FROM CustomerList' 
if @FilterByLoginID = 1 
BEGIN 
    SET @SqlQuery = @SqlQuery + ' WHERE LoginId = ' + CAST(@LoginID AS varchar(10)) 

END 

Execute(@SqlQuery) 

這裏有一個鏈接,讓你去... http://www.codeproject.com/KB/database/Building_Dynamic_SQL.aspx

0

你可以有一個選擇這樣

select * from myTable m 
where m.optional1==$value or $value==-1 
     m.optional2==$value or $value==-1 
.. 

記該「-1」在域中不能是有效的值。

0

我假設你有這樣的事情:

  • 城市(串)
  • 狀態(串)
  • 拉鍊(數/串)
  • 可選條件(字符串項):就這個例子而言,我將假設一個軟件領域 - 說它就像電視提供商。所以一個示例選項是:hasExpandedTVPackage,hasHBOpackage等,因爲checkBoxes只提供一個bool開啓/關閉數據。

因此,例如,您在頁面上有兩個複選框項目:[]也有擴展包[]也有HBO。等等 - 基本上是'找到所有居住在城市,州,郵編的人(如果選擇HBO的話),並且還支付了HBO套餐的費用。

現在,如果你自己寫了SQL,它會是「SELECT * FROM Users WHERE State = @State AND City = @City AND ZipCode = @ZipCode AND HasHboPackage = 1」。但是我們需要使用動態SQL將它們放在一起。

我的建議是把一個表放在一起並在那裏創建額外的SQL位,所以你傳遞給存儲過程的就是選擇項的ID(不傳輸輸入數據)。示例代碼:

DECLARE @Items TABLE 
(
    ID INT, 
    DisplayName VARCHAR(200), 
    SQLStatement VARCHAR(200) 
) 

INSERT INTO @Items (ID, DisplayName, SQLStatement) VALUES (1, 'Has Expanded Package', 'HasExpandedPackage = 1') 
INSERT INTO @Items (ID, DisplayName, SQLStatement) VALUES (2, 'Has HBO Package', 'HasHBOPackage = 1') 

SELECT * FROM @Items 

DECLARE @City VARCHAR(200) 
DECLARE @State VARCHAR(2) 
DECLARE @ZipCode VARCHAR(5) 
DECLARE @Statement VARCHAR(1000) 
DECLARE @SelectedOptions VARCHAR(30) 

SET @City = 'Dallas' 
SET @State = 'TX' 
SET @ZipCode = '12345' 
SET @SelectedOptions = '2' 

DECLARE @TempOptionsTable TABLE 
(
    OptionID VARCHAR(3) 
) 

DECLARE @Delimiter VARCHAR(1) 
DECLARE @StartPosition INT 
DECLARE @Length INT 
DECLARE @Item VARCHAR(3) 

SET @Delimiter = ',' 

WHILE LEN(@SelectedOptions) > 0 
BEGIN 
    SET @StartPosition = CHARINDEX(@Delimiter, @SelectedOptions) 

    IF @StartPosition < 0 
    BEGIN 
     SET @StartPosition = 0 
    END 

    SET @Length = LEN(@SelectedOptions) - @StartPosition - 1 

    IF @Length < 0 
    BEGIN 
     SET @Length = 0 
    END 

    IF @StartPosition > 0 
    BEGIN 
     SET @Item = SUBSTRING(@SelectedOptions, 1, @StartPosition - 1) 
     SET @SelectedOptions = SUBSTRING(@SelectedOptions, @StartPosition + 1, LEN(@SelectedOptions) - @StartPosition) 
    END 
    ELSE 
    BEGIN 
     SET @Item = @SelectedOptions 
     SET @SelectedOptions = '' 
    END 

    INSERT INTO @TempOptionsTable (OptionID) VALUES (@Item) 
END 

DECLARE @StatementTable TABLE 
(
    StatementID INT IDENTITY, 
    OptionID INT, 
    SQLStatement VARCHAR(200) 
) 

SELECT * FROM @StatementTable 

--SELECT I.* FROM @TempOptionsTable TOT INNER JOIN @Items I ON I.ID = TOT.OptionID 

INSERT INTO @StatementTable 
SELECT I.ID, I.SQLStatement FROM @TempOptionsTable TOT INNER JOIN @Items I ON I.ID = TOT.OptionID 

SELECT * FROM @StatementTable 

DECLARE @Iterator INT 
DECLARE @MaxIndex INT 
DECLARE @TempStatement VARCHAR(200) 

SELECT @Iterator = MIN(StatementID) FROM @StatementTable 
SELECT @MaxIndex = MAX(StatementID) FROM @StatementTable 

SELECT @Iterator, @MaxIndex 

SELECT @Statement = 'SELECT * FROM Users WHERE City = ''' + @City + ''' AND State = ''' + @State + ''' AND ZipCode = ''' + @ZipCode + '''' 

SELECT @Statement 

WHILE @Iterator < (@MaxIndex + 1) 
BEGIN 
    SELECT @TempStatement = SQLStatement FROM @StatementTable WHERE StatementID = @Iterator 

    SET @Statement = @Statement + ' AND ' + @TempStatement 

    SET @Iterator = @Iterator + 1 
END 

SELECT @Statement 

--EXEC(@Statement) 

這樣,您只需在語句表中添加新記錄,即刻獲取數據綁定和額外的搜索功能。您需要確保城市狀態和郵政編碼字段已被正確清理,因爲如果這些字段是開放文本字段(而不是下拉菜單或其他字段),它們可能會被利用到SQL注入中。