“Parti” nedir ve GO neden kullanılır?


134

MSDN vb. Üzerinde okudum ve okudum. Tamam, bu yüzden bir partinin sonunu gösteriyor.

Bir grubu ne tanımlar? Aynı anda çalıştırmak için bir sürü senaryoyu yapıştırırken neden gitmem gerektiğini anlamıyorum.

GO'yu hiç anlamadım. Herkes bunu daha iyi açıklayabilir ve ne zaman kullanmam gerekir (kaç veya ne tür işlemlerden sonra)?

Örneğin, burada her güncellemeden sonra neden GO'ya ihtiyacım var:

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

 GO

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


FWIW, sanki bir gode sıfırlar / declare @foodeğişken bildirimleri temizler gibi görünüyor - Ben yorum kadar ben @foo hataları bildirmek için başlamıştıgo .
JL Peyret

Yanıtlar:


107

GOolduğu değil düzgün TSQL komut.

Bunun yerine , bir SQL sunucusuna (Sybase veya Microsoft'un - Oracle'ın ne yaptığından emin değilim) bağlanan belirli istemci programına bir komut olup, istemci programına "git" gereksinimine kadar girilen komut kümesinin sinyalini verir. çalıştırılacak sunucuya gönderilecek.

Neden / ne zaman ihtiyacınız var?

  • MS SQL sunucusunda GO'nun bir "sayım" parametresi vardır - böylece bunu "N kez tekrarla" kısayolu olarak kullanabilirsiniz.

  • Son derece büyük güncellemeler SQL sunucusunun günlüğünü doldurabilir. Bundan kaçınmak için, daha küçük partiler halinde ayrılmaları gerekebilir go.

    Örneğinizde, bir dizi ülke kodu güncellemesinin günlük alanı bitecek bir hacme sahip olması durumunda, çözüm her ülke kodunu ayrı bir işleme ayırmaktır - bu da istemcide ayrılarak yapılabilir go.

  • Çalışmak için bazı SQL ifadeleri GO ile aşağıdakilerden ayrılmalıdır ZORUNLU.

    Örneğin, bir tabloyu bırakamaz ve aynı adlı tabloyu tek bir işlemde, en azından Sybase'de (yordamlar / tetikleyiciler oluşturmak için ditto) yeniden oluşturamazsınız:

> 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 ifadesi işlem oluşturmaz. Bir BEGIN TRANSACTION deyimine birden çok GO deyimi eklerseniz ve sonunda bir ROLLBACK yaparsanız, tüm GO'ları geri alır. Ve ortada bir GO'da bir hata alırsanız ve sonunda COMMIT yaparsanız, hatasız tüm GO işlenir. Biraz zor.
TZ

7
GO"sizin için bir işlem oluşturmaz". Açık bir işlemde çalışmıyorsanız, her ifade yine de kendi işlemini oluşturacaktır. Tamamen diktir. Daha büyük bir güncellemeyi daha küçük adımlara bölmek istiyorsanız, yine de ortak WHILE @@ROWCOUNT > 0düzende olduğu gibi tek bir toplu işte yapabilirsiniz .
Martin Smith

3
Açık bir işlemde çalışmıyorsanız, yine deUPDATE T1 SET X =2;UPDATE T1 SET X =2; iki ayrı işlem olarak çalışacaktır . Eklenmesi kesinlikle yapar fark. Ve benzer şekilde eğer vardır tekrar toplu yayılan ve açık bir işlemde çalışan hiç fark etmez. GOGO
Martin Smith

4
Bunu daha sonra okuyan herkes için açıklama gibi ... GOkesinlikle işlemlerle hiçbir ilgisi yoktur ve yanıtları işlemler ve bir günlük dosyasının boyutu hakkında ikinci nokta yapar. GOhiçbir etkisi olmayacaktır. Birinci ve üçüncü cevaplar doğrudur. Ayrıca, ifadeleri ayrı gruplar halinde ayırmanız gereken zamanlar vardır, örneğin bir tabloya sütun ekleyemez ve bu sütunu daha sonra aynı toplu işte kullanamazsınız. (devam ediyor)
Robert McKee

4
Ayrıca, bazı hatalar toplu işlemi iptal edeceğinden (bazı hatalar yalnızca bir bildirimi iptal eder), hata algılama ve kurtarma işlemlerinde de rol oynar. Ve belirli ifadelerin ( CREATE VIEWvb.) Kendi gruplarında olması gerekir.
Robert McKee

26

GO bir ifade değil, bir toplu ayırıcıdır.

Ayrılmış bloklar GO, istemci tarafından işlenmek üzere sunucuya gönderilir ve istemci sonuçlarını bekler.

Örneğin, yazarsanız

DELETE FROM a
DELETE FROM b
DELETE FROM c

, bu sunucuya tek 3satırlı bir sorgu olarak gönderilir .

Yazarsan

DELETE FROM a
GO
DELETE FROM b
GO
DELETE FROM c

, bu sunucuya 3tek satırlı sorgular olarak gönderilir .

GOkendisi sunucuya gitmez (hiçbir cinas amaçlanan). Bu tamamen istemci tarafında ayrılmış bir kelimedir ve sadece SSMSve tarafından tanınır osql.

Bağlantı üzerinden göndermek için özel bir sorgu aracı kullanacaksanız, sunucu aracı tanımayacak ve hata vermeyecektir.


4
Neden hiç parti yapmak zorundasın?
PositiveGuy

3
Böylece GO gönderir ve daha sonra istemci "Tamam, bu toplu işlem yapılır ve başarılı olur" ifadesini alana kadar bir sonraki toplu işi çalıştırmaz, temelde GO'nun yaptığı şeydir, böylece bir sonraki toplu iş başarıyla çalıştırılabilir ve istemci sunucu tarafı tamamlanmadan önce toplu iş emin olun.
PositiveGuy

3
@coffeeaddict: temel olarak evet. Ek olarak, bazı ifadelerin gruplarında ilk olması gerekir (örneğin CREATE SCHEMA); diğer partilerinde sadece ifadeler (gerektirir gibi SET SHOWPLAN_XML ON) gerektirir
Quassnoi

19

Birçok komutun kendi partisinde olması gerekir, örneğin CREATE PROCEDURE

Veya, bir tabloya sütun eklerseniz, o zaman kendi toplu işinde olmalıdır. Aynı toplu işteki yeni sütunu SEÇMEK çalışırsanız, ayrıştırma / derleme zamanında sütun bulunmadığından başarısız olur.

GO, SQL araçları tarafından bunu bir komut dosyasından çözmek için kullanılır: bir SQL anahtar sözcüğü değildir ve motor tarafından tanınmaz.

Bunlar partilerin günlük kullanımının 2 somut örneğidir.

Düzenleme: Örneğinizde GO'ya ihtiyacınız yok ...

Düzenleme 2, örnek. Bir partide bırakamaz, oluşturamaz ve izin veremezsiniz ... en azından, saklı yordamın sonu nerede?

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

Bazen aynı komutu veya komut kümesini tekrar tekrar yürütmek gerekebilir. Bu, test verilerini eklemek veya güncellemek veya performans testi için sunucunuza bir yük koymak olabilir. Bunu yapmanın en kolay yolu ne olursa olsun, bir while döngüsü kurmak ve kodunuzu yürütmektir, ancak SQL 2005'te bunu yapmanın daha kolay bir yolu vardır.

Bir test tablosu oluşturmak ve 1000 kayıtla yüklemek istediğinizi varsayalım. Aşağıdaki komutu verebilirsiniz ve aynı komutu 1000 kez çalıştıracaktır:

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

kaynak: http://www.mssqltips.com/tip.asp?tip=1216

Bunun dışında bir SQL bloğunun "sonunu" işaretler (örneğin saklı yordamda) ... Yani tekrar "temiz" durumdasınız ... eG: Kod sıfırlanmadan önce ifadede kullanılan parametreler ( artık tanımlanmadı)


Tamam, neden GO'ya ihtiyacınız var? Ekleme deyimi çalıştırılmadan önce tablonun oluşturulduğunu biliyor musunuz? Hala anlamıyorum.
PositiveGuy

Bunun hakkında düşündüğüm yol, örneğinizde GO'ları yoksa, Tablo ilk önce oluşturulur, şimdi oradadır, bu nedenle ekin çalışması gerekir. Tabloyu oluşturduysam GO'nun ne için olduğunu anlamıyorum ... bir sonraki ek için kullanılabilir değil mi?!?!?!
PositiveGuy

2
@coffeeaddict: hayır. "parti" bir seferde ayrıştırılır ve derlenir. Derleme zamanında, dbo.TEST yoktur. Bir nesneyi
başlatmıyorsunuz

3

Herkesin söylediği gibi, "GO" T-SQL'in bir parçası değildir. "GO", veritabanına sorgu göndermek için kullanılan bir istemci uygulaması olan SSMS'de bir toplu ayırıcıdır . Bu, bildirilen değişkenlerin ve tablo değişkenlerinin "GO" dan önceki koddan, onu izleyen koda kadar kalıcı olmayacağı anlamına gelir.

Aslında, GO sadece SSMS tarafından kullanılan varsayılan kelimedir. İsterseniz bu seçeneklerde değiştirilebilir. Biraz eğlenmek için, başkasının sistemindeki seçeneği, "GO" yerine toplu ayırıcı olarak kullanmak için "SELECT" seçeneğini kullanın. Acımasız kıkırdamımı affet.


1
Burada gerçekten ciddi bir noktaya değinilecek: GO'ya, anahtar kelime olmasa da bir anahtar kelime gibi davranmalısınız. Asla değiştirmemelisin. Özel tanımlayıcıların yeniden kullanılmasından kaynaklanan hataların ayıklanması çok zor olabilir.
Jørgen Fogh

@ Dixie Flatline: Beyan edilen değişkenlerin devam etmediğinden emin misiniz? MSSQL 2016'da çalışırken bir "değişken zaten bildirildi" hatası alıyorum: declare $ test int; $ test = 5 olarak ayarlayın; $ test go seçin; $ test int beyan eder; - $ yerine <at> yazın, SE yorumlarında birden fazla <at> kullanılamaz.
Wouter

0

Mantıksal blokları ayırmak için kullanılır. Kodunuz sql komut satırına yorumlanır ve bu bir sonraki kod bloğunu gösterir.

Ancak, belirli bir sayı ile özyinelemeli ifade olarak kullanılabilir.

Deneyin:

exec sp_who2  
go 2

Bazı ifadelerin GO tarafından sınırlanması gerekir:

use DB
create view thisViewCreationWillFail
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.