Сравнение значений в SQL - PullRequest
       2

Сравнение значений в SQL

0 голосов
/ 02 августа 2011

У меня есть таблица SQL Server 2008 с двумя обнуляемыми десятичными значениями и идентификатором.Я передаю значения и идентификатор в хранимую процедуру.Эти значения могут совпадать с существующими значениями или быть чем-то другим.Если это что-то еще, я хочу обновить существующую запись.У меня вопрос, я не уверен, как это сделать из-за обнуляемого фактора.

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

Моя проблема заключается в обработке нулевого регистра.Может кто-нибудь показать мне, как обращаться с нулевым случаем, который я описал?

Спасибо!

Ответы [ 4 ]

1 голос
/ 02 августа 2011

Используйте ISNULL для предоставления значения по умолчанию для значений1 и значений2 в сравнении.И я думаю, вам понадобится ИЛИ , если вы хотите обновить, если любое из значений отличается.

SELECT @count = Count(ID) FROM @MyTable 
WHERE ID = @id 
   AND (ISNULL(Value1,0) <> @value1 OR ISNULL(Value2,0) <> @value2)
0 голосов
/ 02 августа 2011

Это дорогой и расточительный сначала сделать подсчет, а затем выполнить обновление.По сути, вы собираетесь сделать два сканирования вместо одного, если счет вернется> 0. Даже использование существует вместо счетчика может быть не менее эффективным, но это может быть так же плохо.Почему бы просто не попробовать запустить обновление?Вам нужно выбрать какое-нибудь значение токена для сравнения, чтобы число, которое никогда не могло существовать в данных естественным образом.Или вы можете выполнить много условий в 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 строк, но по крайней мере вы сделаете это только за один проход.

0 голосов
/ 02 августа 2011

Вы имеете в виду, что если переданные значения являются нулевыми, вы не хотите перезаписывать существующее значение?

Если это так, вы можете сделать

UPDATE
  [MyTable]
SET
  [Value1]=ISNULL(@value1, [Value1]),
  [Value2]=ISNULL(@value2, [Value2])
WHERE
  [ID]=@id

Если это то, что выВозможно, вы захотите изменить свой выбор, чтобы не выполнять ненужные обновления, если переданные значения равны нулю.

0 голосов
/ 02 августа 2011

Вы должны использовать IsNull . Если вы хотите, чтобы к нулям относились эквивалентно, используйте что-то вроде

IsNull(Value1,'') <> IsNull(@value1,'')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...