2013-03-25 6 views
6

में नहीं है, मैं एक आवेदन से संबंधित तालिका को संसाधित करने के लिए एक संग्रहीत प्रक्रिया लिख ​​रहा हूं और उसी एप्लिकेशन से संबंधित तालिका में मान डालता हूं (इसलिए मैं तालिका में संशोधन नहीं कर सकता)।मूल्य डालने के लिए OUTPUT क्लॉज का उपयोग INSERTED

मुझे केवल नए रिकॉर्ड संसाधित करना है और याद रखना है कि कौन से रिकॉर्ड संसाधित किए गए हैं, इसके लिए मैंने एक तीसरी सरल तालिका बनाई है।

टेबल्स नीचे दिए गए हैं, कई कॉलम केवल महत्वपूर्ण विवरण छोड़ने के लिए हटा दिए गए हैं।

स्रोत तालिका

CREATE TABLE [dbo].[DETAIL](
    [DET_NET] [float] NULL, 
    [DET_VAT] [float] NULL, 
    [DET_VATCODE] [varchar](4) NULL, 
    [DET_GROSS] [float] NULL, 
    [DET_DATE] [datetime] NULL, 
    [DET_PRIMARY] [float] NOT NULL 
) 

लक्ष्य तालिका

CREATE TABLE [dbo].[TRN_TEMP](
    [TRN_TRAN_DATE] [datetime] NULL, 
    [TRN_DESCRIPTION] [varchar](20) NULL, 
    [TRN_PRIMARY] [int] NULL, 
    [TRN_AMT] [float] NULL 
) 

ट्रैकिंग तालिका

CREATE TABLE REGISTER(
    LINE_ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED NOT NULL, 
    DET_PRIMARY_LINK FLOAT NOT NULL, 
    INS_DATE DATETIME NOT NULL 
) 

मैं कोशिश कर रहा हूँ टी o स्रोत तालिका से लक्ष्य तालिका मानों में सम्मिलित करें, लेकिन ट्रैकिंग तालिका में स्रोत तालिका की प्राथमिक कुंजी भी डालें।

INSERT INTO TRN_TEMP (TRN_TRAN_DATE, TRN_DESCRIPTION, TRN_AMT) 
OUTPUT D.DET_PRIMARY, GETDATE() INTO REGISTER (DET_PRIMARY_LINK, INS_DATE) 
SELECT D.DET_DATE, 'SOMETEXT', SUM(D.DET_NET) 
FROM DETAIL D 
LEFT JOIN REGISTER R ON D.DET_PRIMARY = R.DET_PRIMARY_LINK 
WHERE <MY CONDITIONS> AND R.LINE_ID IS NULL -- TO REMOVE LINES ALREADY PROCESSED 
GROUP BY D.DET_DATE 

मैं ऊपर पाठ के साथ एक समस्या नहीं देख सकते हैं, लेकिन मैं कोई त्रुटि मिलती है "बहु हिस्सा पहचानकर्ता 'D.DET_PRIMARY' बाध्य नहीं किया जा सकता है।"। मैंने D.DET_DETAIL और DETAIL.DET_DETAIL दोनों की कोशिश की है और त्रुटि वही है।

क्या समूह का उपयोग करते समय OUTPUT खंड में स्रोत तालिका से मूल्यों का उपयोग करना संभव नहीं है या क्या मुझे स्वरूपण में कोई त्रुटि है? यदि यह संभव नहीं है तो ट्रैक करने का एक और तरीका है कि मैंने किन लाइनों को संसाधित किया है?

उत्तर

7

उपयोग MERGE बजाय INSERT:

MERGE 
INTO trn_temp d 
USING (
     SELECT D.DET_DATE, 'SOMETEXT' AS sometext, SUM(D.DET_NET) AS the_sum 
     ... 
     ) s 
ON  (1 = 0) 
WHEN NOT MATCHED THEN 
INSERT (TRN_TRAN_DATE, TRN_DESCRIPTION, TRN_AMT) 
VALUES (det_date, sometext, the_sum) 
OUTPUT s.* 

अद्यतन:

GROUP BY समस्या को हल करने के लिए, इस का उपयोग करें:

DECLARE @tmp TABLE 
     (
     det_primary INT NOT NULL PRIMARY KEY 
     ) 

MERGE 
INTO register r 
USING detail d 
ON  (r.det_primary_link = d.det_primary) 
WHEN NOT MATCHED THEN 
INSERT (det_primary_link, ins_date) 
VALUES (det_primary, GETDATE()) 
OUTPUT d.det_primary 
INTO @tmp; 

INSERT 
INTO trn_temp (trn_tran_date, trn_description, trn_amt) 
OUTPUT INSERTED.* 
SELECT det_date, 'sometext', SUM(det_net) 
FROM @tmp t 
JOIN detail d 
ON  d.det_primary = t.det_primary 
GROUP BY 
     det_date 
+0

यह दिलचस्प लगता है, मैं समझता हूं कि 'क्या हो जाता है' हालांकि, ऐसा लगता है कि लक्षित तालिका 'मेर्ज इन' के बाद जाती है लेकिन आप ट्रैकिंग तालिका कहां घोषित करते हैं? क्या यह 'आउटपुट' खंड के बाद है जैसे 'आउटपुट'। * [रजिस्ट्रार] में? – bendataclear

+0

@ बेंडटाक्लर: 'आउटपुट' के ऊपर की पूरी चीज 'से चुनें * से चुनें * ... (...) s'। हां, आप 'आउटपुट' * रजिस्टर में नहीं कर सकते हैं (या अल्पविराम सीमांकित कॉलम सूची प्रदान करते हैं)। – Quassnoi

+0

मुझे लगता है कि मुझे कोई समस्या है, मैं 'DET_PRIMARY' फ़ील्ड को आउटपुट करने का प्रयास कर रहा हूं लेकिन मैं इस क्षेत्र द्वारा समूहबद्ध नहीं कर रहा हूं, यह संभव है कि प्रत्येक मान में 2 या अधिक आईडी शामिल हो। – bendataclear

2

मैं जानता हूँ कि इस सवाल का लगभग एक वर्ष है पुराना है, लेकिन अगर आप उचित कोल्लू चुनते हैं तो आपका सम्मिलन इसे प्रस्तुत कर सकता है OUTPUT

आउटपुट क्लॉज हमें संचालन के आधार पर दो संभावित वर्चुअल टेबल, डाला या हटा दिया गया है, एक अपडेट ऑपरेशन दोनों देता है। चूंकि आपके पास आपके TRN_TEMP तालिका में फ़ील्ड नाम DET_DATE नहीं है जिसे आपने अभी डाला है, यह आउटपुट कथन में अमान्य है।

INSERT INTO TRN_TEMP (TRN_TRAN_DATE, TRN_DESCRIPTION, TRN_AMT) 
OUTPUT INSERTED.TRN_TRAN_DATE, GETDATE() 
INTO REGISTER (DET_PRIMARY_LINK, INS_DATE) 
SELECT D.DET_DATE, 'SOMETEXT', SUM(D.DET_NET) 
FROM DETAIL D 
LEFT JOIN REGISTER R ON D.DET_PRIMARY = R.DET_PRIMARY_LINK 
WHERE <MY CONDITIONS> AND R.LINE_ID IS NULL -- TO REMOVE LINES ALREADY PROCESSED 
GROUP BY D.DET_DATE 
+0

हालांकि मैं' मैंने पहले से ही 'मेर्ज' उत्तर लागू किया है, मैं इसे बदलने पर विचार कर सकता हूं क्योंकि ऐसा लगता है कि यह बेहतर प्रदर्शन करेगा, धन्यवाद। – bendataclear

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

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