2012-05-18 4 views
26

कहें कि मेरे पास एक पहचान फ़ील्ड वाला टेबल है। मैं इसमें एक रिकॉर्ड डालना चाहता हूं अगर यह पहले से मौजूद नहीं है। नीचे दिए गए उदाहरण में, मैं जांचता हूं कि तालिका में @ फ़ील्ड 1 में संग्रहीत मान पहले से मौजूद है या नहीं।जब कोई मैच होता है तो आप MERGE का उपयोग करने के बाद पहचान मान कैसे प्राप्त करते हैं?

तालिका की परिभाषा:: यदि नहीं, तो मैं एक नया रिकॉर्ड सम्मिलित

MyTable (MyTableId int Identity not null, Field1 int not null, Field2 int not null) 

यह मैं कैसे की जाँच है अगर मूल्य पहले से मौजूद है और यदि आवश्यक हो

merge MyTable as t 
using (@Field1, @Field2) as s (Field1,Field2) 
on (t.Field1=s.Field1) 
when not matched then 
    insert (Field1,Field2) values (s.Field1,s.Field2); 

पहचान हो रही डालें मान जब तालिका में रिकॉर्ड पहले से मौजूद नहीं था, तो जोड़कर किया जा सकता है:

output Inserted.MyTableId 

लेकिन क्या होगा यदि रिकॉर्ड पहले से ही तालिका में था (यानी यदि कोई मैच था)?

एक ही रास्ता मैंने पाया मर्ज बयान को क्रियान्वित करने के बाद तालिका क्वेरी करने के लिए है:

select MyTableId from MyTable where [email protected] 

वहाँ एक रास्ता मर्ज से सीधे पहचान मूल्य प्राप्त करने के है?

उत्तर

25

मामला है जब रिकॉर्ड पहले से मौजूद है, तो आप इस तरह एक चर में मिलान किया आईडी स्टोर कर सकते हैं:

DECLARE @MatchedId INTEGER; 

MERGE MyTable as t 
.... 
.... 
WHEN MATCHED THEN 
    UPDATE SET @MatchedId = t.MyTableId; 

अद्यतन:
यहाँ एक पूर्ण उदाहरण है।

DECLARE @UpdateVariable bit 
DECLARE @ChangeResult TABLE (ChangeType VARCHAR(10), Id INTEGER) 
DECLARE @Data TABLE (Id integer IDENTITY(1,1), Val VARCHAR(10)) 
INSERT @Data ([Val]) VALUES ('A'); 

MERGE @data AS TARGET 
USING (SELECT 'A' AS Val UNION ALL SELECT 'B' AS Val) AS SOURCE ON TARGET.Val = SOURCE.Val 
WHEN NOT MATCHED THEN 
    INSERT ([Val]) 
    VALUES (SOURCE.Val) 
WHEN MATCHED THEN 
    UPDATE SET @UpdateVariable = 1 
OUTPUT $action, inserted.Id INTO @ChangeResult; 

SELECT * FROM @data 
SELECT * FROM @ChangeResult 

अंक दिये गये हैं::

  • $ कार्रवाई (, सम्मिलित करें, अद्यतन हटाएं) दे देंगे कार्रवाई की किस प्रकार एक पंक्ति के लिए प्रदर्शन किया गया था
  • @ChangeResult तालिका यह एक तरीका है यह दर्शाता है जब भी MATCHED मामले के लिए
  • के लिए किस तरह के परिवर्तन किए गए थे, इस बारे में जानकारी होगी, मैं मूल रूप से एक डमी चर सेट कर रहा हूं। यह आउटपुट में अद्यतन पंक्ति उत्पन्न करने के लिए अद्यतन पथ को हिट करने के अलावा अन्य किसी भी उद्देश्य की सेवा नहीं करता है। यानी कि @UpdateVariable किसी और चीज़ के लिए उपयोग नहीं किया जाता है। यदि आप वास्तव में मौजूदा पंक्ति को अपडेट करना चाहते हैं, तो आप यहां उचित अपडेट डालेंगे, लेकिन उस स्थिति में जहां आप वास्तव में मौजूदा पंक्ति को अपडेट नहीं करना चाहते हैं, तो यह "डमी" अपडेट आवश्यक है।

    DECLARE @Id [int]; 
    
    MERGE INTO [MyTable] AS [t] 
    USING (VALUES 
        (@FieldA, @FieldB) 
    ) 
    AS [x] (FieldA, FieldB) 
    ON [t].[FieldA] = [x].[FieldA] 
    AND [t].[FieldB] = [x].[FieldB] 
    WHEN NOT MATCHED BY TARGET THEN 
        INSERT (FieldA, FieldB) 
        VALUES (FieldA, FieldB) 
    WHEN MATCHED THEN 
        UPDATE SET @Id = [t].[Id] 
    
    IF @Id IS NULL 
    BEGIN 
        SET @Id = CAST(SCOPE_IDENTITY() as [int]); 
    END 
    SELECT @Id; 
    

    मर्ज बयान एक मैच तो @Id मिलान पंक्ति की पहचान करने के लिए स्थापित किया जाएगा में हुई हैं:

+1

धन्यवाद एड्रियन लेकिन यदि कोई मिलान नहीं हुआ है तो आप @MatchedId में नया पहचान मान कैसे प्राप्त करते हैं? – Anthony

+4

अद्यतन के लिए धन्यवाद। हां यह काम करेगा लेकिन ऐसा लगता है कि यह मर्ज के बाद "MyTableId MyTableId का चयन करें जहां फ़ील्ड 1 = @ फील्ड 1" मर्ज करने के बाद यह बहुत अधिक कोड है (जाहिर है यह वास्तविक तालिका आदि के आकार पर निर्भर करता है)।मैं बस उम्मीद कर रहा था कि मर्ज स्टेटमेंट में 'अंतर्निर्मित' समाधान था जो दोनों मामलों (मिलान या मिलान से) में पहचान मान वापस कर देगा। – Anthony

17

यहाँ एक विकल्प है और थोड़ा सरल तरीका (मेरी राय में) है। किसी भी मैच की स्थिति में, नई पंक्ति SCOPE_IDENTITY() से चुनी जाने के लिए तैयार अपनी नई पहचान के साथ डाली जाएगी।

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

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