【问题标题】:How can I make MS Access Query Parameters Optional?如何使 MS Access 查询参数可选?
【发布时间】:2010-09-10 22:22:59
【问题描述】:

我想在不同时间以不同方式过滤一个查询。我现在通过在相关查询字段的条件字段中放置参数来完成此操作,但是在许多情况下,我不想过滤给定字段而只想过滤其他字段。有什么方法可以将某种通配符传递给条件参数,以便我可以绕过对该查询的特定调用的过滤?

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    如果您这样构建查询:

    PARAMETERS ParamA Text ( 255 );
    SELECT t.id, t.topic_id
    FROM SomeTable t
    WHERE t.id Like IIf(IsNull([ParamA]),"*",[ParamA])
    

    如果参数不填,将选择所有记录。

    【讨论】:

    • @Chad 我不确定你的意思,也许是PARAMETERS ParamA Text ( 255 ); SELECT IIf(IsNull([ParamA]),"*",[ParamA]) AS Expr1, t.id FROM table1 AS t GROUP BY IIf(IsNull([ParamA]),"*",[ParamA]), t.id HAVING (((t.id) Like IIf(IsNull([ParamA]),"*",[ParamA])));
    【解决方案2】:

    请注意,带有LIKE 关键字的* 通配符只会在ANSI-89 查询模式中产生预期的效果。

    许多人错误地认为 Access/Jet 中的通配符始终是 *。不是这样。 Jet 有两个通配符:ANSI-92 查询模式中的 % 和 ANSI-89 查询模式中的 *。

    ADO 始终是 ANSI-92,DAO 始终是 ANSI-89,但 Access 接口可以是任何一个。

    在数据库对象中使用 LIKE 关键字时(即,将保存在 mdb 文件中的东西),你应该想一想:如果有人使用我通常使用的查询模式以外的查询模式使用这个数据库会发生什么用自己?假设您只想将文本字段限制为数字字符,并且您编写了这样的验证规则:

    NOT LIKE "*[!0-9]*"
    

    如果有人无意中(或以其他方式)通过 ADO 连接到您的 .mdb,则上述验证规则将允许他们添加非数字字符的数据,您的数据完整性将受到影响。不好。

    更好的 IMO 始终为两种 ANSI 查询模式编码。也许这最好通过显式编码两种模式来实现,例如

    NOT LIKE "*[!0-9]*" AND NOT LIKE "%[!0-9]%"
    

    但是随着 Jet SQL DML/DDL 的参与越来越多,这可能变得很难简洁地实现。这就是为什么我建议使用 ALIKE 关键字,它使用 ANSI-92 查询模式通配符,而不管查询模式如何,例如

    NOT ALIKE "%[!0-9]%"
    

    注意 ALIKE 没有记录(我认为这就是我原来的帖子被标记下来的原因)。我已经在 J​​et 3.51 (Access97)、Jet 4.0 (Access2000 to 2003) 和 ACE (Access2007) 中对此进行了测试,并且工作正常。我之前已在新闻组中发布过此内容,并获得了 Access MVP 的批准。通常我自己会避开未记录的功能,但在这种情况下例外,因为 Jet 已被弃用近十年,并且保持它活着的 Access 团队似乎对对引擎进行深度更改(或错误修复! ),具有使喷气发动机成为非常稳定的产品的效果。

    有关 Jet 的 ANSI 查询模式的更多详细信息,请参阅About ANSI SQL query mode

    【讨论】:

    • 实际上,通配符还取决于您使用的数据接口。例如,在通过 ADO 对 SQL Server 执行的 SQL 中,您使用“%”而不是 Jet SQL “*”。
    • 其实Jet有两个通配符:ANSI-92查询模式下的“%”和ANSI-89查询模式下的“*”。 ADO 始终为 ANSI-92,DAO 始终为 ANSI-89,Access 接口都可以。你可能没有意识到这一点,因为你总是使用 DAO。
    • @Air 链接现已修复。
    • 谢谢。我正在寻找一个似乎具有所描述内容的当前 URL,但也许没有。在 2010 年及更高版本的 Access 中,也找不到关于这在多大程度上是一个问题的太多信息。
    【解决方案3】:

    回到我之前的问题中的示例。您的参数化查询是一个看起来像这样的字符串:

    qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]"
    

    根据 fid_Country 的性质(数字、文本、guid、日期等),您必须将其替换为小丑值和特定分隔符:

    qr = replace(qr,"[fid_country]","""*""")
    

    为了完全允许通配符,您的原始查询也可以是:

    qr = "Select Tbl_Country.* From Tbl_Country _
          WHERE id_Country LIKE [fid_country]"
    

    然后您可以获得 fid_Country 的通配符值,例如

    qr = replace(qr,"[fid_country]","G*")
    

    完成后,您可以使用字符串打开记录集

    set rs = currentDb.openRecordset(qr)
    

    【讨论】:

      【解决方案4】:

      我不认为你可以。你是如何运行查询的?

      我会说,如果您需要一个具有这么多开放变量的查询,请将其放入 vba 模块或类中,然后调用它,让它每次都构建字符串。

      【讨论】:

        【解决方案5】:

        我不确定这是否有帮助,因为我怀疑您想通过保存的查询而不是在 VBA 中执行此操作;但是,您可以做的最简单的事情是在 VBA 中逐行构建查询,然后从中创建记录集。

        一个相当老套的方法是动态重写保存的查询,然后访问它;但是,如果您有多个人使用同一个数据库,您可能会遇到冲突,并且您会迷惑下一个开发人员。

        您还可以以编程方式将默认值传递给查询(如您在上一个问题中所讨论的)

        【讨论】:

          【解决方案6】:

          好吧,您可以通过将 * 作为参数传递给您不希望在当前过滤器中使用的字段来返回非空值。在 Access 2003(以及可能的更早和更高版本)中,如果您使用 like [paramName] 作为数字、文本、日期或布尔字段的标准,星号将显示所有记录(与您指定的其他标准匹配)。如果您也想返回空值,那么您可以使用like [paramName] or Is Null 作为标准,以便它返回所有记录。 (如果您在代码中构建查询,则此方法效果最佳。如果您使用的是现有查询,并且您不想在有过滤值时返回空值,则此方法不起作用。)

          如果您要过滤备注字段,则必须尝试其他方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-11-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多