2012-06-08 7 views
73

मैंने अपने डेटाबेस में कुछ संशोधन किए हैं और मुझे पुराने डेटा को नए टेबल पर माइग्रेट करने की आवश्यकता है। इसके लिए, मुझे मूल तालिका (अभ्यास) से डेटा लेने वाली तालिका (रिपोर्टऑप्शन) भरनी होगी, और दूसरी इंटरमीडिएट टेबल (प्रैक्टिस रिपोर्टपोर्ट) भरें।एसक्यूएल आउटपुट क्लॉज के लिए कॉलम को वापस नहीं करने के लिए संभव है?

ReportOption (ReportOptionId int PK, field1, field2...) 
Practice (PracticeId int PK, field1, field2...) 
PracticeReportOption (PracticeReportOptionId int PK, PracticeId int FK, ReportOptionId int FK, field1, field2...) 

मैं सभी डेटा मैं अभ्यास से ReportOptions को स्थानांतरित करने की आवश्यकता प्राप्त करने के लिए कोई क्वेरी बना है, लेकिन मैं मध्यवर्ती मेज

--Auxiliary tables 
DECLARE @ReportOption TABLE (PracticeId int /*This field is not on the actual ReportOption table*/, field1, field2...) 
DECLARE @PracticeReportOption TABLE (PracticeId int, ReportOptionId int, field1, field2) 

--First I get all the data I need to move 
INSERT INTO @ReportOption 
SELECT P.practiceId, field1, field2... 
    FROM Practice P 

--I insert it into the new table, but somehow I need to have the repation PracticeId/ReportOptionId 
INSERT INTO ReportOption (field1, field2...) 
OUTPUT @ReportOption.PracticeId, --> this is the field I don't know how to get 
     inserted.ReportOptionId 
    INTO @PracticeReportOption (PracticeId, ReportOptionId) 
SELECT field1, field2 
    FROM @ReportOption 

--This would insert the relationship, If I knew how to get it! 
INSERT INTO @PracticeReportOption (PracticeId, ReportOptionId) 
SELECT PracticeId, ReportOptionId 
    FROM @ReportOption 

को भरने के लिए मैं एक क्षेत्र को संदर्भित कर सकता है समस्या हो रही है कि OUTPUT खंड पर गंतव्य तालिका पर नहीं है, यह बहुत अच्छा होगा (मुझे लगता है कि मैं नहीं कर सकता, लेकिन मुझे निश्चित रूप से पता नहीं है)। मेरी जरूरत को कैसे अपनाना है इस पर कोई विचार?

अग्रिम धन्यवाद।

+0

आप अपने 'आउटपुट' खंड में, उस पंक्ति के किसी भी कॉलम को वापस कर सकते हैं जिसमें आप पंक्ति डाल रहे हैं। इसलिए यदि आप अपने 'INSERT' कथन में दिए गए कॉलम के लिए कोई मान नहीं देते हैं, तो भी आप 'OUTPUT' खंड में उस कॉलम को निर्दिष्ट कर सकते हैं। हालांकि आप अन्य सारणी से एसक्यूएल चर या कॉलम वापस नहीं कर सकते हैं। –

+0

@marc_s आपके उत्तर के लिए धन्यवाद, लेकिन मेरे पास गंतव्य तालिका में मुझे आवश्यक फ़ील्ड नहीं है (मुझे प्रैक्टिसआईड की आवश्यकता है, जो रिपोर्टऑप्शन पर नहीं है) –

उत्तर

117

आप डालने के बजाय MERGE का उपयोग करके ऐसा कर सकते हैं:

इसलिए की जगह कुंजी

MERGE INTO ReportOption USING @ReportOption AS temp ON 1 = 0 
WHEN NOT MATCHED THEN 
    INSERT (field1, field2) 
    VALUES (temp.Field1, temp.Field2) 
    OUTPUT temp.PracticeId, inserted.ReportOptionId, inserted.Field1, inserted.Field2 
    INTO @PracticeReportOption (PracticeId, ReportOptionId, Field1, Field2); 

इस

INSERT INTO ReportOption (field1, field2...) 
OUTPUT @ReportOption.PracticeId, --> this is the field I don't know how to get 
     inserted.ReportOptionId 
    INTO @PracticeReportOption (PracticeId, ReportOptionId) 
SELECT field1, field2 
    FROM @ReportOption 

साथ एक बयान है कि सच कभी नहीं होगा उपयोग करने के लिए है (1 = 0) मर्ज स्टेटमेंट में, इसलिए आप हमेशा सम्मिलित करेंगे, लेकिन स्रोत और गंतव्य दोनों तालिकाओं में फ़ील्ड तक पहुंच सकते हैं।


यहाँ पूरे कोड मैं इसे परीक्षण करने के लिए प्रयोग किया जाता है:

CREATE TABLE ReportOption (ReportOptionID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
CREATE TABLE Practice (PracticeID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
CREATE TABLE PracticeReportOption (PracticeReportOptionID INT IDENTITY(1, 1), PracticeID INT, ReportOptionID INT, Field1 INT, Field2 INT) 

INSERT INTO Practice VALUES (1, 1), (2, 2), (3, 3), (4, 4) 


MERGE INTO ReportOption r USING Practice p ON 1 = 0 
WHEN NOT MATCHED THEN 
    INSERT (field1, field2) 
    VALUES (p.Field1, p.Field2) 
    OUTPUT p.PracticeId, inserted.ReportOptionId, inserted.Field1, inserted.Field2 
    INTO PracticeReportOption (PracticeId, ReportOptionId, Field1, Field2); 

SELECT * 
FROM PracticeReportOption 

DROP TABLE ReportOption 
DROP TABLE Practice 
DROP TABLE PracticeReportOption 

अधिक पढ़ने, और जो कुछ मैं इस विषय पर पता के स्रोत Here

+1

धन्यवाद, यह चाल है! मैं एक नकली अस्थायी क्षेत्र का उपयोग करने जा रहा था लेकिन यह बहुत अधिक सुरुचिपूर्ण है। –

+0

बढ़िया! यह चाल सोने का अनाज है! संग्रह में पहली पंक्ति में जोड़ा गया! –

+0

यह वही है जो मैं खोज रहा था, धन्यवाद! – fhilton

11

हो सकता है कि किसी को है जो एमएस एसक्यूएल सर्वर 2005 या निचले का उपयोग करता है, यह उत्तर उपयोगी होगा।


मेर्ज केवल SQL Server 2008 या उच्चतर के लिए काम करेगा। बाकी के लिए मुझे एक और कामकाज मिला जो आपको मैपिंग टेबल बनाने की क्षमता प्रदान करेगा।

यहाँ संकल्प एसक्यूएल 2005 के लिए की तरह दिखाई देगा का तरीका देखें:

DECLARE @ReportOption TABLE (ReportOptionID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
DECLARE @Practice TABLE(PracticeID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
DECLARE @PracticeReportOption TABLE(PracticeReportOptionID INT IDENTITY(1, 1), PracticeID INT, ReportOptionID INT, Field1 INT, Field2 INT) 

INSERT INTO @Practice (Field1, Field2) VALUES (1, 1) 
INSERT INTO @Practice (Field1, Field2) VALUES (2, 2) 
INSERT INTO @Practice (Field1, Field2) VALUES (3, 3) 
INSERT INTO @Practice (Field1, Field2) VALUES (4, 4) 

INSERT INTO @ReportOption (field1, field2) 
    OUTPUT INSERTED.ReportOptionID, INSERTED.Field1, INSERTED.Field2 INTO @PracticeReportOption (ReportOptionID, Field1, Field2) 
    SELECT Field1, Field2 FROM @Practice ORDER BY PracticeID ASC; 


WITH CTE AS (SELECT PracticeID, ROW_NUMBER() OVER (ORDER BY PracticeID ASC) AS ROW FROM @Practice) 
UPDATE M SET M.PracticeID = S.PracticeID 
    FROM @PracticeReportOption AS M 
    JOIN CTE AS S ON S.ROW = M.PracticeReportOptionID 

    SELECT * FROM @PracticeReportOption 

मुख्य चाल है कि हम स्रोत और गंतव्य तालिका से आदेश दिया डेटा के साथ दो बार मानचित्रण तालिका भरने कर रहे हैं। अधिक जानकारी के लिए यहां: Merging Inserted Data Using OUTPUT in SQL Server 2005

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