2009-07-24 12 views
64

क्या कोई मुझे बता सकता है कि मुझे कब और कहाँ SQL Server में begin और end ब्लॉक का उपयोग करने की आवश्यकता है?
इसके अलावा, Go कीवर्ड वास्तव में क्या करता है?मुझे SQL सर्वर में Begin/End Blocks और Go कीवर्ड का उपयोग करने की आवश्यकता कब है?

उत्तर

84

जाओ एक स्क्रिप्ट के अंत की तरह है।

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


से शुरू और समाप्त जैसे {और} में सी/++/#, जावा, आदि

वे कोड का एक तार्किक ब्लॉक बाध्य कर रहे हैं। मैं संग्रहित प्रक्रिया की शुरुआत और अंत में BEGIN और END का उपयोग करता हूं, लेकिन यह कड़ाई से जरूरी नहीं है। कहाँ यह आवश्यक है छोरों के लिए है, और बयान, आदि, जहां आप और अधिक तो एक कदम की जरूरत है ... यदि

IF EXISTS (SELECT * FROM my_table WHERE id = @id) 
BEGIN 
    INSERT INTO Log SELECT @id, 'deleted' 
    DELETE my_table WHERE id = @id 
END 
+0

क्या आपने कोई एसपी और ईएनडी के साथ एसपी बनाने की कोशिश की है? आईआईआरसी, केवल पहली पंक्ति एसपी में शामिल है, बाकी को बस वहां निष्पादित किया गया है और फिर ... – cjk

+1

यह निश्चित रूप से SQL Server 2000 से मेरा अनुभव नहीं है। – MatBailie

29

आपको एक से अधिक कथन में एक ब्लॉक बनाने के लिए BEGIN ... END की आवश्यकता है। इसलिए, यदि आप एक आईएफ कथन के एक 'पैर' में 2 चीजें करना चाहते हैं, या यदि आप WHILE लूप के शरीर में एक से अधिक चीज़ करना चाहते हैं, तो आपको उन कथनों को BEGIN के साथ ब्रैकेट करना होगा ... समाप्त।

जाओ कीवर्ड SQL का हिस्सा नहीं है। इसका उपयोग क्वेरी विश्लेषक द्वारा स्क्रिप्ट को "बैचों" में विभाजित करने के लिए किया जाता है जिसे स्वतंत्र रूप से निष्पादित किया जाता है।

+1

+1 तेजी से टाइपिंग के लिए :) – MatBailie

+0

+1 संक्षिप्त और सटीक – Frozenskys

19

GO एसक्यूएल सर्वर में एक कीवर्ड नहीं है; यह एक बैच विभाजक है। जाओ बयान के एक बैच समाप्त होता है। यह विशेष रूप से उपयोगी होता है जब आप SQLCMD जैसे कुछ उपयोग कर रहे हैं। कल्पना करें कि आप कमांड लाइन पर एसक्यूएल कथन में प्रवेश कर रहे हैं। जब भी आप कोई कथन समाप्त नहीं करते हैं, तो आप जरूरी नहीं है कि जब भी आप "जाओ" दर्ज करें, तब तक SQL सर्वर कुछ भी नहीं करता है।

इसी तरह, आपके बैच शुरू होने से पहले, आपको अक्सर कुछ ऑब्जेक्ट दिखाई देने की आवश्यकता होती है। उदाहरण के लिए, मान लीजिए कि आप डेटाबेस बना रहे हैं और फिर इसे पूछताछ कर रहे हैं। आप लिख नहीं सकते:

CREATE DATABASE foo; 
USE foo; 
CREATE TABLE bar; 

क्योंकि फ़ैब बैच के लिए मौजूद नहीं है जो CREATE तालिका बनाता है। आपको यह करने की आवश्यकता होगी:

CREATE DATABASE foo; 
GO 
USE foo; 
CREATE TABLE bar; 
2

जाओ एक बैच समाप्त होता है, आपको कोड में इसका उपयोग करने की बहुत ही कम आवश्यकता होगी। ध्यान रखें कि यदि आप इसे संग्रहीत प्रो में उपयोग करते हैं, तो जब आप proc निष्पादित करते हैं तो GO के बाद कोई कोड निष्पादित नहीं किया जाएगा।

प्रक्रिया के लिए कोड की मल्टीपे लाइनों के साथ किसी भी प्रक्रियात्मक प्रकार के बयान के लिए BEGIN और END की आवश्यकता होती है। आपको WHILE loops और कर्सर के लिए उनकी आवश्यकता होगी (यदि आप निश्चित रूप से संभवतः बच जाएंगे) और यदि कथन (अच्छी तरह से तकनीकी रूप से आपको उन्हें एक IF स्टेटमेंट के लिए आवश्यकता नहीं है जिसमें केवल कोड की एक पंक्ति हो, लेकिन यह आसान है यदि आप हमेशा उन्हें IF के बाद डालते हैं तो कोड बनाए रखें)। केस स्टेटमेंट्स भी एक ईएनडी का उपयोग करते हैं लेकिन आपके पास BEGIN नहीं है।

+0

क्या गो के बाद कोई कोड वास्तव में संग्रहीत प्रो के खिलाफ संग्रहीत किया जाएगा? क्या CREATE या ALTER कथन संसाधित नहीं किया जाएगा जैसे कि GO के बाद कोड मौजूद नहीं था? और फिर जाओ के बाद कोड निष्पादित हो जाता है जैसे कि यह स्वयं की स्क्रिप्ट थी? – MatBailie

+0

कर्सर को इसके साथ क्या करना है? –

+0

खैर, यथार्थ रूप से, आपको कर्सर का उपयोग करने के लिए एक लूप की आवश्यकता है ... – MatBailie

8

BEGIN और END का उत्तर दूसरों द्वारा दिया गया है।

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

गो का उपयोग करने के सवाल के जवाब देने के लिए, किसी को पता होना चाहिए कि SQL को बैच में अलग किया जाना चाहिए।

कुछ कथन बैच का पहला विवरण होना चाहिए।

select 1 
create procedure #Zero as 
    return 0 

SQL Server 2000 त्रुटि है:

Msg 178, Level 15, State 1, Procedure #Zero, Line 5 
A RETURN statement with a return value cannot be used in this context. 

तो, GO का उपयोग बयान है कि होने के लिए अलग करने के लिए:

Msg 111, Level 15, State 1, Line 3 
'CREATE PROCEDURE' must be the first statement in a query batch. 
Msg 178, Level 15, State 1, Line 4 
A RETURN statement with a return value cannot be used in this context. 

एसक्यूएल सर्वर 2005 त्रुटि कम उपयोगी है एक स्क्रिप्ट में पहले से बयान से एक बैच की शुरुआत।

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

begin transaction 
go 
... test code here ... 
go 
rollback transaction 

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

इसके अलावा, यदि आप एक स्थापित स्क्रिप्ट कर रहे हैं, और एक फ़ाइल में कई बैच हैं, तो एक बैच में एक त्रुटि स्क्रिप्ट को जारी रखने से नहीं रखेगी, जो एक गड़बड़ी छोड़ सकती है। (इंस्टॉल करने से पहले हमेशा बैकअप लें।)

डेव मार्सेल ने जो बताया है उससे संबंधित, ऐसे मामले हैं जब पार्सिंग विफल हो जाएगी क्योंकि SQL सर्वर बैच में पहले बनाए गए ऑब्जेक्ट्स के डेटा डिक्शनरी में देख रहा है, लेकिन पार्सिंग पहले हो सकता है कोई बयान चलाया जाता है। कभी-कभी यह एक मुद्दा है, कभी-कभी नहीं। मैं एक अच्छे उदाहरण के साथ नहीं आ सकता। लेकिन अगर आपको कभी भी 'एक्स मौजूद नहीं है' त्रुटि मिलती है, तो जब यह स्पष्ट रूप से उस कथन द्वारा बैचों में टूट जाएगा।

और एक अंतिम नोट। लेनदेन बैचों का विस्तार कर सकते हैं। (ऊपर देखें।) चर बैचों का विस्तार नहीं करते हैं।

declare @i int 
set @i = 0 
go 
print @i 

Msg 137, Level 15, State 2, Line 1 
Must declare the scalar variable "@i". 
+1

मुझे यही चाहिए, धन्यवाद: "लेनदेन बैचों का विस्तार कर सकता है। चर बैच नहीं फैलते हैं।" – Gary

1

आज इस समस्या से कुश्ती के बाद मेरी राय यह है: शुरू ... अंत कोष्ठक कोड जैसे {....} सी भाषाओं, उदा करता है कोड ब्लॉक अगर ... और लूप

जीओ (होना चाहिए) जब पिछले कथन द्वारा परिभाषित ऑब्जेक्ट पर निर्भर बयानों का पालन किया जाता है। उपयोग डेटाबेस ऊपर एक अच्छा उदाहरण है, लेकिन निम्नलिखित भी आप काट लेगी:

alter table foo add bar varchar(8); 
-- if you don't put GO here then the following line will error as it doesn't know what bar is. 
update foo set bar = 'bacon'; 
-- need a GO here to tell the interpreter to execute this statement, otherwise the Parser will lump it together with all successive statements. 

मुझे ऐसा लगता है समस्या यह है: एसक्यूएल सर्वर एसक्यूएल पार्सर, ओरेकल के विपरीत, वह असमर्थ है एहसास है कि आप ' पहली पंक्ति पर एक नया प्रतीक परिभाषित करना और निम्नलिखित पंक्तियों में संदर्भ देना ठीक है। यह तब तक प्रतीक नहीं देखता जब तक कि यह एक गो टोकन से मुकाबला नहीं करता है जो पिछले गो के बाद से पिछले एसक्यूएल को निष्पादित करने के लिए कहता है, जिस बिंदु पर प्रतीक डेटाबेस पर लागू होता है और पार्सर को दिखाई देता है।

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

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

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