Answers:
在解析期间,SQL Server调用sqllang!DecodeCompOp以确定存在的比较运算符的类型:
在优化程序中的任何事情涉及之前,这种情况就发生了。
使用调试器和公共符号*跟踪代码,sqllang!DecodeCompOp在寄存器eax**中返回一个值,如下所示:
╔════╦══════╗
║ Op ║ Code ║
╠════╬══════╣
║ < ║ 1 ║
║ = ║ 2 ║
║ <= ║ 3 ║
║ !> ║ 3 ║
║ > ║ 4 ║
║ <> ║ 5 ║
║ != ║ 5 ║
║ >= ║ 6 ║
║ !< ║ 6 ║
╚════╩══════╝
!=并且<>都返回5,因此在以后的所有操作(包括编译和优化)中都是无法区分的。
虽然继发于以上这一点,也可以(例如,使用未记录的跟踪标志8605)看传递给优化的逻辑树,以确认这两个!=和<>映射到ScaOp_Comp x_cmpNe(不等于标量操作者比较)。
例如:
SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID != 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);
SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID <> 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);
都产生:
LogOp_Project QCOL:[P] .ProductID
LogOp_Select
LogOp_Get TBL:生产。产品(别名TBL:P)
ScaOp_Comp x_cmpNe
ScaOp_Identifier QCOL:[P] .ProductID
ScaOp_Const TI(int,ML = 4)XVAR(int,不拥有,值= 4)
AncOp_PrjList
*我使用WinDbg ; 其他调试器也可用。可通过常规的Microsoft符号服务器获得公共符号。有关更多信息,请参见SQL Server客户咨询团队对使用Minidumps深入研究SQL Server和WinDbg进行SQL Server调试– Klaus Aschenbrenner 的简介。
**在32位Intel衍生产品上使用EAX来获取函数的返回值是很常见的。当然,Win32 ABI就是这样做的,而且我很确定它是从旧的MS-DOS时代继承了这种做法的,当时AX被用于相同的目的-MichaelKjörling
我认为以下证明<>不能进行2次比较。
<>不等于运算符定义为(http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt)。从技术上讲,!=是对标准的扩展(即使我不能考虑任何未实现该标准的RDBMS)。<>2个运算符(而不是1个),则><实际上会发生语法错误。