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个),则><
实际上会发生语法错误。