我正在写一个正在做的触发器
IF (@A <> @B)
...
Run Code Online (Sandbox Code Playgroud)
但这不适用于@A或@B上的NULL值.它通常的方式是
IF (@A <> @B) OR (@A IS NOT NULL AND @B IS NULL) OR (@A IS NULL AND @B IS NOT NULL)
Run Code Online (Sandbox Code Playgroud)
但这涉及最多9次比较而不是1次!
我可以
SET ANSI_NULLS OFF
Run Code Online (Sandbox Code Playgroud)
但显然不建议这样做(并且不推荐使用).
那么什么是最好的解决方案呢?当它应该为1时,只需进行9次比较即可进行简单的不等式检查?触发器不是性能关键,但确实需要快速.批量加载时,这可能会大大降低速度.
绩效测试
以下是性能测试的结果,该测试检查不等式一百万次,使得90%的时间值不相等,每个值可能为空的时间的10%.
IF (@A <> @B) OR (@A IS NULL AND @B IS NOT NULL) OR (@A IS NOT NULL AND @B IS NULL)
Run Code Online (Sandbox Code Playgroud)
结果:平均3848ms
IF (ISNULL(@A, 0) <> ISNULL(@B, 0))
Run Code Online (Sandbox Code Playgroud)
结果:平均3942ms
IF (@A = @B) GOTO Equal ELSE IF @A IS NULL AND @B IS NULL GOTO Equal
Run Code Online (Sandbox Code Playgroud)
结果:平均4140ms
IF EXISTS (SELECT @A EXCEPT SELECT @B)
Run Code Online (Sandbox Code Playgroud)
结果:平均7795ms
时间并不重要,重要的是相对差异.显然,经典的方法是最快的.可能的MSSQL内部针对此类检查进行了优化.
在MacBook Pro上运行测试(运行MSSQL 2008 Express的Vista VM中的Intel Core 2 Duo,2.4Ghz,8GB RAM).
ANSI SQL有,IS DISTINCT FROM
但SQL Server中没有实现.它可以以不依赖于魔术常量的方式进行模拟,如果在列上使用则可以进行模拟
IF EXISTS (SELECT @A EXCEPT SELECT @B)
PRINT 'Different'
Run Code Online (Sandbox Code Playgroud)