मेरे पास एक लक्ष्य तालिका है जिसमें 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
चलाने के लिए है? क्या यह हासिल करने के लिए कोई और चालाक तरीका है?
यदि आप कोशिश करते हैं तो आप देखेंगे कि यह पंक्ति में पंक्ति के लिए '3 2 0' देता है। कारण यह है कि जब आप 't.id = source.id' पर शामिल होते हैं, तो पंक्ति 3 के लिए कोई' t' नहीं होता है। इसे पंक्ति 2 के समान माना जाता है और सक्रिय में चिह्नित किया जाता है। –
@ किर्कबॉडहर्स्ट यह मेरे लिए नहीं है! – podiluska
से ऊपर पूर्ण परीक्षण देखें, मैं देखता हूं, मैं पढ़ने के लिए बहुत जल्दी था। बहुत बढ़िया जवाब धन्यवाद! मुझे नहीं पता था कि मैं वहां सशर्त रख सकता हूं। –