2010-01-08 6 views
45

में टी-एसक्यूएल स्टॉप या ABORT कमांड क्या स्क्रिप्ट को प्रसंस्करण रोकने के लिए Microsoft SQL Server T-SQL में कोई आदेश है? मेरे पास एक स्क्रिप्ट है जिसे मैं अभिलेखीय उद्देश्यों के लिए रखना चाहता हूं, लेकिन मैं नहीं चाहता कि कोई इसे चलाए।SQL सर्वर

उत्तर

38

एक वैकल्पिक समाधान GOTO बयान का उपयोग करके अपने स्क्रिप्ट के कार्य निष्पादन के प्रवाह को बदलने के लिए हो सकता है ...

DECLARE @RunScript bit; 
SET @RunScript = 0; 

IF @RunScript != 1 
BEGIN 
RAISERROR ('Raise Error does not stop processing, so we will call GOTO to skip over the script', 1, 1); 
GOTO Skipper -- This will skip over the script and go to Skipper 
END 

PRINT 'This is where your working script can go'; 
PRINT 'This is where your working script can go'; 
PRINT 'This is where your working script can go'; 
PRINT 'This is where your working script can go'; 

Skipper: -- Don't do nuttin! 

चेतावनी! उपर्युक्त नमूना मेरिल एल्ड्रिच से मिले एक उदाहरण से लिया गया था। GOTO कथन को अंधाधुंध रूप से कार्यान्वित करने से पहले, मैं आपको Flow control in T-SQL Scripts पर अपना ट्यूटोरियल पढ़ने की सलाह देता हूं।

+1

धन्यवाद जेड! मुझे उसकी पसंद है: त्रुटि त्रुटि उदाहरण पर। –

+11

@ पेड्रो: यदि आप वर्किंग स्क्रिप्ट अनुभागों के बीच जाओ जोड़ते हैं तो यह असफल हो जाएगा क्योंकि प्रति बैच लागू होता है। जब आप कथन बनाते हैं तो आपको स्क्रिप्ट को बैच में तोड़ने के लिए जाना होगा जो अक्सर बैच में पहला आदेश होना चाहिए। अन्य उत्तर – gbn

+1

जेड पर chadhoc की टिप्पणियां देखें। "फ़्लो कंट्रोल" के लिंक के लिए धन्यवाद, एक आंख खोलने वाला: मैंने आखिरी घंटा हर कॉन्फ़िगरेशन के साथ खेलना बिताया है जिसे मैं सोच सकता हूं और रोने के बारे में सोच रहा हूं कि मुझे कितनी स्क्रिप्ट को सही करने की आवश्यकता हो सकती है। :-( –

16

क्यों नहीं बस स्क्रिप्ट

PRINT 'INACTIVE SCRIPT' 
RETURN 
+13

ध्यान दें कि यदि स्क्रिप्ट में बैच विभाजक (यानी गो स्टेटमेंट्स) शामिल हैं तो यह काम नहीं करेगा - वापसी केवल पहले बैच से वापस आ जाएगी। – chadhoc

+1

ओएच! यह जानना अच्छा है! शायद मुझे शुरुआत में एक/* और अंत में एक */रखना चाहिए! –

+0

गुड प्वाइंट चाडहोक, मैंने सोचा कि वह एक संग्रहीत प्रक्रिया का जिक्र कर रहा था ... धन्यवाद – Sparky

3

की शुरुआत करने के लिए निम्न जोड़ने के एक TSQL स्क्रिप्ट

SELECT 1 
RETURN 
SELECT 2 
SELECT 3 

वापसी निष्पादन समाप्त होता है के रूप में इस चलाने की कोशिश करें। एक प्रश्न या प्रक्रिया से बिना शर्त

RETURN (Transact-SQL)

से बाहर निकलता है। रिटर्न तत्काल है और पूर्ण है और किसी प्रक्रिया, बैच, या कथन ब्लॉक से बाहर निकलने के लिए किसी भी बिंदु पर उपयोग किया जा सकता है। विवरण रिटर्न का पालन नहीं किया जाता है।

+2

फिर, बैच सेपरेटर्स (यानी गो स्टेटमेंट्स) वाली एक स्क्रिप्ट के लिए मदद नहीं करेगा - रिटर्न बैच विशिष्ट है। – chadhoc

14

रिटर्न/जीओ मुद्दे के आसपास काम करने के लिए आप शीर्ष पर RAISERROR ('Oi! Stop!', 20, 1) WITH LOG डाल सकते हैं।

यह RAISERROR on MSDN के अनुसार ग्राहक कनेक्शन को बंद कर देगा।

बहुत बड़ा नकारात्मक पक्ष यह है कि आप गंभीरता उपयोग करने के लिए सिस्टम प्रशासक होना जरूरी है 20.

संपादित करें:

एक साधारण जर्सी Dude की टिप्पणी का मुकाबला करने के प्रदर्शन ...

RAISERROR ('Oi! Stop!', 20, 1) WITH LOG 
SELECT 'Will not run' 
GO 
SELECT 'Will not run' 
GO 
SELECT 'Will not run' 
GO 
+0

फिर से, यह केवल मौजूदा बैच में काम करेगा। अगले बैच (जीओ के बाद) की शुरुआत में निष्पादन फिर से शुरू होता है। –

+0

@ जर्सी दोस्त: आप गलत हैं।ग्राहक कनेक्शन 20 और उससे अधिक गंभीरता के साथ बंद है। तो कोई और बैच नहीं चलेगा। या आप अन्यथा साबित कर सकते हैं? – gbn

+0

@neves: वास्तव में? http://msdn.microsoft.com/en-us/library/aa238452(v=sql.80).aspx – gbn

34

नहीं , कोई नहीं है - आपके पास कुछ विकल्प हैं:

  1. पूरी स्क्रिप्ट को एक बड़े/अगर ब्लॉक में लपेटें जिसे बस सच नहीं माना जाता है (यानी। "अगर 1 = 2 शुरू होता है" - यह केवल तभी काम करेगा यदि स्क्रिप्ट में कोई भी गो बयान शामिल नहीं है (जैसे वे एक नया बैच इंगित करते हैं)

  2. शीर्ष पर वापसी विवरण का उपयोग करें (फिर, बैच द्वारा सीमित विभाजक)

  3. एक कनेक्शन आधारित दृष्टिकोण का उपयोग करें, जो पूरी स्क्रिप्ट के लिए गैर-निष्पादन (पूरे कनेक्शन सुनिश्चित अधिक सटीक होगा) - स्क्रिप्ट के शीर्ष पर एक 'SET PARSEONLY ON' या 'SET NOEXEC ON' की तरह कुछ का उपयोग करें। यह कनेक्शन में सभी बयानों को सुनिश्चित करेगा (या जब तक सेट कथन बंद नहीं किया जाता है) निष्पादित नहीं होगा और इसके बजाय केवल पार्स/संकलित किया जाएगा।

  4. संपूर्ण स्क्रिप्ट को टिप्पणी करने के लिए एक टिप्पणी ब्लॉक का उपयोग करें (यानी।/ * और * /)

संपादित करें: प्रदर्शन है कि 'वापसी' बयान बैच विशिष्ट है - ध्यान दें कि आप को देखने के लिए परिणाम सेट रिटर्न के बाद जारी रहेगा:

select 1 
return 
go 
select 2 
return 
select 3 
go 
select 4 
return 
select 5 
select 6 
go 
2

इसकी बहुत बावजूद स्पष्ट और बलपूर्वक वर्णन, रिटर्न ने मेरे लिए संग्रहीत प्रक्रिया के अंदर काम नहीं किया (आगे निष्पादन छोड़ने के लिए)। मुझे स्थिति तर्क को संशोधित करना पड़ा। दोनों एसक्यूएल 2008, 2008 R2 पर होता है:

if @idSess is null 
    begin 
     begin tran 
      insert tbSess (sSessID) values (@sSessID) 
      select @idSess= scope_identity() 
     commit 
    end 

दोहराया पंक्तियों को खोजने का एक परिणाम के रूप की खोज:

create proc dbo.prSess_Ins 
(
    @sSessID varchar(32) 
, @idSess  int out 
) 
as 
begin 
    set nocount on 

    select @id= idSess 
     from tbSess 
     where sSessID = @sSessID 

    if @idSess > 0 return -- exit sproc here 

    begin tran 
     insert tbSess (sSessID) values (@sSessID) 
     select @idSess= scope_identity() 
    commit 
end 

था में परिवर्तित करने की। प्रिंस ने डीबगिंग की पुष्टि की है कि IF चेक में @idSess के शून्य से अधिक मूल्य था - रिटर्न ने निष्पादन को तोड़ दिया नहीं!

+2

बाद में पाया गया कि यदि मैं एक वापसी मूल्य निर्दिष्ट करता हूं (जैसा कि 'रिटर्न 1' में है), पुनर्नवीनीकरण अपेक्षित कार्य करता है - स्पोक से बाहर निकलना। – Astrogator

7

गंभीरता के साथ RAISERROR 20 ईवेंट इवेंट में त्रुटि के रूप में रिपोर्ट करेगा।

आप एसईटी पेरिसोनली चालू कर सकते हैं; (या NOEXEC)। स्क्रिप्ट के अंत में जाओ सेट पैरासेट बंद करें;

SET PARSEONLY ON; 
-- statement between here will not run 

SELECT 'THIS WILL NOT EXEC'; 

GO 
-- statement below here will run 

SET PARSEONLY OFF; 
2

यहां "ग्लोबल" वेरिएबल का उपयोग करके जीओ-बैचों के साथ काम करने के लिए कुछ हद तक यह तरीका है।

if object_id('tempdb..#vars') is not null 
begin 
    drop table #vars 
end 

create table #vars (continueScript bit) 
set nocount on 
    insert #vars values (1) 
set nocount off 

-- Start of first batch 
if ((select continueScript from #vars)=1) begin 

    print '1' 

    -- Conditionally terminate entire script 
    if (1=1) begin 
    set nocount on 
     update #vars set continueScript=0 
    set nocount off 
    return 
    end 

end 
go 

-- Start of second batch 
if ((select continueScript from #vars)=1) begin 

    print '2' 

end 
go 

और यहां एक ही विचार है जो लेनदेन के साथ उपयोग किया जाता है और प्रत्येक गो-बैच के लिए प्रयास/पकड़ ब्लॉक होता है। आप विभिन्न स्थितियों को बदलने की कोशिश कर सकते हैं और/या यह एक त्रुटि उत्पन्न करते हैं (0 द्वारा विभाजित, टिप्पणी देखें) यह कैसे बर्ताव करता है परीक्षण करने के लिए:

if object_id('tempdb..#vars') is not null 
begin 
    drop table #vars 
end 

create table #vars (continueScript bit) 
set nocount on 
    insert #vars values (1) 
set nocount off 

begin transaction; 
    -- Batch 1 starts here 
    if ((select continueScript from #vars)=1) begin 
    begin try 
     print 'batch 1 starts' 

     if (1=0) begin 
     print 'Script is terminating because of special condition 1.' 
     set nocount on 
      update #vars set continueScript=0 
     set nocount off 
     return 
     end 

     print 'batch 1 in the middle of its progress' 

     if (1=0) begin 
     print 'Script is terminating because of special condition 2.' 
     set nocount on 
      update #vars set continueScript=0 
     set nocount off 
     return 
     end 

     set nocount on 
     -- use 1/0 to generate an exception here 
     select 1/1 as test 
     set nocount off 

    end try 
    begin catch 
     set nocount on 
     select 
      error_number() as errornumber 
      ,error_severity() as errorseverity 
      ,error_state() as errorstate 
      ,error_procedure() as errorprocedure 
      ,error_line() as errorline 
      ,error_message() as errormessage; 
     print 'Script is terminating because of error.' 
     update #vars set continueScript=0 
     set nocount off 
     return 
    end catch; 

    end 
    go 

    -- Batch 2 starts here 
    if ((select continueScript from #vars)=1) begin 

    begin try 
     print 'batch 2 starts' 

     if (1=0) begin 
     print 'Script is terminating because of special condition 1.' 
     set nocount on 
      update #vars set continueScript=0 
     set nocount off 
     return 
     end 

     print 'batch 2 in the middle of its progress' 

     if (1=0) begin 
     print 'Script is terminating because of special condition 2.' 
     set nocount on 
      update #vars set continueScript=0 
     set nocount off 
     return 
     end 

     set nocount on 
     -- use 1/0 to generate an exception here 
     select 1/1 as test 
     set nocount off 

    end try 
    begin catch 
     set nocount on 
     select 
      error_number() as errornumber 
      ,error_severity() as errorseverity 
      ,error_state() as errorstate 
      ,error_procedure() as errorprocedure 
      ,error_line() as errorline 
      ,error_message() as errormessage; 
     print 'Script is terminating because of error.' 
     update #vars set continueScript=0 
     set nocount off 
     return 
    end catch; 

    end 
    go 

if @@trancount > 0 begin 
    if ((select continueScript from #vars)=1) begin 
    commit transaction 
    print 'transaction committed' 
    end else begin 
    rollback transaction; 
    print 'transaction rolled back' 
    end 
end 
1

मैं जानता हूँ कि सवाल पुराना है और कुछ अलग में सही ढंग से उत्तर दिया गया था तरीकों से मेरा कोई जवाब नहीं है जिसे मैंने इसी तरह की स्थितियों में उपयोग किया है। पहले दृष्टिकोण (बहुत बुनियादी):

IF (1=0) 
BEGIN 
    PRINT 'it will not go there' 
    -- your script here 
END 
PRINT 'but it will here' 

दूसरा दृष्टिकोण:

PRINT 'stop here' 
RETURN 
    -- your script here 
PRINT 'it will not go there' 

आप इसे आसानी से अपने आप से परीक्षण कर सकते हैं यह व्यवहार करते अपेक्षा के अनुरूप सुनिश्चित करने के लिए।