为什么在Access中使用LIKE查询没有返回任何记录?

24

有没有任何理由为什么

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

OleDbAdapter.Fill(DataSet)OleDbCommand.ExecuteReader()运行时为什么没有返回任何记录?

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

 SELECT * FROM MyTable 

返回所有记录。


直接在MS Access中运行SQL查询是什么意思? - StockB
在MS Access中,您可以创建一个查询,在SQL模式下。这就是我想要直接在Access中键入查询的意思。 - Jake
4个回答

34
尝试将 LIKE 改为 ALIKE,并将通配符字符从 * 改为 %
Access 数据库引擎(Jet、ACE 等)有两种ANSI 查询模式,每种模式使用不同的通配符字符来匹配 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 连接时,ADO 总是使用 ANSI-92 查询模式,如果用户在不应该使用 * 字符的地方插入了 * 字符,那么就会出现相同的问题。”
“据我所知,没有办法强制指定使用哪种 ANSI 查询模式来访问 Access 数据库。因此,我认为所有 SQL 代码都应该编写得能够始终一致地运行,无论用户选择使用哪种 ANSI 查询模式。”
“请注意,使用上述示例中的 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谓词时,要比在文本字面值中找到多个*字符的所有实例要容易得多。请记住,“可移植”并不意味着“代码将运行‘as is’”,而是衡量在各个平台之间移动代码的难易程度(请谨记,在同一产品的不同版本之间移动也是一种移植,例如从Jet 4.0到ACE的移植,因为用户级安全性不再起作用,DECIMAL值排序方式不同等)。

ALIKE被其他数据库引擎支持吗?我不知道,我以为它只适用于Jet/ACE。仅仅通过谷歌搜索一分钟,我没有发现任何其他数据库引擎支持ALIKE的证据。 - David-W-Fenton
@onedaywhen:我不明白你所说的“确保所有用户只使用ANSI-92查询模式”的意思。如果你正在构建一个应用程序,你完全可以对此进行控制。如果你有一个Jet/ACE后端想要限制在该模式下运行,你可以为该数据库设置该属性。现在,这对DAO访问该数据库没有任何影响,但这意味着如果有人在Access中打开它,它将使用SQL 92模式。我不知道ODBC是否支持它的任何场景,但我可能是错的。所以,我不理解你的观点。 - David-W-Fenton
1
@David-W-Fenton:“如果你正在构建一个应用程序,你对此有完全的控制...现在,这对DAO访问数据库没有任何影响...我不知道ODBC是否支持它...”--你已经为我证明了一点:你无法控制SQL代码将在哪种ANSI查询模式下执行!如果你认为你可以控制,那么你就是在自欺欺人 :) - onedaywhen
你的意思是使用“%”通配符比使用“*”通配符转换SQL要容易得多吗?对我来说,两种情况下都像是一个简单的搜索和替换,所以我看不出为什么会有人更喜欢其中之一。 - David-W-Fenton
2
@David-W-Fenton:不,我的意思是将ALIKE转换为LIKE比将*转换为%容易得多 - 考虑到您可能正在解析连接的字符串,处理*CHR(42)CHR $(42),而且*字符或42 ASCII代码可能存储在表中!但与ANSI查询模式中立性相比,这只是一个小问题。 - onedaywhen
显示剩余3条评论

27

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

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

1
这个答案没有传达出在某些情况下*是正确的,尽管在其他情况下%是正确的。我的Access 2010数据库更喜欢使用*。请参见下面@onedaywhen的答案。 - CodeMed

5

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

这应该解决问题。


0

哎呀,这个方法可行!非常感谢。

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

我分享我的“故事”,以帮助其他人更容易地找到这篇文章,并节省他们两个小时的搜索时间。

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

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

L


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接