2011-09-07 6 views
18

मैं वर्तमान में स्रोत से लक्ष्य तक माइग्रेट करने के लिए नीचे विलय कोड का उपयोग कर रहा हूं। लक्ष्य पर एक अद्यतन/डालने के बाद स्रोत से रिकॉर्ड हटाने के लिए नीचे दिए गए कोड को बढ़ाने के लिए मेरी एक नई आवश्यकता है। यह संभव विलय उपयोग कर रहा है करने के लिए संशोधित/डाला पंक्तियों पर कब्जा करने केSQL सर्वर 2008 में MERGE कमांड का उपयोग कर स्रोत से कैसे हटाएं?

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

नीचे का उपयोग कर सकते आप एक ही बयान के भाग के रूप में नहीं कर सकते। प्रत्येक डेटा संशोधित कथन केवल एक ही तालिका में परिवर्तन करता है। –

+0

धन्यवाद डेमियन। – nfa379

उत्तर

28

आप उत्पादन खंड का उपयोग कर सकते हैं (सभी उदाहरण मैं नेट पर देख स्रोत पर नहीं लक्ष्य में डेल/सम्मिलित/अपडेट प्रदर्शन किया था) तालिका सारणी और मर्ज के बाद हटाए गए कथन के साथ इसका उपयोग करें।

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


अच्छा प्रतिक्रिया है, लेकिन अपने कोड अपने गंतव्य तालिका से पंक्ति को नष्ट करेगा, यहाँ एक उदाहरण जिसमें आप अपने लक्ष्य तालिका को प्रभावित किए बिना अपने स्रोत गंतव्य से हुई पंक्तियां हटाना कर सकते हैं:

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 

मुझे आशा है कि यह आप में मदद मिलेगी।

0

आप भी कोड

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