VARCHAR和CHAR之间的SQL Server Null比较



问题:

  • 我有一个有两列的表,一个是char(1),另一个是varchar(1
  • 我插入一行NULLS
  • 我比较两列的值
  • 我知道他们不平等
  • 为什么

代码:

CREATE TABLE ss_1
    (
      [char] CHAR(1) ,
      [varchar] VARCHAR(3)
    )

INSERT  INTO TimeCurrent..ss_1
        ( char, varchar )
VALUES  ( NULL,-- char - char(1)
          NULL  -- varchar - varchar(3)
          )
SELECT  CASE WHEN S.char = S.varchar THEN 'yes'
             ELSE 'no'
        END AS eq2
FROM    ss_1 AS S

FIDDLE:

http://sqlfiddle.com/#!6/84bc4/2/0

实际上,这是因为SQL基于三值逻辑,其中谓词可以评估为三个不同的值:TRUEFALSEUNKNOWN。当比较的任何部分是NULL时,谓词求值为UNKNOWN。这是正式的定义。示例:

1 = 1 => TRUE
1 = 2 => FALSE
1 = NULL => UNKNOWN
NULL = NULL => UNKNOWN

现在当你写:

CASE WHEN predicate THEN

只有当谓词求值为TRUE时,它才会转到THEN。但在您的情况下,它的评估值为UNKNOWN。这就是它进入ELSE部分的原因。

CREATE TABLE ss_1
(
  [char] CHAR(1) ,
  [varchar] VARCHAR(3)
)

INSERT  INTO TimeCurrent..ss_1
    ( char, varchar )
VALUES  ( NULL,-- char - char(1)
      NULL  -- varchar - varchar(3)
      )
SELECT  CASE WHEN coalesce(S.char, '') = coalesce(S.varchar, '') THEN 'yes'
         ELSE 'no'
    END AS eq2
FROM    ss_1 AS S

这样的东西可能对你想要的东西有效。如前所述,null与另一个null值的直接比较永远不会返回相等,因为null只是意味着没有值,因此没有可供比较的值。输入类型与此无关(如果两者都是char(1)或char (3),或者其他数据类型,则情况相同)。

编辑:需要注意的一点是,如果空白是数据库中该列的有效输入,则您需要将''替换为其他值(否则不合法),否则您最终会将数据库中的空白值与空值进行匹配,这可能没问题,也可能没问题。。。

编辑2:这实际上可能会稍微好一点,更能反映你的实际意图:

CREATE TABLE ss_1
(
  [char] CHAR(1) ,
  [varchar] VARCHAR(3)
)

INSERT  INTO TimeCurrent..ss_1
    ( char, varchar )
VALUES  ( NULL,-- char - char(1)
      NULL  -- varchar - varchar(3)
      )
SELECT  CASE WHEN S.char = S.varchar THEN 'yes'
        CASE When S.char IS NULL and S.varchar IS NULL Then 'yes'
         ELSE 'no'
    END AS eq2
FROM    ss_1 AS S

最新更新