针对 Access 2010 DB 的 SQL 语句不适用于 ODBC
Posted
技术标签:
【中文标题】针对 Access 2010 DB 的 SQL 语句不适用于 ODBC【英文标题】:SQL statement against Access 2010 DB not working with ODBC 【发布时间】:2012-09-21 21:00:09 【问题描述】:我正在尝试对 Access DB 运行一个简单的语句来查找记录。
记录中的数据验证非常糟糕,我无法对其进行清理。意思是,它必须保持原样。
我需要能够搜索删除了空格和连字符的字符串。以下语句适用于 Access 2010 direct:
select * from dummy where Replace(Replace([data1],' ',''),'-','') = 'ABCD1234';
通过 php 从 ODBC 连接运行它不会。它会产生以下错误:
SQL error: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression., SQL state 37000 in SQLExecDirect
在运行函数的数据库中创建查询并尝试间接搜索其值会导致相同的错误:
select * from dummy_indirect where Expr1 = 'ABCD1234';
我尝试使用现有的两个 ODBC 驱动程序。 ODBCJR32.dll (03/22/2010) 和 ACEODBC.dll (02/18/2007)。据我所知,这些应该是最新的,因为它与完整的 Access 2010 和 Access 2010 数据库引擎一起安装。
欢迎任何关于如何解决此错误并达到相同效果的想法。请注意,我无法更改数据库的方式、形状或形式。该间接查询是在另一个 mdb 文件中创建的,该文件具有从原始 DB 链接的原始表。
* 更新 *
OleDB 并没有真正影响任何事情。
$dsn= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\dummy.mdb;";
我也没有尝试将其用作 Web 后端。我不是施虐狂。
有一个我必须支持的旧系统确实使用 Access 作为后端。数据来自其他旧系统,我必须将其集成到更现代的系统中。因此,使用 Apache/PHP 创建一个 API,该 API 在支持遗留系统的服务器上运行。
我需要能够搜索具有字母数字大小写标识符的表,以获取唯一且与生成器相关联的数字标识符(访问中的自动编号)。用户多年来一直将其用作垃圾箱(数据输入不一致,带有零星符号),因此我唯一的解决方案是从字段值和搜索值中删除除字母数字之外的所有内容,并尝试对其执行 LIKE 比较。
如果不支持访问的 replace(),存在哪些 ODBC 兼容函数可以用来进行相同类型的比较?
【问题讨论】:
Access db 引擎支持所有应用程序上下文中的一组标准函数。其他函数(例如Replace()
)和用户定义的函数(例如您的 dummy_indirect()
)仅在 Access 应用程序实例中受支持。当您使用 ODBC 访问您的数据库时,Access 本身没有运行......所以这些功能不可用。
dummy_indirect 是一个查询。 ODBC 支持哪些功能?在任何地方都很难找到列表。有没有类似replace的东西?
抱歉,我对 dummy_indirect 感到困惑。但是,如果它是另一个使用 Replace()
的查询,则 db 引擎仍然无法识别该函数,除非它从 Access 应用程序实例中运行。
【参考方案1】:
回顾一下,除非您的查询是在 Access 应用程序会话中运行的,否则 Access 数据库引擎将无法识别 Replace()
函数。来自 Access 外部的任何尝试都将触发“未定义函数”错误消息。您无法通过从 ODBC 切换到 OleDb 作为连接方法来避免错误。而且您也不能通过将Replace()
隐藏在单独的查询中(在同一个或另一个 Access db 中)并将该查询用作主查询的数据源来欺骗引擎。
此行为由Access' sandbox mode 确定。该链接页面包含在默认沙盒模式下可用的功能列表。该页面还介绍了如何更改沙盒模式。如果您绝对必须有Replace()
可用于您的查询,也许最低设置 (0) 将允许它。但是,我不建议您这样做。我自己从来没有做过,所以不知道后果。
至于Replace()
的替代品,了解您正在搜索的值的可变性会有所帮助。如果空格或破折号仅出现在一个或几个一致的位置,您可以使用Like
表达式进行模式匹配。例如,如果搜索字段值由 4 个字母、一个可选的空格或破折号以及后跟 4 个数字组成,则类似这样的 WHERE
子句应该适用于“ABCD1234”的变体:
SELECT * FROM dummy
WHERE
data1 = 'ABCD1234'
OR data1 Like 'ABCD[- ]1234';
另一种可能性是与值列表进行比较:
SELECT * FROM dummy
WHERE
data1 IN ('ABCD1234','ABCD 1234','ABCD-1234');
但是,如果您的搜索字段值可以在字符串中的任何位置包含任意数量的空格或破折号,那么这种方法就不好用了。而且我会非常努力地寻找某种方法来简化查询任务:
-
您无法清除存储的值,因为您被禁止以任何方式更改原始 Access 数据库。也许您可以创建一个新的 Access db,导入数据,然后清理它。
将原始 Access db 设置为 SQL Server 中的链接服务器并构建查询以利用 SQL Server 功能。
投降。 :-( 将更大的数据集拉入您的 PHP 客户端代码,并评估使用哪些行与忽略哪些行。
【讨论】:
啊。谢谢你的名单。我可以试试 Sandbox 0,看看它是否给了我替换功能。至于其他建议,1)数据库与遗留系统一起创建新数据。 2) 见 1. 3) 听起来越来越像明智的选择..... :( 你的情况听起来太像卡在岩石和坚硬的地方了。你有我的同情……对你有好处。就像我说的,我从来没有摆弄过沙盒设置。这种前景让我很焦虑。如果它以某种方式爆炸,请不要怪我。 ;) 祝你好运。 值的可变性非常大。案例标识符的 23 种不同模式。 23。许多模式,天知道为什么,具有与存储方式不同的显示模式(例如电话号码),并且在直接存储与自动输入时没有输入验证。因此,从显示复制到字段并存储的值与自动输入不同。有时使用 0 字符而不是连字符。还在想那个。是的.......把所有东西都剥离到 alphnum 是我唯一的机会,但它已经被鱼雷破坏了。【参考方案2】:我不确定您是否可以使用 ODBC 和您的约束来做到这一点。 MS Access driver is limited(设计使然;MS 希望您将 SQL Server 用于后端)。
你可以使用 OLEDB 吗?这可能是一个选择。
【讨论】:
你无法避免 OleDb 的问题。这是数据库引擎的限制......连接方法无关紧要。他只能在实际的 Access 应用程序会话中使用这些函数运行查询。 “设计使然;MS 希望您将 SQL Server 用于后端”我非常怀疑这一点。 SQL server 完全不适合非常小的用户。 我的意思是“高级”的东西,比如将它用作 Web 后端。无论如何,这就是 MS 的 Access Dev 告诉我的。关键是,“不要指望 MS 在这方面提供大量支持”以上是关于针对 Access 2010 DB 的 SQL 语句不适用于 ODBC的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MS Access VB 中访问 SQL Server 标量函数
SQL 2005 使用 PHP 链接 Access 2003 DB 高级子查询