gpt4 book ai didi

sql - 关闭 ANSI_NULLS 时的 T-SQL/意外 NULL 处理

转载 作者:行者123 更新时间:2023-12-02 01:11:52 27 4
gpt4 key购买 nike

我只是在 SQL Server 中处理 NULL 值(在版本 12.0.5000.0 上测试)。基本上,我的目的是让所有具有列值 <> 静态值(例如 999)的行。我不是在寻找替代方案,例如“使用 ISNULL 函数”。查询由第三方引擎生成,我不打算编写解析器并更改语句。

-- All examples with ANSI_NULLS OFF
SET ANSI_NULLS OFF;
GO

--------------------------------------------------------------------------------------------------------
-- "Virtual" example / working as expected
--------------------------------------------------------------------------------------------------------
DECLARE
@One INT = 1,
@Null INT = NULL

SELECT
IIF(@Null = NULL, 1, 0) '@Null = NULL' -- To test if ANSI_NULL is OFF
,IIF(@One <> NULL, 1, 0) '@One <> NULL' -- working with NULL variable
,IIF(1 <> NULL, 1, 0) '1 <> NULL' -- working with NULL value

--------------------------------------------------------------------------------------------------------
-- MSDN Example / NOT working as expected
-- https://learn.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql
--------------------------------------------------------------------------------------------------------

-- Create table t1 and insert values.
CREATE TABLE dbo.t1 (a INT NULL);
INSERT INTO dbo.t1 values (NULL),(0),(1);
GO

-- SET ANSI_NULLS to OFF and test.
DECLARE @varname int;
SET @varname = 999;

SELECT a
FROM t1
WHERE a <> @varname; -- working with NULL variable

SELECT a
FROM t1
WHERE a <> 999; -- NOT working with NULL value

-- Drop table t1.
DROP TABLE dbo.t1;

谁能解释为什么“虚拟”示例与 MSDN 示例的工作方式不同?

Virtual example:
+--------------+--------------+-----------+
| @Null = NULL | @One <> NULL | 1 <> NULL |
+--------------+--------------+-----------+
| 1 | 1 | 1 |
+--------------+--------------+-----------+

MSDN example:
-- SELECT 1
+------+
| a |
+------+
| NULL |
| 0 |
| 1 |
+------+

-- SELECT 2
+------+
| a |
+------+
| 0 |
| 1 |
+------+

最佳答案

看起来查询优化器选择了不同的比较运算符:

DECLARE @varname int;  
SET @varname = 999;

SELECT a
FROM t1
WHERE a <> @varname;

XML 执行计划:

<Predicate>
<ScalarOperator ScalarString="[fiddle_84f7799901e54a779e8bff464a2d01f3].[dbo].[t1].[a] &lt;&gt; [@varname]">
<Compare CompareOp="IS NOT">
<ScalarOperator>
<Identifier>
<ColumnReference Database="[fiddle_84f7799901e54a779e8bff464a2d01f3]" Schema="[dbo]" Table="[t1]" Column="a"></ColumnReference>
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Column="@varname"></ColumnReference>
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>

Compare CompareOp="IS NOT"


带有硬编码值的第二个查询:

SELECT a   
FROM t1
WHERE a <> 999;

-- same as
DECLARE @varname int = 999;

SELECT a
FROM t1
WHERE a <> (SELECT @varname);

XML 执行计划:

<Predicate>
<ScalarOperator ScalarString="[fiddle_ac5121a789da473382366733b51ef441].[dbo].[t1].[a]&lt;&gt;(999)">
<Compare CompareOp="NE">
<ScalarOperator>
<Identifier>
<ColumnReference Database="[fiddle_ac5121a789da473382366733b51ef441]" Schema="[dbo]" Table="[t1]" Column="a"></ColumnReference>
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(999)"></Const>
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>

Compare CompareOp="NE"

DBFiddle

编辑:

SET ANSI_NULLS

SET ANSI_NULLS ON affects a comparison only if one of the operands of the comparison is either a variable that is NULL or a literal NULL. If both sides of the comparison are columns or compound expressions, the setting does not affect the comparison.

关于sql - 关闭 ANSI_NULLS 时的 T-SQL/意外 NULL 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44909559/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com