【问题标题】:Problems with Recordset Filter记录集过滤器的问题
【发布时间】:2009-10-02 17:24:47
【问题描述】:

我在使用旧版 ASP 经典代码中的 ADO 记录集上的过滤器时遇到了问题,我正在尝试了解我正在尝试执行的操作是否不受支持,或者我是否只是做错了。

我有一个项目记录集,它们的状态为 1(活动)或 0(非活动),以及可选的 End_Date。在我的管理用户界面中,我有一个控件来显示所有项目或仅显示应向最终用户显示的项目:Status = 1 AND ( End_Date is null OR End_Date > Date() )

为了实现这个逻辑,我尝试了:

rs.Filter = "Status = 1 AND ( End_Date = null OR End_Date > #" & Date() & "# )"

但我明白了

ADODB.Recordset (0x800A0BB9)
Unknown runtime error

经过多次鬼混,ADO 似乎不喜欢将 End_Date 条件与 AND 条件结合使用的分组括号。如果我把括号拿出来,这行得通:

rs.Filter = "Status = 1 AND End_Date = null OR End_Date > #" & Date() & "#"

但这只是一个意外——看起来过滤条件是按顺序评估的,所以我得到了我想要的结果。如果我将 AND 更改为 OR,则括号起作用:

rs.Filter = "Status = 1 OR ( End_Date = null OR End_Date > #" & Date() & "# )"

当然,这个逻辑是错误的——它显示的是 Active but expired items。

奇怪的是,如果我移动条件,它会再次中断:

rs.Filter = "End_Date = null OR Status = 1 AND End_Date > #" & Date() & "# "

由于相同的 ADODB 错误而崩溃。

我似乎无法预测什么会起作用,什么不会起作用,而且我读过的文档对预期的语法(它不是纯 T-SQL!)、限制等以及所有我见过的例子最多有两个条件。我不认为我的条件那么复杂。谁能告诉我是否支持我正在尝试做的事情,是否有更好的方法来做,或者向我指出符合这种逻辑的综合文档和示例?

谢谢!

【问题讨论】:

    标签: asp-classic vbscript filter ado recordset


    【解决方案1】:

    ADO Recordset Object Filter Property:

    AND 和 OR 之间没有优先级。子句可以在括号内分组。但是,您不能对通过 OR 连接的子句进行分组,然后使用 AND 将该组连接到另一个子句,如下所示:

    (姓氏 = '史密斯' 或姓氏 = '琼斯') AND FirstName = '约翰'

    相反,您将构建这个 过滤为:

    (姓氏 = '史密斯' AND 名字 = '约翰') 或

    (姓氏 = '琼斯' AND 名字 = '约翰')

    所以你必须像这样构建你的过滤器:

    rs.Filter = "( Status = 1 AND End_Date = null ) OR ( Status = 1 AND End_Date > #" & Date() & "# )"
    

    【讨论】:

    • Bertine,谢谢——这正是我想要的!在您发布此内容后,我能够使用 ChiliSoft 描述在technet.microsoft.com/en-us/library/… 找到 MS ADO 过滤器属性文档,其中非常清楚过滤器子句中可接受的运算符组合。不知道我以前是怎么想念他们的;谢谢你指路! – 瓦尔
    【解决方案2】:

    我知道您正在使用遗留代码,并且可能还有其他东西正在运行,但是您如何在此特定页面中打开记录集?您是否使用了一些在 adovbs.inc 中定义的常量?

    例如:

    rs.Open "SELECT * FROM table1", db, adOpenStatic, adLockPessimistic
    

    【讨论】:

    • 为了获取记录集,我使用实用程序类来调用存储过程。该类在 ADODB.Recordset 对象上设置以下属性: .CursorLocation = adUseClient .CursorType = adOpenStatic .LockType = adLockBatchOptimistic
    【解决方案3】:

    当你尝试这个时会发生什么......

    Dim strToday
    strToday = Now()
    rs.Filter = "Status=1 AND (End_Date = null OR End_Date > """ & strToday & """)" 
    

    【讨论】:

    • 不,crashola。请参阅 Bertine 的回答和链接的文档。 OR 只能出现在顶级子句之间,因此第一个词 (status=1) 必须出现在两个子句中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多