"बैच" क्या है, और GO का उपयोग क्यों किया जाता है?


134

मैंने MSDN, आदि पर पढ़ा और पढ़ा है, इसलिए यह एक बैच के अंत का संकेत देता है।

क्या एक बैच को परिभाषित करता है? मैं यह नहीं देखता कि जब मुझे एक ही समय में सभी स्क्रिप्ट चलाने के लिए स्क्रिप्ट्स के एक समूह में चिपकाने की आवश्यकता होती है, तो मुझे क्यों जाना चाहिए।

मैंने कभी जीओ को नहीं समझा। क्या कोई इसे बेहतर तरीके से समझा सकता है और जब मुझे इसका उपयोग करने की आवश्यकता होती है (कितने या किस प्रकार के लेनदेन के बाद)?

उदाहरण के लिए मुझे यहां प्रत्येक अपडेट के बाद GO की आवश्यकता क्यों होगी:

 UPDATE [Country]
   SET [CountryCode] = 'IL'
 WHERE code = 'IL'

 GO

 UPDATE [Country]
   SET [CountryCode] = 'PT'
 WHERE code = 'PT'


FWIW, ऐसा लगता है जैसे कि एक goभी रीसेट करता है / declare @fooचर घोषणाओं को साफ करता है - मुझे आपको @foo त्रुटियों को घोषित करने की आवश्यकता थी , जब तक कि मैंने टिप्पणी नहीं की go
JL Peyret

जवाबों:


107

GOहै ठीक से एक TSQL आदेश।

इसके बजाय यह विशिष्ट क्लाइंट प्रोग्राम के लिए एक कमांड है जो एक SQL सर्वर से कनेक्ट होता है (Sybase या Microsoft का - जो ओरेकल क्या करता है इसके बारे में निश्चित नहीं है), क्लाइंट प्रोग्राम को संकेत देता है कि "गो" की आवश्यकता होने तक इनपुट का आदेश सेट किया गया था। निष्पादित होने के लिए सर्वर को भेजा जाए।

आपको इसकी आवश्यकता क्यों / कब पड़ती है?

  • MS SQL सर्वर में GO का "काउंट" पैरामीटर होता है - इसलिए आप इसे "रिपीट एन टाइम्स" शॉर्टकट के रूप में उपयोग कर सकते हैं।

  • अत्यंत बड़े अद्यतन SQL सर्वर के लॉग को भर सकते हैं। इससे बचने के लिए, उन्हें छोटे बैचों के माध्यम से अलग करने की आवश्यकता हो सकती है go

    आपके उदाहरण में, यदि देश कोड के एक सेट के लिए अद्यतन करने की मात्रा इतनी है कि यह लॉग स्पेस से बाहर चलेगा, तो समाधान प्रत्येक देश कोड को एक अलग लेनदेन में अलग करना है - जिसे क्लाइंट के साथ अलग करके किया जा सकता है go

  • कुछ SQL कथनों को काम करने के लिए निम्नलिखित में से GO से अलग किया जाना चाहिए।

    उदाहरण के लिए, आप एक तालिका को नहीं छोड़ सकते हैं और एकल-लेन-देन में समान नाम वाली तालिका को फिर से बना सकते हैं, कम से कम साइबेस (प्रक्रिया / ट्रिगर बनाने के लिए डिट्टो) में:

> drop table tempdb.guest.x1          
> create table tempdb.guest.x1 (a int)
> go
  Msg 2714, Level 16, State 1
  Server 'SYBDEV', Line 2
  There is already an object named 'x1' in the database.   
  
> drop table tempdb.guest.x1          
> go
> create table tempdb.guest.x1 (a int)
> go
>

4
GO स्टेटमेंट लेन-देन नहीं बनाता है। यदि आप एक BEGIN ट्रांजेक्शन स्टेटमेंट में कई GO स्टेटमेंट्स को शामिल करते हैं और अंत में आप एक रोलबैक करेंगे, तो यह सभी GO के रोलबैक कर देगा। और अगर बीच में एक GO में आपको कुछ त्रुटि मिलेगी, और अंत में आप COMMIT करेंगे, तो बिना त्रुटि के सभी GO को सराहा जाएगा। एक तरह से मुश्किल है।
TZ

7
GO"आपके लिए कोई लेनदेन नहीं बनाता है।" यदि आप स्पष्ट लेन-देन में नहीं चल रहे हैं, तो प्रत्येक स्टेटमेंट वैसे भी अपना लेनदेन बनाएगा। यह पूरी तरह से ऑर्थोगोनल है। यदि आप किसी बड़े अपडेट को छोटे चरणों में विभाजित करना चाहते हैं, तो आप इसे सामान्य WHILE @@ROWCOUNT > 0पैटर्न की तरह एकल बैच में भी कर सकते हैं ।
मार्टिन स्मिथ

3
यदि आप एक स्पष्ट लेनदेन में नहीं चल रहे हैं, तो वैसे भीUPDATE T1 SET X =2;UPDATE T1 SET X =2; दो अलग-अलग लेनदेन के रूप में चलेंगे । इसके अलावा बिल्कुल कोई फर्क नहीं पड़ता। और इसी तरह यदि आप एक स्पष्ट लेनदेन में चल रहे हैं तो यह बैचों को फैलाता है और फिर से कोई फर्क नहीं पड़ता है। GOGO
मार्टिन स्मिथ

4
बस इसे पढ़ने वाले किसी भी व्यक्ति के लिए स्पष्टीकरण के रूप में ... GOलेनदेन के साथ बिल्कुल भी कोई लेना-देना नहीं है, और यह उत्तर लेनदेन के बारे में दूसरे बिंदु और लॉग फ़ाइल के आकार को गलत बनाता है। GOकोई प्रभाव नहीं पड़ेगा। पहले और तीसरे उत्तर सही हैं। इसके अलावा, ऐसे समय होते हैं जिनमें आपको अलग-अलग बैचों में अलग-अलग स्टेटमेंट देने होते हैं, उदाहरण के लिए आप किसी कॉलम को टेबल पर नहीं जोड़ सकते हैं और फिर बाद में उसी बैच में उस कॉलम का उपयोग कर सकते हैं। (जारी)
रॉबर्ट मैककी

4
इसके अतिरिक्त, क्योंकि कुछ त्रुटियां एक बैच को निरस्त कर देंगी (कुछ त्रुटियां केवल एक कथन को निरस्त करती हैं), यह त्रुटि का पता लगाने और वसूली में भी भूमिका निभाता है। और कुछ बयानों ( CREATE VIEWआदि) को अपने स्वयं के बैच में होना चाहिए।
रॉबर्ट मैककी

26

GO एक बयान नहीं है, यह एक बैच विभाजक है।

GOक्लाइंट द्वारा अलग-अलग ब्लॉक को प्रोसेसिंग के लिए सर्वर को भेजा जाता है और क्लाइंट अपने रिजल्ट का इंतजार करता है।

उदाहरण के लिए, यदि आप लिखते हैं

DELETE FROM a
DELETE FROM b
DELETE FROM c

, यह एक सिंगल- 3क्वेरी क्वेरी के रूप में सर्वर को भेजा जाएगा ।

अगर आप लिखेंगे

DELETE FROM a
GO
DELETE FROM b
GO
DELETE FROM c

, यह सर्वर को 3एक-लाइन प्रश्नों के रूप में भेजा जाएगा ।

GOखुद सर्वर पर नहीं जाता है (कोई सज़ा नहीं)। यह एक शुद्ध क्लाइंट-साइड आरक्षित शब्द है और केवल द्वारा पहचाना जाता है SSMSऔर osql

यदि आप कनेक्शन पर भेजने के लिए एक कस्टम क्वेरी टूल का उपयोग करेंगे, तो सर्वर इसे पहचान भी नहीं पाएगा और एक त्रुटि जारी करेगा।


4
आखिर आपको बैचेन क्यों होना है ??
पॉजिटिव

3
तो तब GO का अर्थ है कि इसे भेजें और फिर अगले बैच को तब तक न चलाएं जब तक कि क्लाइंट को "ओके नहीं मिलता है, वह बैच हो चुका है और सफल रहा है" मूल रूप से जीओ ऐसा करता है ताकि अगला बैच सफलतापूर्वक चलाया जा सके और ग्राहक को पता चले सुनिश्चित करें कि सर्वर-साइड होने से पहले बैच।
पॉजिटिव

3
@coffeeaddict: मूल रूप से, हाँ। इसके अलावा, कुछ बयानों को अपने बैचों (जैसे CREATE SCHEMA) में पहले होना आवश्यक है ; अन्य को अपने बैचों (जैसे ) में केवल कथन होने की आवश्यकता हैSET SHOWPLAN_XML ON
क्वासोई

19

कई कमांड को अपने बैच में होना चाहिए, जैसे CREATE PROCEDURE

या, यदि आप किसी तालिका में एक स्तंभ जोड़ते हैं, तो यह अपने स्वयं के बैच में होना चाहिए। यदि आप एक ही बैच में नए कॉलम को चुनने का प्रयास करते हैं तो यह विफल हो जाता है क्योंकि पार्स / संकलन समय पर कॉलम मौजूद नहीं होता है।

एक स्क्रिप्ट से काम करने के लिए SQL टूल द्वारा GO का उपयोग किया जाता है: यह SQL कीवर्ड नहीं है और इंजन द्वारा मान्यता प्राप्त नहीं है।

ये बैचों के उपयोग के लिए दिन के 2 ठोस उदाहरण हैं।

संपादित करें: आपके उदाहरण में, आपको GO की आवश्यकता नहीं है ...

2 संपादित करें, उदाहरण। आप एक बैच में ड्रॉप, क्रिएट और अनुमति नहीं दे सकते ... कम से कम, संग्रहीत प्रक्रिया का अंत कहां है?

IF OBJECT_ID ('dbo.uspDoStuff') IS NOT NULL
    DROP PROCEDURE dbo.uspDoStuff
GO
CREATE PROCEDURE dbo.uspDoStuff
AS
SELECT Something From ATable
GO
GRANT EXECUTE ON dbo.uspDoStuff TO RoleSomeOne
GO

4

कभी-कभी एक ही कमांड या कमांड के सेट को बार-बार निष्पादित करने की आवश्यकता होती है। यह परीक्षण डेटा सम्मिलित या अद्यतन करने के लिए हो सकता है या प्रदर्शन परीक्षण के लिए अपने सर्वर पर लोड डालने के लिए हो सकता है। इसे करने के लिए सबसे आसान तरीका जो भी हो, एक लूप सेटअप करना और अपने कोड को निष्पादित करना है, लेकिन SQL 2005 में ऐसा करने का एक और आसान तरीका है।

मान लें कि आप एक परीक्षण तालिका बनाना चाहते हैं और इसे 1000 रिकॉर्ड के साथ लोड करना चाहते हैं। आप निम्न आदेश जारी कर सकते हैं और यह 1000 बार एक ही कमांड चलाएगा:

CREATE TABLE dbo.TEST (ID INT IDENTITY (1,1), ROWID uniqueidentifier)
GO
INSERT INTO dbo.TEST (ROWID) VALUES (NEWID()) 
GO 1000

स्रोत: http://www.mssqltips.com/tip.asp?tip=1216

इसके अलावा, यह एक SQL ब्लॉक के "अंत" को चिह्नित करता है (जैसे एक संग्रहीत प्रक्रिया में) ... मतलब आप फिर से "साफ" स्थिति पर हैं ... eG: कोड रीसेट होने से पहले कथन में उपयोग किए गए पैरामीटर ( अब परिभाषित नहीं)


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

जिस तरह से मैं इस बारे में सोचता हूं, वह यह है कि अगर मेरे पास आपके उदाहरण में GOs नहीं है, तो तालिका पहले बनाई गई है, यह अब वहां है, इसलिए सम्मिलित करना चाहिए। मुझे यह नहीं मिलता कि यदि मैंने तालिका बनाई है तो GO क्या है ... यह अगले डालने के लिए उपलब्ध है ना?!?!?!
पॉजिटिव

2
@coffeeaddict: नहीं। "बैच" को एक बार में देखा और संकलित किया गया है। संकलन समय पर, dbo.TEST मौजूद नहीं है। आप किसी ऑब्जेक्ट को इंस्टेंट नहीं कर रहे हैं और SQL लाइन प्रक्रियात्मक कोड
gbn

3

जैसा कि सभी ने पहले ही कहा था, "गो" टी-एसक्यूएल का हिस्सा नहीं है। "GO" SSMS में एक बैच सेपरेटर है , जो क्लाइंट एप्लिकेशन को डेटाबेस में प्रश्न सबमिट करने के लिए उपयोग किया जाता है। इसका मतलब यह है कि घोषित चर और तालिका चर "गो" से पहले कोड से बने रहेंगे और इसके बाद कोड नहीं बनाएंगे।

वास्तव में, GO केवल SSMS द्वारा उपयोग किया जाने वाला डिफ़ॉल्ट शब्द है। यदि आप चाहें तो इसे विकल्पों में बदला जा सकता है। थोड़ी सी मस्ती के लिए, "GO" के बजाय बैच सेपरेटर के रूप में "SELECT" का उपयोग करने के लिए किसी और के सिस्टम पर विकल्प बदलें। माफ़ करना मेरी क्रूर चकली।


1
यहां वास्तव में एक गंभीर बिंदु बनाया जाना है: आपको जीओ का इलाज करना चाहिए जैसे कि यह एक कीवर्ड था, हालांकि यह नहीं है। आपको भी इसे कभी नहीं बदलना चाहिए। विशेष पहचानकर्ताओं के पुन: उपयोग के कारण होने वाले कीड़े डीबग करने के लिए बहुत कठिन हो सकते हैं।
जोर्जेन फोग

@ दीक्सी फ़्लैटलाइन: क्या आप घोषित चर के बारे में सुनिश्चित हैं जो स्थायी नहीं हैं? MSSQL 2016 में मुझे एक "चर पहले से ही घोषित" त्रुटि मिलती है, जब चल रहा है: $ $ int घोषित करें; सेट $ परीक्षण = 5; $ परीक्षण का चयन करें; घोषित $ परीक्षण int; - एसई टिप्पणियों में $ को <पर> से बदलें, एकाधिक <पर> का उपयोग नहीं कर सकते।
राउटर

0

इसका उपयोग तार्किक ब्लॉकों को विभाजित करने के लिए किया जाता है। आपके कोड की व्याख्या sql कमांड लाइन में की जाती है और यह कोड के अगले ब्लॉक को इंगित करता है।

लेकिन इसका उपयोग विशिष्ट संख्या के साथ पुनरावर्ती कथन के रूप में किया जा सकता है।

प्रयत्न:

exec sp_who2  
go 2

कुछ कथन को GO द्वारा सीमांकित किया जाना है:

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