Таблица обновления MS SQL с несколькими условиями - PullRequest
4 голосов
/ 23 июня 2011

Долго читал этот сайт для ответов, а теперь задаю свой первый вопрос!

Я использую SQL Server

У меня две таблицы, ABC и ABC_Temp .

Содержимое вставляется в ABC_Temp , прежде чем попасть в ABC.Таблицы ABC и ABC_Temp имеют одинаковые столбцы, за исключением того, что ABC_Temp имеет дополнительный столбец с именем LastUpdatedDate, который содержит дату последнего обновления.Поскольку ABC_Temp может иметь более одной и той же записи, он имеет составной ключ с номером элемента и датой последнего обновления.

Столбцы: ItemNo |Цена |Кол-во и ABC_Temp имеет дополнительный столбец: LastUpdatedDate

Я хочу создать инструкцию, которая соответствует следующим условиям:

  1. Проверьте, если каждый из атрибутов ABC отличается от значения ABC_Temp для записей с тем же ключом, если это так, тогда выполните обновление (даже если отличается только один атрибут, все остальные атрибуты также могут быть обновлены)
  2. Обновлять только те, которые нуждаются в изменениях, если запись та же самая, то она не будет обновляться.
  3. Поскольку элемент может иметь более одной записи в ABC_Temp I onlyхочу, чтобы последнее обновленное было обновлено до ABC

В настоящее время я использую 2005 (думаю, на данный момент не на работе).

Это будетнаходиться в хранимой процедуре и вызывается внутри запланированной задачи VBscript.Так что я верю, что это однажды.Кроме того, я не пытаюсь синхронизировать две таблицы, поскольку содержимое ABC_Temp будет содержать только новые объемные записи, вставленные из текстового файла через BCP.Ради контекста, это будет использоваться вместе со вставкой, хранимой процедурой, которая проверяет, существуют ли записи.

Ответы [ 2 ]

2 голосов
/ 23 июня 2011
UPDATE
    ABC
SET
    price = T1.price,
    qty = T1.qty
FROM
    ABC
INNER JOIN ABC_Temp T1 ON
    T1.item_no = ABC.item_no
LEFT OUTER JOIN ABC_Temp T2 ON
    T2.item_no = T1.item_no AND
    T2.last_updated_date > T1.last_updated_date
WHERE
    T2.item_no IS NULL AND
    (
        T1.price <> ABC.price OR
        T1.qty <> ABC.qty
    )

Если в столбцах price или qty возможны значения NULL, вам необходимо учитывать это.В этом случае я бы, вероятно, изменил бы выражения неравенства, чтобы они выглядели так:

COALESCE(T1.price, -1) <> COALESCE(ABC.price, -1)

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

Кроме того, действительно ли ABC_Temp является временной таблицей, которая просто загружается достаточно долго, чтобы получить значения в ABC?Если нет, то вы храните дубликаты данных в нескольких местах, что является плохой идеей.Первая проблема заключается в том, что теперь вам нужны такие сценарии обновления.Есть и другие проблемы, с которыми вы можете столкнуться, такие как несоответствия в данных и т. Д.

1 голос
/ 23 июня 2011

Вы можете использовать cross apply для поиска последней строки в ABC_Temp с тем же ключом. Используйте предложение where для фильтрации строк без различий:

update  abc
set     col1 = latest.col1
,       col2 = latest.col2
,       col3 = latest.col3
from    ABC abc
cross apply
        (
        select  top 1 *
        from    ABC_Temp tmp
        where   abc.key = tmp.key
        order by
                tmp.LastUpdatedDate desc
        ) latest
where   abc.col1 <> latest.col1
        or (abc.col2 <> latest.col2
            or (abc.col1 is null and latest.col2 is not null)
            or (abc.col1 is not null and latest.col2 is null))
        or abc.col3 <> latest.col3

В этом примере только col2 может иметь значение null. Поскольку null <> 1 не соответствует действительности, необходимо проверить различия, связанные с нулем, используя синтаксис is null.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...