为什么Access中的LIKE查询不返回任何记录?

Jak*_*ake 20 sql ms-access oledbcommand

有什么理由吗?

SELECT * FROM MyTable WHERE [_Items] LIKE '*SPI*'
Run Code Online (Sandbox Code Playgroud)

没有返回任何记录OleDbAdapter.Fill(DataSet)OleDbCommand.ExecuteReader()

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

 SELECT * FROM MyTable 
Run Code Online (Sandbox Code Playgroud)

返回所有记录.

one*_*hen 30

尝试改变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]%')
);
Run Code Online (Sandbox Code Playgroud)

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

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

INSERT INTO MyStuff (ID) VALUES ('%[!0-9]%');
Run Code Online (Sandbox Code Playgroud)

插入将成功,我的数据完整性将被拍摄:(

通过使用LIKE*在ANSI-89查询模式下创建的验证规则和使用ADO连接的人(始终使用ANSI-92查询模式)和INSERT(字符不应该**字符)可以说同样的情况.

据我所知,没有办法强制使用哪种ANSI查询模式来访问一个Access数据库.因此,我认为所有SQL都应编码为一致,无论用户选择的ANSI查询模式如何.

请注意,使用LIKE上述示例进行编码并不太困难,例如

CHECK (
       ID NOT LIKE '%[!0-9]%'
       AND ID NOT LIKE '*[!0-9]*'
      )
Run Code Online (Sandbox Code Playgroud)

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

CHECK (ID LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')
Run Code Online (Sandbox Code Playgroud)

但是,使用ALIKE将导致更简洁的代码,即人类读者更容易,因此更容易维护.

此外,当需要移植到符合SQL标准的SQL产品时,ALIKE端口也很好,即将ALIKE关键字转换LIKE为所需的全部内容.在解析给定的SQL谓词时,找到一个LIKE关键字远比*在文本文字中找到该字符的所有多个实例要容易得多.请记住,"便携式"并不意味着"代码将按原样运行"; 相反,它衡量在平台之间移动代码是多么容易(并且要记住,在同一产品的版本之间移动是一个端口,例如Jet 4.0到ACE是一个端口,因为用户级安全性不再起作用,DECIMAL值排序不同的,等等).

  • @onedaywhen为我+1学习有关“ ALIKE”的新知识。谢谢。 (2认同)
  • @ David-W-Fenton:不,我的意思是将`ALIKE`转换为`LIKE'要比将`*`转换为'%`更容易 - 考虑到你可能正在解析连接的字符串,处理`*`,`CHR(42)`和`CHR $(42)`,并且`*`字符或`42`ascii代码可以存储在表格中!但与ANSI查询模式中性相比,这是一个小问题. (2认同)

Nei*_*ght 24

更改您*%%使用OLE DB时是通配符搜索.

SELECT * FROM MyTable WHERE [_Items] LIKE '%SPI%' 
Run Code Online (Sandbox Code Playgroud)


Poo*_*oli 5

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

这应该排除问题.