Sql 如何在where子句中添加空值(比较)

Sql 如何在where子句中添加空值(比较),sql,asp.net,Sql,Asp.net,这是我的样品台 id name grade sign 1 pinky A null 2 smita B sam 我想在检查名称、等级和符号后将新记录添加到示例表中。如果找不到这些组合的记录,请插入else not declare @count int select @count = count(*) from sample where name = @name and grade= @grade and sign = @sign -- @na

这是我的样品台

id  name    grade   sign
1   pinky   A       null
2   smita   B       sam
我想在检查名称、等级和符号后将新记录添加到示例表中。如果找不到这些组合的记录,请插入else not

declare @count int
select @count = count(*) from sample where name = @name and grade= @grade and sign = @sign
-- @name,@grade and @sign are input para
if(@count = 0)
begin
-- insert 
end
当我尝试添加第一条小号、'A'和null的记录时出现问题。它将计数设为零并添加记录。如何处理此问题?我的表可能有null值,也可能没有null值。具体取决于。 我知道null和null的比较,总是false。
(null=null)

朋友们好,谢谢你们的帮助。我尝试了以下代码

select @count = count(*) from sample where name = @name and grade= @grade and  (sign = @sign OR (Sign IS NULL AND @Sign IS NULL))
但它不起作用。它给我的计数是零而不是1

我也试过喜欢这个。我在尝试添加第一条记录时工作过,即小指、A和null。它显示我计数为1。提示我进一步添加

 select @count = count(*) from sample where name = @name and grade= @grade and  (@Sign IS NULL or sign = @sign)
但当我尝试添加值为'smita','B',null的新列时失败。它给了我一个作为计数。但它是错误的。这些组合的记录不存在

再次检查您的查询@Mukund

select @count = count(*) from sample where name = @name and grade= @grade and  (sign = @sign OR (Sign IS NULL AND @Sign IS NULL)).
It gave me count as zero instead of 1 when I am trying to add 'pinky',A and null 

您可以对
null
进行一些额外检查:

sign = @sign or (sign is null and @sign is null)

您可以对
null
进行一些额外检查:

sign = @sign or (sign is null and @sign is null)
这样做

select @count = count(*) 
from sample 
where name = @name 
and grade= @grade 
and isnull(sign,'') = @sign
它将做什么,如果列中有任何值为null,则它将用“”替换它,然后尝试进行比较

这样做

select @count = count(*) 
from sample 
where name = @name 
and grade= @grade 
and isnull(sign,'') = @sign
它将做什么,如果列中有任何值为null,则它将用“”替换它,然后尝试进行比较

如果存在,请使用:

if not exists(
select * from sample where name = @name and grade= @grade and (sign = @sign or (sign is null and @sign is null))
)
    begin
      insert into sample(name,grade,sign) values (@name,@grade,@sign)
    end;
请看一看示例

6个插入查询,其中2个记录显示每种情况下发生的情况。

如果存在,请使用:

if not exists(
select * from sample where name = @name and grade= @grade and (sign = @sign or (sign is null and @sign is null))
)
    begin
      insert into sample(name,grade,sign) values (@name,@grade,@sign)
    end;
请看一看示例


6个插入查询,其中2个记录显示每种情况下发生的情况。

您的查询容易受到攻击。在多线程环境中,在检索匹配记录的计数和插入新记录之间存在一个变化(尽管可能性不大),即另一个线程插入了相同的记录

防范这种情况的第一步是添加一个唯一的约束。如果
(名称、等级、符号)
应是唯一的,则应将其约束为:

ALTER TABLE sample 
ADD CONSTRAINT UQ_sample__Name_Grade_Sign UNIQUE (Name, Grade, Sign);
无论选择何种方法插入记录,都应执行此操作。这将把您的逻辑与数据库集成在一起,并保护它不受任何可能不是来自应用程序层的插入的影响,例如,有人可以运行一个独立的
INSERT Sample(Name,Grade,Sign)值('pinky','a',null)
,这将绕过您的INSERT方法,从而避免重复

为了避免陷入竞争条件并获得约束冲突错误,我知道的最好的方法是使用
MERGE
HOLDLOCK

MERGE sample WITH (HOLDLOCK) AS t
USING (VALUES (@Name, @Grade, @Sign)) AS s (Name, Grade, Sign)
    ON s.name = t.Name
    AND s.Grade = t.Grade
    AND ISNULL(s.Sign, '') = ISNULL(t.Sign, '')
WHEN NOT MATCHED THEN 
    INSERT (Name, Grade, Sign)
    VALUES (s.Name, s.Grade, s.Sign);

您的查询易受攻击。在多线程环境中,在检索匹配记录的计数和插入新记录之间存在一个变化(尽管可能性不大),即另一个线程插入了相同的记录

防范这种情况的第一步是添加一个唯一的约束。如果
(名称、等级、符号)
应是唯一的,则应将其约束为:

ALTER TABLE sample 
ADD CONSTRAINT UQ_sample__Name_Grade_Sign UNIQUE (Name, Grade, Sign);
无论选择何种方法插入记录,都应执行此操作。这将把您的逻辑与数据库集成在一起,并保护它不受任何可能不是来自应用程序层的插入的影响,例如,有人可以运行一个独立的
INSERT Sample(Name,Grade,Sign)值('pinky','a',null)
,这将绕过您的INSERT方法,从而避免重复

为了避免陷入竞争条件并获得约束冲突错误,我知道的最好的方法是使用
MERGE
HOLDLOCK

MERGE sample WITH (HOLDLOCK) AS t
USING (VALUES (@Name, @Grade, @Sign)) AS s (Name, Grade, Sign)
    ON s.name = t.Name
    AND s.Grade = t.Grade
    AND ISNULL(s.Sign, '') = ISNULL(t.Sign, '')
WHEN NOT MATCHED THEN 
    INSERT (Name, Grade, Sign)
    VALUES (s.Name, s.Grade, s.Sign);

其中(sign=@sign或(sign为NULL,@sign为NULL))
您能检查一下我的解决方案吗@Swatii在我的答案中添加了一个小提琴,看看它是否对你有帮助。
在哪里(sign=@sign或(sign为NULL和@sign为NULL))
你能检查一下我的解决方案吗@Swatii在我的答案中添加了一个小提琴,看看它是否对你有帮助。我认为这应该是
isnull(sign,)=isnull(@sign,)
是否可以将@sign设为null。如果是的话,她可以做到。在这两种情况下,结果都是一样的。根据这个问题,
@sign
可能是空的-结果将不一样。如果
sign
为空且
@sign
为空,则您最终得到的
'=null
为空,即不为真。然而,如果你使用
ISNULL(sign,)=ISNULL(@sign,)
,并且
sign
@sign
都是null,那么你最终得到的结果是
''='
,这是真的。你认为这应该是
ISNULL(sign,)=ISNULL(@sign,)
有可能将@sign设为null吗。如果是的话,她可以做到。在这两种情况下,结果都是一样的。根据这个问题,
@sign
可能是空的-结果将不一样。如果
sign
为空且
@sign
为空,则您最终得到的
'=null
为空,即不为真。然而,如果您使用
ISNULL(sign,”)=ISNULL(@sign,”)
,并且
sign
@sign
都为null,那么您将得到
'='
,这是真的。