我刚刚开始了一个项目,该项目涉及为已经由SQL数据库支持的旧Access应用程序构建Web应用程序替换。
我遇到的问题是Access应用程序中有一堆查询使用'* ='作为条件运算符(即“where field1 * ='Something'”)当我运行应用程序时导致它崩溃。
我试图验证操作符是否有效,或者原始开发人员是否已经移交了故意破坏的应用程序版本。
任何人都可以提供验证'* ='(即asterix等于)是否是Access查询中的有效运算符?
答案 0 :(得分:1)
别担心;你的原始开发人员并没有试图故意通过你破碎的代码。只是代码很老了。
*=
(及其对应的=*
)是一个非标准的SQL运算符,最初由Sybase SQL支持,并在90年代中期由Microsoft SQL Server继承。 *=
表示LEFT JOIN
(及其对应=*
表示RIGHT JOIN
) 1
(Microsoft SQL Server最初是Sybase的重新打包版本,由Sybase授权,经过改编和重新编译,可在Microsoft全新的Windows NT操作系统上运行。该合作伙伴关系最终终止,Microsoft在没有Sybase参与的情况下从头开始重写代码,这就是我们今天仍然拥有的产品)
在*=
运营商出现之前,运营商LEFT JOIN
是表达LEFT JOIN
运营的一种方式:
SELECT *
FROM a, b
WHERE a.id *= b.id
与:
相同SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
自SQL Server 2012以来,这些运算符已被弃用了十多年,并且完全不再受支持。在早期版本的SQL Server中使用它们是可能的,但要求整个数据库都有一个名为legacy-mode的设置compatibility_level
设置为80
(“SQL Server 2000模式”)。
Access从未支持这些运营商。 2
您需要找到执行这些外部联接的代码,并使用适当的LEFT JOIN
(或RIGHT JOIN
进行=*
)操作替换它们。
最后,您应该知道*=
不是LEFT JOIN
的精确镜像。我不记得所有细节,但它是这样的:如果只涉及两个表,或者如果有一个中央表,并且所有LEFT JOIN都从中央表转到直接叶表,则可以替换{ {1}} *=
以直截了当的方式。但是,如果外连接跨越两个以上的表,那么LEFT JOIN
的行为与天真的替换不同,您需要更仔细地研究它。我可能错了细节。小心!
1 将*=
这个奇怪的语法与LEFT JOIN
的这个变体进行比较,今天仍然完全可以接受:
INNER JOIN
完全相同:
SELECT *
FROM a, b
WHERE a.id = b.id
2 更新:重新阅读您的问题后,我意识到您正在讨论SQL Server执行的传递查询。然后您的选择取决于您使用的SQL Server版本。
如果您能够针对SQL Server 2008 R2或更早版本运行该应用程序,则可以暂时将SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
切换为80,以便有时间修复查询。
很可能,您遇到此问题正是因为您正试图将数据库移动到比2008 R2更新的SQL Server版本,而不支持compatibility_level
80.当您在比2008 R2更新的SQL Server版本上加载数据库时,该设置会自动增加到您的SQL Server版本支持的最低值(但高于80,将不再支持)。那么你唯一合理的选择就是暂时停留SQL Server 2008 R2(并在必要时将数据库切换回compatibility_level
80),同时修复应用程序查询。