2010-12-03 9 views
7

नीचे दिए गए निम्न SQL कथन कुछ SQL का एक अच्छा उदाहरण है जो नेस्टेड विवरणों के साथ अपवाद फेंकता है। यह कथन के पकड़ हिस्से में लगता है कि मैं केवल बाहरी अपवाद विवरण प्राप्त कर सकता हूं Could not create constraint. See previous errors (बहुत उपयोगी नहीं!)।SQL सर्वर प्रयास करें आंतरिक अपवाद संदेश conundrum

परिचय तालिका 'तालिका 2' पर विदेशी कुँजी बाधा 'FK_TWO' चक्र या एक से अधिक झरना रास्तों का कारण हो सकता है: क्या मैं प्राप्त करना चाहते हैं भीतरी अपवाद संदेश है। किसी भी कार्रवाई को हटाएं या पर कोई कार्रवाई अपडेट करें या अन्य विदेशी कुंजी बाधाओं को संशोधित करें (आप को कोड को बिना किसी प्रयास के चलाकर प्राप्त कर सकते हैं)।

कैच ब्लॉक में, यह टी-एसक्यूएल में कैसे प्राप्त किया जा सकता है?

BEGIN TRY 
     BEGIN TRAN; 

     CREATE TABLE TABLE1 (USER_ID INTEGER NOT NULL PRIMARY KEY, USER_NAME 
      CHAR(50) NOT NULL); 

     CREATE TABLE TABLE2 (AUTHOR_ID INTEGER NOT NULL PRIMARY KEY, AUTHOR_NAME 
      CHAR(50) NOT NULL, LASTMODIFIEDBY INTEGER NOT NULL, ADDEDBY INTEGER NOT 
      NULL); 

     ALTER TABLE TABLE2 ADD CONSTRAINT FK_ONE FOREIGN KEY (LASTMODIFIEDBY) 
      REFERENCES TABLE1 (USER_ID) ON DELETE CASCADE ON UPDATE CASCADE; 

     ALTER TABLE TABLE2 ADD CONSTRAINT FK_TWO FOREIGN KEY (ADDEDBY) 
      REFERENCES TABLE1(USER_ID) ON DELETE NO ACTION ON UPDATE CASCADE; 

     COMMIT TRAN; 
END TRY 
BEGIN CATCH 

     DECLARE @ERROR_MSG NVARCHAR(MAX), @SEVERITY INT, @STATE INT 
     SELECT @SEVERITY = ERROR_SEVERITY(), @STATE = ERROR_STATE() 
      , @ERROR_MSG = ERROR_MESSAGE() + ' err src line: ' + CAST(ERROR_LINE() AS NVARCHAR(20)) + ' ' + ISNULL(ERROR_PROCEDURE(), ''); 

     ROLLBACK; 
     -- RE-THROW EXCEPTION FOR DIAGNOSTIC VISIBILITY 
     RAISERROR (@ERROR_MSG ,@SEVERITY, @STATE); 
END CATCH; 

[संपादित करें]

तो यह बहुत बाद खोज लगता है इस समस्या का कोई समाधान नहीं है। उम्मीद है कि वे इसे भविष्य के संस्करण में ठीक कर देंगे।

+1

मुझे नहीं लगता कि ऐसा करने का कोई तरीका है। यह संबंधित प्रश्न भी देखें: [एक ही कथन से एकाधिक त्रुटि संदेशों को कैप्चर करना] (http://stackoverflow.com/questions/3697492/capturing-multiple-error-messages-from-a-single-statement) –

उत्तर

0

अब इस समस्या का कोई समाधान नहीं है। this के अनुसार SQL सर्वर के अगले संस्करण में समाधान नए फेंक कीवर्ड का उपयोग करना होगा जो दोनों त्रुटियों को दोबारा बढ़ाएगा।

+0

[हो सकता है एक समाधान यदि आप इसे काम करने के लिए आउटपुट बफर को पार्स करने के बारे में गड़बड़ करने के इच्छुक हैं!] (http://stackoverflow.com/questions/3697492/capturing-multiple-error-messages-from-a-single-statement/5773071 # 5773071) –

9

आप मूल त्रुटि को फिर से फेंक नहीं सकते हैं। आपको 50000 से ऊपर त्रुटि संख्या के साथ नया त्रुटि फेंकनी है, जिसमें कैप्चर किए गए त्रुटि संदेश शामिल हैं। एक उदाहरण के लिए Exception handling and nested transactions देखें:

begin catch 
    declare @error int, @message varchar(4000), @xstate int; 
    select @error = ERROR_NUMBER() 
     , @message = ERROR_MESSAGE(); 
raiserror ('Caught exception: %d: %s', 16, 1, @error, @message) ; 
return; 
end catch 

लेख मैं जुड़ा हुआ एक अधिक गहन उदाहरण के लिए, यह भी कवर अनिवार्य XACT_STATE() जांच और लेनदेन अर्थ विज्ञान के साथ ट्राई/कैच ब्लॉक मिश्रण है।

अगले संस्करण ("डेनाली") के साथ यह समस्या ठीक हो गई है, क्योंकि आपके पास throw; w/o कोई तर्क जारी करने की क्षमता है, जो अन्य प्रयास/पकड़ भाषाओं में मूल अपवाद उठाएगा। TRY CATCH THROW: Error handling changes in T-SQL

अपडेट किया गया

डी 'ओह मैं इन सबसे छुटकारा विकर्ण में पोस्ट पढ़ देखें। यदि अधिक अपवाद उठाए गए हैं, तो आप केवल एक ही पकड़ सकते हैं। यह अभी भी सच है, डेनाली के साथ भी। लेकिन ज्यादातर बार उठाए गए अपवाद गंभीरता 0 होते हैं (जिसका अर्थ है कि वे वास्तव में प्रिंट हैं, अपवाद नहीं हैं) और वे अभी भी इसे क्लाइंट को सूचनात्मक संदेश (SqlConnection.InfoMessage ईवेंट) के रूप में बनाते हैं।