MFC执行Access SQL时通配符*失效,用户表查询误含系统表
问题原因及解决方案
这个问题其实是ADO连接Access时的SQL语法兼容和系统表识别规则差异导致的,我来拆解一下:
1. 通配符失效的根源
Access界面默认使用Jet SQL语法,这里的LIKE操作符用*作为任意字符通配符;但当你用MFC的ADO(基于OLE DB)连接Access时,默认会启用ANSI-92 SQL模式,这种模式下LIKE的通配符是%而不是*。
你的原SQL里写的NAME NOT LIKE 'MSys*'在ANSI模式下,*会被当成普通字符,相当于找名字不是MSys*的对象——但系统表的名字都是MSysObjects、MSysACEs这类,自然不会被过滤掉,所以通配符等于被忽略了。
2. 系统表被包含的额外原因
仅靠TYPE=1在ADO连接里不足以区分用户表和系统表,因为部分系统表在OLE DB的查询视角下,TYPE值也会被标记为1(和用户本地表一致)。这时候需要借助MSYSOBJECTS的FLAGS字段:用户自己创建的表FLAGS值为0,而系统表的FLAGS通常是非0值(比如1)。
修正后的SQL语句
把这两个问题都解决的话,你可以用下面的SQL替换原语句:
SELECT name FROM MSYSOBJECTS WHERE TYPE=1 AND FLAGS=0 AND NAME NOT LIKE 'MSys%'
另一种方案:强制使用Jet SQL模式
如果你不想改通配符,也可以修改ADO的连接字符串,强制让它使用Jet SQL的语法规则,比如在连接字符串里加上:
Jet OLEDB:SQL Query Mode=Jet 4.0;
这样原SQL里的*就能正常作为通配符使用了,但这种方式兼容性稍差,更推荐用ANSI标准的%通配符方案。
内容的提问来源于stack exchange,提问作者Zhang
相关产品推荐
相关产品推荐

