2011-09-07 13 views
18

Şu an kaynağından hedefe geçiş yapmak için aşağıdaki birleştirme kodunu kullanıyorum. Hedefe bir güncelleme/ekleme yapıldığında kaydı kaynağından silmek için aşağıdaki kodu genişletmek için yeni bir gereksinimim var. birleştirme kullanarak bu mümkün mü modifiye/eklenen satırları yakalamak içinSQL Server 2008'de MERGE komutunu kullanarak kaynaktan nasıl silinir?

MERGE Target1 AS T 
USING Source1 AS S 
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) 
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName 
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%' 
    THEN DELETE ; 
+1

altında kullanabilirsiniz. Her bir veri değiştirme ifadesi sadece tek bir tabloda değişiklik yapar. –

+0

Teşekkür ederim Damien. – nfa379

cevap

28

Sen çıkış maddesini kullanabilirsiniz (i net gördüğünüz tüm örnekler değil kaynağa hedefteki del/ekleme/güncelleme yapmadan vardı) Bir tablo değişkeni ve birleştirme sonrası bir silme ifadesi ile kullanın.

DECLARE @T TABLE(EmployeeID INT); 

MERGE Target1 AS T 
USING Source1 AS S 
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) 
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName 
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%' 
    THEN DELETE 
OUTPUT S.EmployeeID INTO @T; 

DELETE Source1 
WHERE EmployeeID in (SELECT EmployeeID 
        FROM @T); 
2


Güzel Karşılık, ancak hedef tablodan satır silmek Kodunuz, burada hedef tablo etkilemeden kaynak hedef satırları silebilirsiniz wich bir exemple var:

if OBJECT_ID('audit.tmp1') IS NOT NULL 
    DROP TABLE audit.tmp1 

select * 
into audit.tmp1 
from 
(
select 1 id, 'aa' nom, convert(date,'2014-01-01') as dd UNION ALL 
select 2 id, 'bb' nom, convert(date,'2013-07-12') as dd UNION ALL 
select 3 id, 'cc' nom, convert(date,'2012-08-21') as dd UNION ALL 
select 4 id, 'dd' nom, convert(date,'2011-11-15') as dd UNION ALL 
select 5 id, 'ee' nom, convert(date,'2010-05-16') as dd) T 


if OBJECT_ID('audit.tmp2') IS NOT NULL 
DROP TABLE audit.tmp2 

select * 
into audit.tmp2 
from 
(
select 1 id, 'aAa' nom, convert(date,'2014-01-14') as dd UNION ALL 
select 2 id, 'bbB' nom, convert(date,'2013-06-13') as dd UNION ALL 
select 4 id, 'dDD' nom, convert(date,'2012-11-05') as dd UNION ALL 
select 6 id, 'FFf' nom, convert(date,'2014-01-12') as dd) T 


SELECT * FROM audit.tmp1 order by 1 
SELECT * FROM audit.tmp2 order by 1 


DECLARE @T TABLE(ID INT); 

MERGE audit.tmp2 WITH (HOLDLOCK) AS T 
USING (SELECT * FROM audit.tmp1 WHERE nom <> 'dd') AS S 
ON (T.id = S.id) 
WHEN NOT MATCHED BY TARGET 
THEN INSERT(id, nom, dd) VALUES(S.id, S.nom, S.dd) 
WHEN MATCHED 
THEN UPDATE SET T.nom = S.nom, T.dd = S.dd 
WHEN NOT MATCHED BY SOURCE 
THEN UPDATE SET T.id = T.id OUTPUT S.id INTO @T; 

DELETE tmp1 
FROM audit.tmp1 
INNER JOIN 
@T AS DEL 
    ON DEL.id = tmp1 .id 


SELECT * FROM audit.tmp1 ORDER BY 1 
SELECT * FROM audit.tmp2 ORDER BY 1 

Umarım bu size yardımcı olacaktır.

0

da tek bir ifadenin parçası olarak bunu yapamaz kod

drop table energydata 

create table temp_energydata 
(
webmeterID int, 
DT DateTime , 
kWh varchar(10) 
) 

Insert into temp_energydata 
select 1,getdate()-10, 120 
union 
select 2,getdate()-9, 140 
union 
select 3,getdate()-6, 37 
union 
select 4,getdate()-3, 40 
union 
select 5,getdate()-1, 240 

create table energydata 
(
webmeterID int, 
DT DateTime , 
kWh varchar(10) 
) 

Insert into energydata (webmeterID,kWh) 
select 1, 120 
union 
select 2, 140 
union 
select 3, 37 
union 
select 4, 40 

select * from energydata 
select * from temp_energydata 

begin tran ABC 

DECLARE @T TABLE(ID INT); 

MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target 
USING dbo.temp_energydata AS source 
    ON target.webmeterID = source.webmeterID 
    AND target.kWh = source.kWh 

WHEN MATCHED THEN 
    UPDATE SET target.DT = source.DT 

WHEN NOT MATCHED BY source THEN delete 
OUTPUT source.webmeterID INTO @T; 


DELETE temp_energydata 
WHERE webmeterID in (SELECT webmeterID 
        FROM @T); 
    --INSERT (webmeterID, DT, kWh) 
    --VALUES (source.webmeterID, source.DT, source.kWh) 


rollback tran ABC 
commit tran ABC