SQL Server में मुझे शुरुआत / अंत ब्लॉक और गो कीवर्ड का उपयोग करने की आवश्यकता कब है?


103

क्या कोई मुझे बता सकता है कि मुझे एसक्यूएल सर्वर में कब और कहां उपयोग करना है beginऔर endब्लॉक करना है?
इसके अलावा, Goकीवर्ड वास्तव में क्या करता है?

जवाबों:


116

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

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


BEGIN और END C / ++ / #, Java आदि में {और} जैसे हैं।

वे कोड के एक तार्किक ब्लॉक को बाध्य करते हैं। मैं एक संग्रहीत प्रक्रिया के प्रारंभ और अंत में 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

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

2
यह निश्चित रूप से SQL सर्वर 2000 से मेरा अनुभव नहीं है।
मेटाबेली

1
क्या BEGIN और END भी एक नए दायरे को परिभाषित करता है?
Samis

2
हाँ। बाहर घोषित की गई कोई भी चीज अंदर दिखाई दे रही है, लेकिन अंदर बताई गई कोई भी चीज दायरे से बाहर हो जाएगी।
माटबेली

36

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

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


28

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

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

CREATE DATABASE foo;
USE foo;
CREATE TABLE bar;

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

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

13

BEGIN और END को अन्य लोगों द्वारा अच्छी तरह से उत्तर दिया गया है।

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

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

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

select 1
create procedure #Zero as
    return 0

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

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.

SQL सर्वर 2005 पर त्रुटि कम मददगार है:

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

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

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

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

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

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

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

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

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

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

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

3

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

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


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

शाप देने वालों को इससे क्या लेना-देना?
गैरी मैकगिल

3

इस समस्या के साथ कुश्ती करने के बाद आज मेरी राय यह है: BEGIN ... END कोष्ठक कोड ठीक वैसे ही {....} सी भाषाओं में होता है, जैसे यदि ... और छोरों के लिए कोड ब्लॉक

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

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.

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

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

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