SQL स्क्रिप्ट निष्पादन को कैसे तोड़ें


16

मैं sql स्क्रिप्ट पर काम कर रहा हूं और मुझे कुछ शर्तों से संतुष्ट नहीं होने पर स्क्रिप्ट को जारी रखने की आवश्यकता है।

जब मैंने इसे गूगल किया, तो मैंने पाया कि 20 गंभीरता स्तर के साथ रईसआयर को समाप्त कर दूंगा। लेकिन कुछ कारणों से मैं उस विकल्प का उपयोग नहीं कर सकता।

कृपया मुझे प्रदान कर सकते हैं कि SQL स्क्रिप्ट निष्पादन को रोकने के लिए संभावित विकल्प क्या हैं।


1
अस्वीकार्य त्रुटि क्यों बढ़ रही है? क्या यह स्क्रिप्ट एक संग्रहीत प्रक्रिया है?
नामीबिया

मैं आपके मुट्ठी के सवाल को स्पष्ट रूप से नहीं समझ पाया। दूसरे प्रश्न के लिए; नहीं, यह SP नहीं है
New Developer

1
स्क्रिप्ट क्या है? क्या इसमें कई बैच शामिल हैं? क्या आपने यहाँ उत्तर देखे हैं?
मार्टिन स्मिथ

जवाबों:


8

से RAISERROR प्रलेखन (जोर मेरा):

किसी भी उपयोगकर्ता द्वारा 0 से 18 के बीच गंभीर स्तर निर्दिष्ट किया जा सकता है। 19 से 25 के बीच गंभीरता का स्तर केवल sysadmin निश्चित सर्वर भूमिका या ALTER TRACE अनुमतियों वाले उपयोगकर्ताओं द्वारा निर्दिष्ट किया जा सकता है। 19 से 25 के बीच गंभीरता स्तर के लिए, लॉग विकल्प के साथ की आवश्यकता है।

यह अत्यधिक संभावना है कि आप इन मानदंडों को पूरा नहीं करने वाले प्रिंसिपल को स्क्रिप्ट निष्पादित कर रहे हैं।

उपयोग करने में कुछ भी गलत नहीं है RAISERROR; आप एक गंभीरता स्तर का उपयोग कर रहे हैं जो अत्यधिक है। मैं स्तर 16 का उपयोग एक त्रुटि के लिए एक डिफ़ॉल्ट के रूप में करता हूं जो उठाया जाता है और अनुक्रम समाप्त हो जाएगा। यदि आप अधिक सटीक होना चाहते हैं, तो आप स्वयं Microsoft द्वारा दिए गए स्तरों का अनुसरण कर सकते हैं:

यहाँ छवि विवरण दर्ज करें

अब, स्क्रिप्ट के संदर्भ के आधार पर, सभी का उपयोग RAISERRORकरना पर्याप्त नहीं हो सकता है, क्योंकि यह स्क्रिप्ट को अपने आप से "बाहर" नहीं करता है (सामान्य गंभीरता के स्तर का उपयोग करके)।

उदाहरण के लिए:

RAISERROR(N'Test', 16, 1);

SELECT 1;   /* Executed! */

यह दोनों एक त्रुटि बढ़ाएगा और परिणाम सेट लौटाएगा।

स्क्रिप्ट को तुरंत समाप्त करने के लिए, मैं उपयोग करना पसंद करता हूं RETURN( GOTOआमतौर पर निर्माण का उपयोग करके अधिकांश प्रोग्रामिंग सर्किलों में निराश किया जाता है जहां वैकल्पिक रूप से मौजूद हैं:

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */

या त्रुटि का उपयोग करके संभालें TRY/CATCH, जो CATCHकि गंभीरता 11 या अधिक होने पर ब्लॉक में कूदने के लिए निष्पादन का कारण बनेगा :

BEGIN TRY
    RAISERROR(N'Test', 16, 1);
    SELECT 1;   /* Not executed */
END TRY
BEGIN CATCH
    SELECT 2;   /* Executed */
END CATCH

BEGIN TRY
    RAISERROR(N'Test', 10, 1);
    SELECT 1;   /* Executed */
END TRY
BEGIN CATCH
    SELECT 2;   /* Not executed */
END CATCH

एक अलग समस्या यह है कि यदि स्क्रिप्ट कई बैचों को फैलाती है - RETURNकेवल बैच से बाहर निकल जाएगी :

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

SELECT 2;   /* Executed! */

इसे ठीक करने के लिए, आप @@ERRORप्रत्येक बैच की शुरुआत में देख सकते हैं :

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

IF (@@ERROR != 0)
    RETURN;

SELECT 2;   /* Not executed */

संपादित करें: जैसा कि मार्टिन स्मिथ टिप्पणियों में सही ढंग से बताते हैं, यह केवल 2 बैचों के लिए काम करता है। 3 या अधिक बैचों का विस्तार करने के लिए, आप त्रुटियों को उठा सकते हैं जैसे (नोट: GOTOविधि इस समस्या को हल नहीं करती है क्योंकि लक्ष्य लेबल को बैच के भीतर परिभाषित किया जाना चाहिए):

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

IF (@@ERROR != 0)
BEGIN
    RAISERROR(N'Error already raised. See previous errors.', 16, 1);
    RETURN;
END

SELECT 2;   /* Not executed */
GO

IF (@@ERROR != 0)
BEGIN
    RAISERROR(N'Error already raised. See previous errors.', 16, 1);
    RETURN;
END

SELECT 3;   /* Not executed */

या, जैसा कि वह बताते हैं, यदि आप अपने वातावरण के लिए उपयुक्त हैं तो आप इस SQLCMDविधि का उपयोग कर सकते हैं ।


वह आखिरी सुझाव काम नहीं करता है। पास्टबिन देखें । मुझे यहां sqlcmd विधि
मार्टिन स्मिथ

6

आप GOTOजहाँ चाहें चारों ओर स्किप करने के लिए स्टेटमेंट का उपयोग कर सकते हैं। दूसरे शब्दों में, आप एक त्रुटि या किसी अन्य स्थिति में भाग लेते हैं, और आपके पास स्क्रिप्ट के तल पर एक लेबल हो सकता है (यानी TheEndOfTheScript:) और बस एक goto TheEndOfTheScript;बयान जारी करें।

यहाँ एक त्वरित नमूना है:

print 'here is the first statement...';

print 'here is the second statement...';

-- substitute whatever conditional flow determining factor
-- you'd like here. I have chosen a dummy statement that will
-- always return true
--
if (1 = 1)
    goto TheEndOfTheScript;

print 'here is the third statement...';

print 'here is the fourth statement...';


TheEndOfTheScript:
print 'here is the end of the script...';

इस निष्पादन का आउटपुट निम्नलिखित होगा:

here is the first statement...
here is the second statement...
here is the end of the script...

जैसा कि आप देख सकते हैं, GOTOतीसरे और चौथे स्टेटमेंट को प्रिंट करना छोड़ दिया है और लेबल ( TheEndOfTheScript) पर राइट जंप किया है ।


7
केवल एक ही बैच होने पर काम करता है, जैसे ही आप एक GO स्टेटमेंट तोड़ेंगे।
गेब्रियल

4

0

के साथ सहमत हैं SET NOEXEC ON/OFF, हालांकि संग्रहित Procs (एक एकल ब्लॉक युक्त) में मैं केवल RETURNकथन का उपयोग करता हूं ।

कैविट्स: एक स्क्रिप्ट फ़ाइल में, यदि आपके पास कई GOकथन हैं, तो RETURNकेवल वर्तमान ब्लॉक से बाहर निकलेगा और अगले ब्लॉक / बैच के साथ जारी रहेगा।

नोट: GOTOमाना जाता है कि एक बुरा कोडिंग अभ्यास है, " TRY..CATCH" का उपयोग करने की सिफारिश की जाती है, क्योंकि यह SQL Server 2008 के बाद से THROW2012 में शुरू किया गया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.