参数表单输入具有多个字段的查询条件,具有值或空值

时间:2017-10-23 17:03:56

标签: sql ms-access parameterized-query

我已经构建了一个带有未绑定字段的表单,以便用户可以输入日期范围,设施名称(这些来自组合框),以及用于在Access中生成查询的徽章编号。如果字段留空,我希望能够在所选设施的所选日期范围内返回结果,或者只选择特定设施的结果。我还希望能够将结果限制为与人的徽章编号匹配的结果。

所以我想要的可能性是:

  1. 日期范围=由用户|定义设施 - 如果没有选择所有|徽章#=全部如果未选中
  2. 日期范围=由用户|定义设施 - 如果没有选择所有|徽章#=由用户
  3. 定义
  4. 日期范围=由用户|定义设施 - 由用户定义|徽章#=全部如果未选中
  5. 日期范围=由用户|定义设施 - 由用户定义|徽章#=由用户
  6. 定义

    我最初使用日期范围和设施名称构建它,它工作正常。当我尝试添加徽章#时,它确实无法正常工作。

    我的SQL for WHERE TO部分是:

    WHERE (((Diversion.Transaction_Date) Between [Forms]![Parameters]![FromDate] And [Forms]![Parameters]![ToDate]) 
    AND ((Diversion.Employee_Badge_Number)=[Forms]![Parameters]![BadgeNumber]) 
    AND ((Diversion.Facility)=[Forms]![Parameters]![FacilitySelect])) 
    OR (((Diversion.Transaction_Date) Between [Forms]![Parameters]![FromDate] And [Forms]![Parameters]![ToDate]) 
    AND ((Diversion.Facility)=[Forms]![Parameters]![FacilitySelect]) 
    AND ((([Diversion].[Employee_Badge_Number]) Like [Forms]![Parameters]![BadgeNumber]) Is Null)) 
    OR (((Diversion.Transaction_Date) Between [Forms]![Parameters]![FromDate] And [Forms]![Parameters]![ToDate]) 
    AND ((Diversion.Employee_Badge_Number)=[Forms]![Parameters]![BadgeNumber]) 
    AND ((([Diversion].[Facility]) Like [Forms]![Parameters]![FacilitySelect]) Is Null)) 
    OR (((Diversion.Transaction_Date) Between [Forms]![Parameters]![FromDate] And [Forms]![Parameters]![ToDate]) 
    AND ((([Diversion].[Employee_Badge_Number]) Like [Forms]![Parameters]![BadgeNumber]) Is Null) 
    AND ((([Diversion].[Facility]) Like [Forms]![Parameters]![FacilitySelect]) Is Null)) 
    OR (((([Diversion].[Facility]) Like [Forms]![Parameters]![FacilitySelect]) Is Null));
    

    对我而言,它似乎包含了我想从表单中获得的四个可能的结果,但它不能正常工作。例如,如果我将设施字段留空,并定义徽章编号,它仍然会给我所有结果。如果我定义设施并定义徽章编号,它确实给我正确的结果。

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这可能会为您提供构建具有多个条件值的动态查询的一些想法。在此示例中,用户可以选择任意数量的标准。它是用VB.Net编写的。它适用于Access。我检查每个字段以查看是否提供了任何条件,然后在有有效值的情况下将其附加到查询中。 我使用Interpolated字符串只是因为它更容易看到空格去向何处。替代方案是:

String.Format("RoasterId = {0} ", itgRoaster)

我还使用了一个字符串构建器,它是一种有效的方法来更改字符串,而无需为每个附加创建和处理字符串。如果在VBA中不可用,您可以使用&=

Dim bolNeedAnd As Boolean = False
        Dim sb As New Text.StringBuilder
        sb.Append("SELECT Coffees.ID, Coffees.[Name], Coffees.RoasterID, Roasters.[Name], Coffees.[Type],Coffees.Rating, Coffees.Comment, Coffees.Description, Coffees.Roast, Coffees.IsExtraBold, Coffees.IsFavorite
    From Coffees Inner Join Roasters on Coffees.RoasterID = Roasters.ID Where ")
        If itgRoaster <> 0 Then
            sb.Append($"RoasterID = {itgRoaster} ")
            bolNeedAnd = True
        End If
        If strRoast <> "" Then
            If bolNeedAnd Then
                sb.Append($"AND Roast = '{strRoast}' ")
            Else
                sb.Append($"Roast = '{strRoast}' ")
            End If
            bolNeedAnd = True
        End If
        If strType <> "" Then
            If bolNeedAnd Then
                sb.Append($"AND Type = '{strType}' ")
            Else
                sb.Append($"Type = '{strType}' ")
            End If
            bolNeedAnd = True
        End If
        If strRating <> "" Then
            If bolNeedAnd Then
                sb.Append($"AND Rating = '{strRating}' ")
            Else
                sb.Append($"Rating = '{strRating}' ")
            End If
            bolNeedAnd = True
        End If
        If bolBold Then
            If bolNeedAnd Then
                sb.Append("AND IsExtraBold = 1 ")
            Else
                sb.Append("IsExtraBold = 1 ")
            End If
            bolNeedAnd = True
        End If
        If bolFavorite Then
            If bolNeedAnd Then
                sb.Append("AND IsFavorite = 1 ")
            Else
                sb.Append("IsFavorite = 1 ")
            End If
        End If
        sb.Append("Order By Coffees.[Name];")
        Debug.Print(sb.ToString)

        Dim cmd As New OleDbCommand With {
            .Connection = cn,
            .CommandType = CommandType.Text,
            .CommandText = sb.ToString}