Проверка, чтобы увидеть, изменились ли данные строки - PullRequest
6 голосов
/ 08 сентября 2011

Моя цель: Перемещает данные из одной таблицы в другую, если строка была обновлена ​​или была вставлена ​​новая строка.

У меня есть таблица, из которой мне нужны определенные поля. Мне нужно знать, была ли строка обновлена ​​или вставлена. Исходная таблица не имеет полей Timestamp. Я использую MSSQL2008. Данные поступают от клиента, и они контролируют таблицы и репликацию.

Мне показалось, что я выяснил это с помощью новой функции Merge для MSSQL 2008, но он обновляет все строки независимо от того, изменилось ли что-либо. Обычно это не большая проблема, но я должен добавить поля отметки времени. Мои измененные поля времени будут обновлены независимо от того, была ли обновлена ​​строка.

Так что мне нужен способ для достижения моей цели. Я не большой эксперт по SQL, так что, как вы видите, я изо всех сил, любая помощь была бы великолепной.

USE NaylorAequor
DECLARE CurretDate GetDate();

MERGE Aequor_SLA_Ads AS Target

USING (select AWA.AdOrderID,emp.FirstName, emp.LastName,AWA.VendorID,AO.OrderDate,AO.SaleStatusID,A.AdColorId,AO.PublicationID,AWA.DateAssigned,AWA.DateAdCompleted 
from AdWorkAssignMent as AWA, Employee as emp, AdOrder AS AO,Ad as A
WHERE VendorId = 'Aequor' AND emp.EmployeeID = AWA.EmployeeID AND AWA.AdOrderId = AO.AdOrderID AND AO.AdId = A.AdId) AS Source

ON (Target.AdOrderID = Source.AdOrderID) 

WHEN MATCHED THEN
         UPDATE SET 
            Target.AdOrderID =Source.AdOrderID,
            Target.FirstName = Source.FirstName,
            Target.LastName =Source.LastName,
            Target.VendorID =Source.VendorID,
            Target.OrderDate =Source.OrderDate,
            Target.SaleStatusID =Source.SaleStatusID,
            Target.AdColorId =Source.AdColorId,
            Target.PublicationID =Source.PublicationID,
            Target.DateAssigned =Source.DateAssigned,
            Target.DateAdCompleted =Source.DateAdCompleted,
            Target.AequorModifiedDateTime = GetDate()


WHEN NOT MATCHED BY TARGET THEN
      INSERT (AdOrderID,FirstName,LastName,VendorID,OrderDate,SaleStatusID,AdColorId,PublicationID,DateAssigned,DateAdCompleted,AequorDateTime,AequorModifiedDateTime)

     VALUES (Source.AdOrderID, Source.FirstName,Source.LastName,Source.VendorID, Source.OrderDate,Source.SaleStatusID,Source.AdColorId,
                Source.PublicationID,Source.DateAssigned,Source.DateAdCompleted,GetDate(),GetDate())

OUTPUT $action, Inserted.*, Deleted.*;

Ответы [ 2 ]

16 голосов
/ 08 сентября 2011

Точно так же, как дополнение к ответу Ламака, потому что эти сравнения неравенства могут быть немного утомительными, особенно если столбцы обнуляются, вы можете заменить их на NOT EXISTS(SELECT Source.* INTERSECT SELECT Target.*)

Пример использования ниже

declare @t1 table
(
id int,
col2 int NULL
)

declare @t2 table
(
id int,
col2 int NULL
)

INSERT INTO @t1 VALUES(1, NULL),(2,NULL)
INSERT INTO @t2 VALUES(1, NULL),(2,NULL), (3,NULL)

MERGE @t1 AS Target
USING  @t2 AS Source
ON (Target.id = Source.id) 
WHEN MATCHED AND NOT EXISTS(SELECT Source.* INTERSECT SELECT Target.*) THEN
         UPDATE SET 
            Target.id =Source.id
WHEN NOT MATCHED BY TARGET THEN
      INSERT (id)
      VALUES (id)
OUTPUT $action, Inserted.*, Deleted.*;
5 голосов
/ 08 сентября 2011

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

WHEN MATCHED AND (  Target.FirstName != Source.FirstName OR 
                    Target.LastName != Source.LastName OR
                    Target.VendorID != Source.VendorID OR
                    Target.OrderDate != Source.OrderDate OR
                    Target.SaleStatusID != Source.SaleStatusID OR
                    Target.AdColorId !=Source.AdColorId OR
                    Target.PublicationID !=Source.PublicationID OR
                    Target.DateAssigned !=Source.DateAssigned OR
                    Target.DateAdCompleted !=Source.DateAdCompleted)
THEN
         UPDATE SET 
            Target.AdOrderID =Source.AdOrderID,
            Target.FirstName = Source.FirstName,
            Target.LastName =Source.LastName,
            Target.VendorID =Source.VendorID,
            Target.OrderDate =Source.OrderDate,
            Target.SaleStatusID =Source.SaleStatusID,
            Target.AdColorId =Source.AdColorId,
            Target.PublicationID =Source.PublicationID,
            Target.DateAssigned =Source.DateAssigned,
            Target.DateAdCompleted =Source.DateAdCompleted,
            Target.AequorModifiedDateTime = GetDate()

В этом случае при сравнении предполагается, что каждое поле не имеет значения NULL, если это не так, вам необходимо добавить это и в логику (ISNULL или что-то в этом роде)

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