2012-06-27 11 views
11

मेरे पास एक लक्ष्य तालिका है जिसमें IsActive ध्वज है, और मैं MERGE कथन का उपयोग करके स्रोत तालिका से सम्मिलित और अद्यतन कर रहा हूं। अगर स्रोत तालिका में कुछ मौजूद है तो यह सक्रिय है, और यदि ऐसा नहीं होता है तो यह सक्रिय नहीं है। तर्क बहुत सरल है:क्या मैं किसी MERGE कथन में लक्ष्य पर WHERE क्लॉज लागू कर सकता हूं?

  • अगर यह स्रोत में मौजूद है और लक्ष्य पंक्ति IsActive सच
  • अगर यह एकमात्र स्रोत तो एक नई पंक्ति लक्षित करने के लिए डाला जाना चाहिए में मौजूद होना चाहिए, IsActive साथ सच
  • यदि यह केवल लक्ष्य में मौजूद है तो IsActive को गलत पर सेट किया जाना चाहिए।

लक्ष्य तालिका को छोड़कर सभी बहुत सरल, एक भेदक कॉलम SourceId है जो स्रोत तालिका से संबंधित है। तो किसी दिए गए स्रोत तालिका के लिए, मैं संबंधित SourceId के साथ पंक्तियों के विरुद्ध केवल MERGE चाहता हूं।

(मेरे सामान्यीकृत तालिका कई सिस्टम से समान डेटा प्रकार के पंक्तियां हैं - मैं व्यक्तिगत रूप से और इस तरह उन प्रणालियों से डेटा पुनः प्राप्त एक समय में एक स्रोत से मर्ज करने के लिए की जरूरत है)

यहाँ एक उदाहरण है:

IF OBJECT_ID('tempdb..#target') IS NOT NULL DROP TABLE #target  
IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source 

CREATE TABLE #target (Id INT, SourceId INT, IsActive BIT) 
INSERT #target VALUES (1, 1, 0) 
INSERT #target VALUES (2, 1, 1) 
INSERT #target VALUES (3, 2, 1) 

CREATE TABLE #source (Id INT)  
INSERT #source VALUES (1) 
INSERT #source VALUES (4) 

DECLARE @SourceId INT = 1;  
SELECT * FROM #target 

MERGE INTO #target t 
USING 
(
    SELECT [Id] FROM #source 
) AS s 
ON t.[Id] = s.[Id] AND t.[SourceId] = @SourceId 
WHEN MATCHED THEN UPDATE SET [IsActive] = 1 
WHEN NOT MATCHED BY TARGET THEN INSERT VALUES ([Id], @SourceId, 1) 
WHEN NOT MATCHED BY SOURCE THEN UPDATE SET [IsActive] = 0; 

SELECT * FROM #target 

मेरा प्रारंभिक प्रयास मर्ज स्थिति में AND t.[SourceId] = @SourceId को शामिल करना था, लेकिन जाहिर है कि यह काम नहीं करेगा - यह वस्तुओं को मर्ज करने के लिए प्रतिबंधित है, लेकिन लक्ष्य तालिका नहीं है। लक्ष्य पंक्ति आईडी = 3 मेल नहीं खाएगी, और इसलिए इसे निष्क्रिय करने के लिए सेट किया जाएगा, चाहे वह अतिरिक्त स्थिति शामिल हो या नहीं।

अंत परिणाम यह है कि जब भी किसी स्रोत सिस्टम के लिए प्रक्रिया चलती है, तो अन्य सभी सिस्टम निष्क्रिय हो जाएंगे।

मेरे समाधान अब तक MERGE केवल MATCHED और NOT MATCHED BY TARGET के लिए चलाने के लिए, और फिर बेजोड़ पंक्तियों

UPDATE #target 
SET [IsEnabled] = 0 
WHERE [SourceId] = @SourceId 
AND [ID] NOT IN (SELECT [ID] FROM #source) 

वहाँ किसी भी तरह से MERGE बयान में इस फ़िल्टर की शर्त शामिल करने के लिए है के लिए एक बाद UPDATE चलाने के लिए है? क्या यह हासिल करने के लिए कोई और चालाक तरीका है?

उत्तर

7

तो अपने परिणाम सेट

1 1 1 
2 1 0  
3 2 1 
4 1 1 

होना चाहिए जो मामले में अपने मर्ज बयान होना चाहिए

merge #target as t 
using #source as source 
on (t.id=source.id) 
when matched then update set isactive=1 
when not matched by target then insert values (id, @sourceid,1) 
when not matched by source and [email protected] then update set isactive=0 

पूर्ण परीक्षण:

CREATE TABLE #target (Id INT, SourceId INT, IsActive BIT)  
INSERT #target VALUES (1, 1, 0) 
INSERT #target VALUES (2, 1, 1) 
INSERT #target VALUES (3, 2, 1) 

CREATE TABLE #source (Id INT)  
INSERT #source VALUES (1) 
INSERT #source VALUES (4) 

DECLARE @SourceId INT 
select @SourceId = 1;  

merge #target as t 
using #source as source 
on (t.id=source.id) 
when matched then update set isactive=1 
when not matched by target then insert values (id, @sourceid,1) 
when not matched by source and [email protected] then update set isactive=0; 


SELECT * FROM #target 

drop table #target; 
drop table #source 

परिणाम ...

Id   SourceId IsActive 
----------- ----------- -------- 
1   1   1 
2   1   0 
3   2   1 
4   1   1 
+0

यदि आप कोशिश करते हैं तो आप देखेंगे कि यह पंक्ति में पंक्ति के लिए '3 2 0' देता है। कारण यह है कि जब आप 't.id = source.id' पर शामिल होते हैं, तो पंक्ति 3 के लिए कोई' t' नहीं होता है। इसे पंक्ति 2 के समान माना जाता है और सक्रिय में चिह्नित किया जाता है। –

+1

@ किर्कबॉडहर्स्ट यह मेरे लिए नहीं है! – podiluska

+0

से ऊपर पूर्ण परीक्षण देखें, मैं देखता हूं, मैं पढ़ने के लिए बहुत जल्दी था। बहुत बढ़िया जवाब धन्यवाद! मुझे नहीं पता था कि मैं वहां सशर्त रख सकता हूं। –

संबंधित मुद्दे