使用CheckboxList进行高级搜索

时间:2009-07-30 17:54:00

标签: c# sql-server search

我需要为使用C#和SQL Server的网站实现高级搜索。这是基本的想法:

  1. 用户选择所需的搜索条件 - 城市,州,邮政
  2. 用户可以选择可选的搜索条件。此搜索条件是一个复选框列表。复选框列表将数据绑定到sql server的条件列表。
  3. 搜索所有必需的搜索条件,如果选择了任何可选条件,则该项目需要匹配所有可选条件。
  4. 我有所需的搜索条件,但我无法弄清楚如何执行可选标准。问题在于用户可以在复选框列表中选择多个条件,并且所有这些项目都需要匹配。我还需要实现分页和排序(我已经工作),但这意味着搜索需要在SQL中进行。

    有没有人之前做过这样的事情并且有最好的方法可以做到这一点?

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:0)

你可以选择这样的

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

请注意,“ - 1”不能是域中的有效值。

答案 3 :(得分:0)

我假设你有类似的东西:

  • city(string)
  • 州(字符串)
  • zip(数字/字符串)
  • 可选标准(字符串项):出于本示例的目的,我将假设一个软件域 - 比如电视提供商。所以一个示例选项是:hasExpandedTVPackage,hasHBOpackage等,因为checkBox只提供一个bool开/关数据。

例如,页面上有两个复选框项:[]还有Expanded Package []还有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注入。