我想确保我没有在表格中插入重复的行(例如,只有主键不同).我的所有字段都允许NULLS,因为我已经确定null表示"所有值".由于null,我的存储过程中的以下语句不起作用:
IF EXISTS(SELECT * FROM MY_TABLE WHERE
MY_FIELD1 = @IN_MY_FIELD1 AND
MY_FIELD2 = @IN_MY_FIELD2 AND
MY_FIELD3 = @IN_MY_FIELD3 AND
MY_FIELD4 = @IN_MY_FIELD4 AND
MY_FIELD5 = @IN_MY_FIELD5 AND
MY_FIELD6 = @IN_MY_FIELD6)
BEGIN
goto on_duplicate
END
Run Code Online (Sandbox Code Playgroud)
因为NULL = NULL不是真的.
如何在没有每列的IF IS NULL语句的情况下检查重复项?
我有一个更新查询,当值与另一个表中的字段不匹配时更新一个表中的字段.
UPDATE table1
SET a.field1 = b.field3
FROM table1 a ,
table2 b
WHERE a.field2 = b.field2
AND a.field1 <> b.field3
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,当a.field1为null并且b.field3为值时,如果a.field1为值且b.field3为null,则不会拾取.
我通过添加以下内容来解决这个问题...
UPDATE table1
SET a.field1 = b.field3
FROM table1 a ,
table2 b
WHERE a.field2 = b.field2
AND ( a.field1 <> b.field3
OR (a.field1 IS NOT NULL
AND b.field3 IS NULL)
OR (a.field1 IS NULL
AND b.field3 IS NOT NULL)
)
Run Code Online (Sandbox Code Playgroud)
我的问题更集中在为什么会发生这种情况以及如何最好地构建查询以防止这种情况?
在SQL Server 2008中,我使用的是MERGE.一切都很好,除了我有2个可以为空的列.如果我传递一个空值并且目标不是null,则MERGE没有看到差异(每个BOL对ev = false = false ).如果我在两侧使用IsNull(源和目标),但有可能错误评估值的问题.
我的意思是,如果我说:
WHEN MATCHED AND NOT (IsNull(tgt.C, 0) = IsNull(src.C, 0)) THEN
Run Code Online (Sandbox Code Playgroud)
那么如果tgt.C为null且src.C = 0,则不会执行更新.无论我选择什么替代价值,我都会遇到这个问题.
我还尝试了"AND NOT(... true ...)"语法,因为BOL声明对null的评估结果为FALSE.但是,它们似乎实际上导致NULL并且不会导致我的多部分语句变为false.
我认为一种解决方案是使用NaN或-INF或+ INF,因为它们在目标中无效.但是我找不到在SQL中表达这种方法的方法.
任何想法如何解决这个问题?
编辑:
以下逻辑解决了这个问题,但它很冗长,不会导致快速逃避:
declare @i int, @j int
set @j = 0
set @i = 0
if ISNULL(@i, 0) != ISNULL(@j, 0) OR
((@i is null or @j is null) and not (@i is null and @j is null))
print 'update';
Run Code Online (Sandbox Code Playgroud)