C# 如何使用类似C的行为在SQL中进行等式比较?

C# 如何使用类似C的行为在SQL中进行等式比较?,c#,sql,compare,equality,C#,Sql,Compare,Equality,如何将SQL中的值相等与null进行比较 对于熟悉C#的人,以下是比较可为空值的结果: null == null : true null == john : false null == paul : false john == null : false john == john : true john == paul : false paul == null : false paul == john : false paul == paul : true 我在SQL中找到的最简单的解决方案是将

如何将SQL中的值相等与null进行比较

对于熟悉C#的人,以下是比较可为空值的结果:

null == null : true
null == john : false
null == paul : false
john == null : false
john == john : true
john == paul : false
paul == null : false
paul == john : false
paul == paul : true
我在SQL中找到的最简单的解决方案是将可为空的字段合并成一些sentinel值(例如“scoobydoo”),然后比较它们

coalesce(A, 'scoobydoo') = coalesce(B, 'scoobydoo')
但如果有人使用sentinel值,如果A恰好为NULL,B为‘scoobydoo’,那么上面的表达式将产生true,这显然是一个难题

这正是我询问上述代码逻辑(T-SQL更新触发器)的目的:

再次编辑。。。合并结果应该会起作用,并使事情变得更简单:

平等:

where COALESCE((A = B) or (A is null and B is null), false)
我同意这不太令人愉快

编辑:维尔克斯指出了
ab
的一个问题。不过,我认为这会奏效:

where (A <> B) or ((A is null or B is null) and
                   (A is not null or B is not null))

如果是Microsoft SQL Server,则您正在寻找该选项。如果它是另一个DBMS,您必须阅读它的文档。他们中的一些人根本不支持这一点


补充道:哦,我注意到你提到了T-SQL。它就是MSSQL!:)

s/delete/deleted/在上一个示例中。明确给出paul&john的初始值?如果这是T-SQL,它肯定是Postgres问题的重复吗?同样的答案会起作用吗?@Jon Skeet:你只是厌倦了,迫不及待地想回答另一个问题:兴趣的撅嘴,你说的“炸弹爆炸”到底是什么意思?你有什么错误?我很好奇。。。(SQL不是我的强项。)+1用于提供的引擎盖下语义不同于Umm。。。如果我错了,请原谅,如果A为空,B不为空,那么第二个不是会失败吗?@Vilx:你关心哪一点
AB
将为真,
(A不为空或B不为空)
将为真,因为B不为空-因此根据需要,总体结果为真。不,AB将为假,因为其中一个为空,将任何内容与空值进行比较将导致空值。好吧,除非你玩弄ANSI_NULLS,但你无论如何都不需要这些。@Jon:这是有效的(如果我们将null视为false):其中(ab)或((A为null或B为null)和(A为非null或B为非null));这不是:如果不((A=B)或(A为null,B为null))看到我的查询结果,我喜欢它!我知道这不是标准,但该死!谢谢。理论上,它也可能是Sybase。嗯,好吧,我不知道。:)
select

    A, B,

    A = B,
    A IS NOT DISTINCT FROM B, -- "logically" same as above
    coalesce( (A = B) or (A is null and B is null), false ), 
    -- tested Jon's code for ==, semi-work, coalesced to make it true/false only


    A <> B,
    A IS DISTINCT FROM B, -- "logically" same as above
    (A <> B) and (A is not null or B is not null)  
    -- tested Jon's code for !=, bombs out

from(    
    values
    (null, null),
    (null, 'john'),
    (null, 'paul'),
    ('john', null),
    ('john', 'john'),
    ('john', 'paul'),
    ('paul', null),
    ('paul', 'john'),
    ('paul', 'paul')) as x(A,B)
select

    A, B,

    A = B,
    A IS NOT DISTINCT FROM B, -- "logically" same as above
    (A = B) or (A is null and B is null), 
    -- tested Jon's code for ==


    A <> B,
    A IS DISTINCT FROM B -- "logically" same as above,
    (A <> B) and (A is not null or B is not null)  
    -- tested Jon's code for !=, bombs out

from(    
    values
    (null, null),
    (null, 'john'),
    (null, 'paul'),
    ('john', null),
    ('john', 'john'),
    ('john', 'paul'),
    ('paul', null),
    ('paul', 'john'),
    ('paul', 'paul')) as x(A,B)


  a   |  b   | ?column? | ?column? | ?column? | ?column? | ?column? | ?column?
------+------+----------+----------+----------+----------+----------+----------
 null | null | null     | t        | t        | null     | f        | f
 null | john | null     | f        | null     | null     | t        | null
 null | paul | null     | f        | null     | null     | t        | null
 john | null | null     | f        | null     | null     | t        | null
 john | john | t        | t        | t        | f        | f        | f
 john | paul | f        | f        | f        | t        | t        | t
 paul | null | null     | f        | null     | null     | t        | null
 paul | john | f        | f        | f        | t        | t        | t
 paul | paul | t        | t        | t        | f        | f        | f
(9 rows)
select

    A, B,

    A = B as e,
    A IS NOT DISTINCT FROM B AS e_works, -- "logically" same as above
    (A = B) or (A is null and B is null) AS e_semi_work, -- tested Jon's code for ==, works if we treat null as false


    A <> B as ie,
    A IS DISTINCT FROM B as ie_works, -- "logically" same as above,
    (A <> B) and (A is not null or B is not null) as ie_not_work, -- tested Jon's code for !=, bombs out

    (A <> B) or ((A is null or B is null) and (A is not null or B is not null)) as ie_semi_works, -- this works(well it is, if you treat null as false),

     not ((A = B) or (A is null and B is null)) as ie_not_work2 -- this doesn't work


from(    
    values
    (null, null),
    (null, 'john'),
    (null, 'paul'),
    ('john', null),
    ('john', 'john'),
    ('john', 'paul'),
    ('paul', null),
    ('paul', 'john'),
    ('paul', 'paul')) as x(A,B)
  a   |  b   | e    | e_works | e_semi_work | ie   | ie_works | ie_not_work | ie_semi_works | ie_not_work2
------+------+------+---------+-------------+------+----------+-------------+---------------+--------------
 null | null | null | t       | t           | null | f        | f           | null          | f
 null | john | null | f       | null        | null | t        | null        | t             | null
 null | paul | null | f       | null        | null | t        | null        | t             | null
 john | null | null | f       | null        | null | t        | null        | t             | null
 john | john | t    | t       | t           | f    | f        | f           | f             | f
 john | paul | f    | f       | f           | t    | t        | t           | t             | t
 paul | null | null | f       | null        | null | t        | null        | t             | null
 paul | john | f    | f       | f           | t    | t        | t           | t             | t
 paul | paul | t    | t       | t           | f    | f        | f           | f             | f
(9 rows)
where COALESCE((A = B) or (A is null and B is null), false)
where (A <> B) or ((A is null or B is null) and
                   (A is not null or B is not null))
where !(COALESCE((A = B) or (A is null and B is null)), false)