【问题标题】:Why does a LIKE query in Access not return any records?为什么 Access 中的 LIKE 查询不返回任何记录?
【发布时间】:2011-07-07 05:13:54
【问题描述】:

有什么原因吗

SELECT * FROM MyTable WHERE [_Items] LIKE '*SPI*'

不返回任何带有OleDbAdapter.Fill(DataSet)OleDbCommand.ExecuteReader() 的记录?

当我直接在 MS Access 中运行相同的 SQL 时,它会返回预期的记录。此外,在相同的代码中,如果我将 SQL 更改为

 SELECT * FROM MyTable 

返回所有记录。

【问题讨论】:

  • “直接在 MS Access 中”运行 SQL 查询到底是什么意思?
  • 在 MS Access 中,您可以在 SQL 模式下创建查询。这就是我要直接在 Access 中键入查询的意思。

标签: sql ms-access oledbcommand


【解决方案1】:

尝试将LIKE 更改为ALIKE,并将您的通配符从* 更改为%

Access 数据库引擎(Jet、ACE 等)有两个 ANSI Query Modes,每个 LIKE 使用不同的通配符:

  • ANSI-89 查询模式使用*

  • ANSI-92 查询模式使用%

OLE DB 始终使用 ANSI-92 查询模式。 DAO 始终使用 ANSI-89 查询模式。 Access UI 可以设置为使用其中一种。

但是,当使用 ALIKE 关键字时,通配符始终为 %,无论 ANSI 查询模式如何。

考虑一个业务规则,它规定一个数据元素必须正好包含八个数字字符。假设我按如下方式实施规则:

CREATE TABLE MyStuff 
(
 ID CHAR(8) NOT NULL, 
 CHECK (ID NOT LIKE '%[!0-9]%')
);

我不可避免地会使用% 作为通配符,因为Access 的CHAR 数据类型和CHECK 约束只能在ANSI-92 查询模式下创建。

但是,有人可以使用 DAO 访问数据库,它始终使用 ANS-89 查询模式,% 字符将被视为文字而不是“特殊”字符,并且可以执行以下代码:

INSERT INTO MyStuff (ID) VALUES ('%[!0-9]%');

插入会成功,我的数据完整性会被破坏:(

在 ANSI-89 查询模式下创建的验证规则中使用 LIKE* 以及使用 ADO 连接的人(始终使用 ANSI-92 查询模式)并插入 * * 字符不应该出现的字符。

据我所知,没有办法规定使用哪种 ANSI 查询模式来访问自己的 Access 数据库。因此,我认为无论用户选择何种 ANSI 查询模式,所有 SQL 都应编码为一致的行为。

请注意,在上面的示例中使用LIKE 对两者进行编码并不难,例如

CHECK (
       ID NOT LIKE '%[!0-9]%'
       AND ID NOT LIKE '*[!0-9]*'
      )

...或者确实完全避免使用通配符,例如

CHECK (ID LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')

但是,使用 ALIKE 将减少冗长的代码,即更容易被人类阅读,因此更容易维护。

此外,当需要移植到符合 SQL 标准的 SQL 产品时,ALIKE 也可以很好地移植,即将 ALIKE 关键字转换为 LIKE 就足够了。在解析给定的 SQL 谓词时,找到一个 LIKE 关键字比在文本文字中找到 * 字符的所有多个实例要容易得多。请记住,“可移植”并不意味着“代码将按原样运行”;相反,它是衡量在平台之间移动代码的难易程度(请记住,在同一产品的不同版本之间移动是一个端口,例如 Jet 4.0 到 ACE 是一个端口,因为用户级安全不再起作用,@987654350 @ 值的排序方式不同,等等)。

【讨论】:

  • 我假设ALIKEANSI LIKE 的缩写。除了外国人访问之外,我认为它没有任何用处。这意味着您最终会编写不可移植的 SQL,但实际上,重要的是您的数据接口方法。如果您是来自 Access 外部的难民,并且下意识地必须使用 % 作为通配符,那么您所要做的就是确保始终使用将使用 ANSI 92 模式的数据访问方法。这将产生可移植的 SQL,并且没有像 ALIKE 这样的专有组件。真的,如果你要使用 ALIKE,你不妨只使用 * -- 两者都是不可移植的。
  • @David-W-Fenton:“您所要做的就是确保始终使用将使用 ANSI 92 模式的数据访问方法”——相反,必须确保 所有 用户只使用 ANSI-92 查询模式,但如何做到这一点?据我所知,这是不可能的。因此,您需要同时处理 ANSI 查询模式或将您的客户端暴露给数据完整性问题。此外,ALIKE 是高度可移植的,比使用 LIKE + * 更便携。我已经相应地更新了我的答案。
  • ALIKE 是否被其他数据库引擎支持?我不知道——我认为它是特定于 Jet/ACE 的。仅通过谷歌搜索一分钟,我发现没有任何其他数据库引擎支持 ALIKE 的证据。
  • @David-W-Fenton:“如果你正在构建一个应用程序,你就可以完全控制它......现在,这对访问该数据库没有任何影响来自 DAO...我不知道 ODBC 支持它...”——您已经为我指出了一点:您无法控制您的 SQL 代码将在其中执行的 ANSI 查询模式!如果你认为你这样做了,那你就是在开玩笑:)
  • @David-W-Fenton: 不,我的意思是将ALIKE 转换为LIKE 比将* 转换为% 要容易得多——考虑一下你可能是解析连接的字符串,处理*CHR(42)CHR$(42),并且* 字符或42 ascii 代码可以存储在一个表中!但与 ANSI 查询模式中立性相比,这是一个小问题。
【解决方案2】:

* 更改为%,因为% 是使用OLE DB 时的通配符搜索。

SELECT * FROM MyTable WHERE [_Items] LIKE '%SPI%' 

【讨论】:

  • 这个答案无法传达* 在某些情况下是正确的,尽管% 在其他情况下是正确的。我的 access 2010 数据库更喜欢*。请参阅下面@onedaywhen 的答案。
【解决方案3】:

尝试将通配符 (*) 转换为 %

这应该可以解决问题。

【讨论】:

    【解决方案4】:

    天哪,这行得通! 非常感谢。

    我只需要将not like criteria 替换为not alike criteria

    我分享我的“故事”是为了帮助其他人更轻松地找到这篇文章,并让他们免于两个小时的搜索。

    虽然我已将 Excel 95-97 xls 文件链接到 Access 2010 数据库,并运行 create tableinsert into 查询以将所有数据导入数据库,但出于某种奇怪的原因,选择查询无法找到我输入的字符串。

    我尝试了not like "something"not like "%something%",但没有成功 - 根本没用。

    L

    【讨论】:

      猜你喜欢
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多