我有一个带有两个可以为零的十进制值和一个ID的sql server 2008表。我将值和ID传递给存储过程。这些值可能与现有值相同,也可能是其他值。如果是其他内容,我想更新现有记录。我的问题是,由于可以考虑的因素,我不知道该如何做到这一点。
DECLARE @count int
SET @count=(SELECT Count(ID) FROM [MyTable] WHERE
[ID]=@id AND
[Value1]<>@value1 AND
[Value2]<>@value2
)
IF (@count>0)
BEGIN
UPDATE
[MyTable]
SET
[Value1]=@value1,
[Value2]=@value2
WHERE
[ID]=@id
END
我的问题是处理null case。有人可以告诉我如何处理我描述的空案例吗?
谢谢!
答案 0 :(得分:1)
使用ISNULL在比较中为Value1和Value2提供默认值。 如果您想要更新,如果任何一个值不同,我认为您需要 OR 。
SELECT @count = Count(ID) FROM @MyTable
WHERE ID = @id
AND (ISNULL(Value1,0) <> @value1 OR ISNULL(Value2,0) <> @value2)
答案 1 :(得分:0)
您应该使用IsNull。如果你想要等效处理空值,请使用
之类的东西IsNull(Value1,'') <> IsNull(@value1,'')
答案 2 :(得分:0)
您的意思是,如果传入的值为null,您不想覆盖现有值吗?
如果是这样,你可以做
UPDATE
[MyTable]
SET
[Value1]=ISNULL(@value1, [Value1]),
[Value2]=ISNULL(@value2, [Value2])
WHERE
[ID]=@id
如果您正在寻找这样做,您可能还需要修改您的选择,以便在传入的值为空时不执行不必要的更新。
答案 3 :(得分:0)
首先进行计数然后执行更新是昂贵且浪费的。如果计数回来,你基本上会进行两次扫描而不是一次扫描&gt;即使使用存在而不是计数也可以效率不高,但也可能同样糟糕。为什么不尝试运行更新?您需要选择一些令牌值进行比较,因此数据中的数字自然不会存在。或者你可以在OR中运行很多条件。
CREATE PROCEDURE dbo.MyTable_Update
@ID INT,
@Value1 DECIMAL(5,2),
@Value2 DECIMAL(5,2)
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.MyTable
SET Value1 = @Value1,
Value2 = @Value2
WHERE
ID = @id
AND
(
COALESCE(Value1, -1) <> COALESCE(@Value1, -1)
OR COALESCE(Value2, -1) <> COALESCE(@Value2, -1)
);
SELECT 'Rows updated:', @@ROWCOUNT;
END
GO
这是一个使用更多条件的版本,但是不需要选择像-1这样的标记值:
CREATE PROCEDURE dbo.MyTable_Update
@ID INT,
@Value1 DECIMAL(5,2),
@Value2 DECIMAL(5,2)
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.MyTable
SET Value1 = @Value1,
Value2 = @Value2
WHERE
ID = @id
AND
(
Value1 <> @Value1
OR (Value1 IS NULL AND @Value1 IS NOT NULL)
OR (Value1 IS NOT NULL AND @Value1 IS NULL)
OR Value2 <> @Value2
OR (Value2 IS NULL AND @Value2 IS NOT NULL)
OR (Value2 IS NOT NULL AND @Value2 IS NULL)
);
SELECT 'Rows updated:', @@ROWCOUNT;
END
GO
关键是,不要先计算,只是为了看看你是否应该运行更新查询。只需运行更新查询。最糟糕的情况是你会更新0行,但至少你只能在一次通过中完成。