我的目标: 如果行已更新或已插入新行,则将数据从一个表移动到另一个表。
我有一张桌子我需要某些字段。我需要知道行是否已更新或插入。 Source表没有任何Timestamp字段。我正在使用MSSQL2008。数据来自客户端,他们正在控制表和复制。
我认为我已经弄清楚使用MSSQL 2008的新 Merge 函数,但无论是否有任何更改,它都会更新所有行。这通常不是一个大问题,但我必须添加时间戳字段。无论行是否已更新,我的修改时间字段都将更新。
所以我需要一种方法来完成我的上述目标。我不是一个伟大的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.*;
答案 0 :(得分:16)
正如Lamak的回答一样,因为这些不等式比较会变得有点乏味,特别是在列可以为空的情况下,您可能希望用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.*;
答案 1 :(得分:5)
如果某些值不同,您需要添加只想更新数据的限制。所以你必须改变查询的那一部分,如下所示:
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()
在这种情况下,比较假设每个字段都不可为空,如果不是这样,你需要将它添加到逻辑中(ISNULL
或类似的东西)