比较SQL中的值

时间:2011-08-02 13:44:29

标签: sql sql-server sql-server-2008

我有一个带有两个可以为零的十进制值和一个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。有人可以告诉我如何处理我描述的空案例吗?

谢谢!

4 个答案:

答案 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行,但至少你只能在一次通过中完成。