हर T-SQL स्टेटमेंट के बाद जाएं


34

हर SQL स्टेटमेंट के बाद GO स्टेटमेंट का उपयोग करने के पीछे क्या कारण है? मैं समझता हूं कि GO, बैच के अंत का संकेत देता है और / या बयानों की प्रतिष्ठा की अनुमति देता है लेकिन हर बयान के बाद इसका क्या फायदा है।

मैं Microsoft के बहुत सारे दस्तावेज़ों के बारे में जानने के लिए उत्सुक हूँ, आदि हर कथन के बाद इसका उपयोग शुरू कर दिया है या शायद मैंने अभी नोटिस करना शुरू किया है।

इसके अलावा सबसे अच्छा अभ्यास क्या माना जाता है?

जवाबों:


51

इसका उपयोग कब और क्यों करना है, इसका उत्तर देने से पहले, यह समझने में सबसे पहले सर्वोपरि है कि GOयह क्या है, और यह क्या नहीं है।

कीवर्ड GOका उपयोग SQL सर्वर प्रबंधन स्टूडियो और SQLCMD द्वारा एक चीज और केवल एक चीज को इंगित करने के लिए किया जाता है: बयानों के एक बैच का अंत। वास्तव में, आप "गो" के अलावा कुछ और चीज़ों को समाप्त करने के लिए जो आप उपयोग करते हैं उसे भी बदल सकते हैं :

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

कि ऊपर स्क्रीनशॉट SSMS के भीतर एक विकल्प है जो विन्यास योग्य है।

लेकिन एक बैच क्या है ?? यह BOL संदर्भ इसे सबसे अच्छा कहता है:

एक बैच निष्पादन के लिए एक अनुप्रयोग से SQL सर्वर पर एक ही समय में भेजे गए एक या अधिक Transact-SQL स्टेटमेंट का एक समूह है

इतना ही आसान। यह सिर्फ एक कस्टम तरीका है एक आवेदन (हाँ ... एक आवेदन) SQL सर्वर को बयान भेजता है। आइए, इसका एक एप्लिकेशन-देखने वाला उदाहरण देखें। मैं SQL सर्वर पर स्टेटमेंट और बैच भेजने के लिए एक एप्लिकेशन क्या करेगा, इसकी नकल करने के लिए PowerShell का उपयोग करूंगा:

$ConnectionString = "data source = SomeSQLInstance; initial catalog = AdventureWorks2012; trusted_connection = true; application name = BatchTesting;"

try {
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString)
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlCmd.Connection = $SqlConnection

    # first batch of statements
    #
    $SqlCmd.CommandText = "
        select * from humanresources.department where departmentid = 1;
        select * from humanresources.department where departmentid = 2;
        select * from humanresources.department where departmentid = 3;
        select * from humanresources.department where departmentid = 4;"

    # execute the first batch
    #
    $SqlConnection.Open()
    $SqlCmd.ExecuteNonQuery()
    $SqlConnection.Close()

    # second batch of statements
    #
    $SqlCmd.CommandText = "
        select * from humanresources.department where departmentid = 5;
        select * from humanresources.department where departmentid = 6;
        select * from humanresources.department where departmentid = 7;
        select * from humanresources.department where departmentid = 8;"

    # execute the second batch
    #
    $SqlConnection.Open()
    $SqlCmd.ExecuteNonQuery()
    $SqlConnection.Close()
}
catch {
    $SqlCmd.Dispose()
    $SqlConnection.Dispose()
    Write-Error $_.Exception
}

टिप्पणियाँ इसे दूर देती हैं, लेकिन आप ऊपर देख सकते हैं कि हम प्रोग्रामेटिक रूप से SQL सर्वर पर दो बैच भेज रहे हैं । चलो सत्यापित करते हैं, हालांकि। यहाँ मेरी पसंद विस्तारित घटनाओं का उपयोग करना है:

create event session BatchTesting
on server
add event sqlserver.sql_batch_starting
(
    set
        collect_batch_text = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
),
add event sqlserver.sql_batch_completed
(
    set
        collect_batch_text = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
),
add event sqlserver.sql_statement_starting
(
    set
        collect_statement = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
),
add event sqlserver.sql_statement_completed
(
    set
        collect_statement = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
)
add target package0.event_file
(
    set
        filename = N'<MyXelLocation>\BatchTesting.xel'
);
go

alter event session BatchTesting
on server
state = start;
go

यह सब XEvents सत्र कर रहा है और उन कथनों और बैचों को कैप्चर कर रहा है जो एक एप्लिकेशन के नाम से शुरू और पूर्ण होते हैं "BatchTesting"(यदि आप मेरे पॉवरशेल कोड उदाहरण में मेरे कनेक्शन स्ट्रिंग को देखते हैं, तो यह "एप्लिकेशन का उपयोग करके घटनाओं के किसी विशेष प्रवर्तक को देखने का एक त्वरित तरीका है" नाम "कनेक्शन स्ट्रिंग पैरामीटर और उस का फ़िल्टरिंग)।

मैं उन बैचों और बयानों को भेजने के लिए PowerShell कोड निष्पादित करने के बाद, मैं निम्नलिखित परिणाम देखता हूं:

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

जैसा कि आप स्क्रीनशॉट से देख सकते हैं, यह स्पष्ट है कि स्टेटमेंट को दो अलग-अलग बैचों में कैसे विभाजित किया गया है, यह भी स्पष्ट है कि जिस तरह से हम बैचों को कॉल करते थे। और यदि हम batch_textपहली घटना को sql_batch_startingदेखते हैं, तो हम उस बैच में शामिल सभी कथनों को देख सकते हैं:

    select * from humanresources.department where departmentid = 1;
    select * from humanresources.department where departmentid = 2;
    select * from humanresources.department where departmentid = 3;
    select * from humanresources.department where departmentid = 4;

एक बैच क्या है, इस विवरण के साथ , अब आपके प्रश्न का उत्तर आता है कि कब बैचों को समाप्त करना है। बैचों के नियम इस BOL संदर्भों पर बैचों के बारे में पाए जाते हैं :

क्रिएट डिफाल्ट, क्रिएट फंक्शन, क्रिएट प्रोसीजर, क्रिएट रूल, क्रिएट स्कीमा, क्रिएट ट्राइगर, और क्रिएट व्यू स्टेटमेंट को एक बैच में अन्य स्टेटमेंट के साथ नहीं जोड़ा जा सकता है। क्रिएट स्टेटमेंट को बैच शुरू करना चाहिए। अन्य सभी कथन जो उस बैच में अनुसरण करते हैं, पहले क्रिएट स्टेटमेंट की परिभाषा के हिस्से के रूप में व्याख्या किए जाएंगे।

एक तालिका नहीं बदली जा सकती और फिर उसी बैच में संदर्भित नए कॉलम।

यदि एक EXECUTE स्टेटमेंट एक बैच में पहला स्टेटमेंट है, तो EXECUTE कीवर्ड की आवश्यकता नहीं है। यदि EXECUTE कथन बैच में पहला कथन नहीं है, तो EXECUTE कीवर्ड की आवश्यकता है।

इसी तरह, कुछ रनटाइम त्रुटियां (संकलन त्रुटियां बैच के निष्पादन की शुरुआत नहीं होने देंगी) जो कि बैच के दौरान होती हैं, विभिन्न व्यवहारों का कारण बन सकती हैं: बैच को पूरी तरह से निरस्त करना, या बैच को जारी रखना और केवल अपमानजनक बयान (उपरोक्त) को निरस्त करना लिंक दो बहुत अच्छे उदाहरण देता है: एक अंकगणितीय अतिप्रवाह त्रुटि, उदाहरण के लिए, बैच के निष्पादन को रोक देगा, जबकि एक बाधा उल्लंघन त्रुटि केवल वर्तमान बयान को पूरा करने से रोक देगी लेकिन बैच निष्पादित करना जारी रखेगा)।

हमारे पेशे में कई चीजों की तरह, हालांकि, व्यक्तिगत प्राथमिकता टी-एसक्यूएल कोड समाप्त बैचों के एक व्यक्ति और लेखक के रूप में आपके पीछे बहुत बड़ी प्रेरणा होगी। कुछ लोग केवल स्पष्ट रूप से बैचों को परिभाषित करते हैं जब उन्हें पूरी तरह से (उन आवश्यकताओं के लिए ऊपर देखें), और अन्य लोग बैचों को प्रोग्रामिक रूप से 100% समय तक समाप्त कर देते हैं, तब भी जब वे एसएसएमएस में एक क्वेरी विंडो में केवल एक बयान को निष्पादित कर रहे हैं। ज्यादातर लोग आमतौर पर उन दो सीमाओं के बीच में कहीं गिर जाते हैं। इसके लायक होने के लिए, स्टेटमेंट टर्मिनेटर्स के पास बहुत कम लागू आवश्यकताओं के साथ एक ही है। इस सब का एक बड़ा हिस्सा कोड शैली है , जहां इसे लागू नहीं किया गया है (SSMS और SQLCMD में)।


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

1
@SteveChambers मेरी भावना बिल्कुल। उत्तर कहता है "यह उतना ही सरल है" (ए बैच निष्पादन के लिए एक एप्लिकेशन से SQL सर्वर पर एक ही समय में भेजे गए एक या एक से अधिक Transact-SQL स्टेटमेंट का समूह है।) लेकिन यह नहीं है। ऐसे बयानों के संयोजन हैं जिन्हें मैं कोशिश कर सकता हूं और एक बैच में भेज सकता हूं जो विफल होते हैं। अंततः मुझे लगता है कि आपको यह समझने की आवश्यकता है कि बैच भेजना क्यों और कैसे अलग-अलग बयानों का एक सेट भेजने से अलग है - इसलिए मैंने आखिरकार इस पर अपना जवाब देने में अपना योगदान दिया: stackoverflow.com/a/56370223/3714936 - जो आपकी टिप्पणी के लिए भी बोलता है ।
youcantryreachingme
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.