Her T-SQL deyiminden sonra GO


34

Her SQL ifadesinden sonra GO ifadesini kullanmanın ardındaki sebep nedir? GO'nun partinin sonunu işaret ettiğini ve / veya ifadelerin itibarını sağladığını ancak her ifadeden sonra kullanmanın ne avantajı olduğunu biliyorum.

Her türlü açıklamadan sonra Microsoft dokümanları vb. Kullanmaya başladığım için merak ediyorum ya da belki fark etmeye başladım.

Ayrıca en iyi uygulama nedir?

Yanıtlar:


51

Ne zaman ve ne zaman kullanılacağına cevap vermeden önce, tam olarak ne GOolduğunu ve ne olmadığını anlamada ilk şarttır .

Anahtar kelime GO, bir şeyi ve yalnızca bir şeyi belirtmek için SQL Server Management Studio ve SQLCMD tarafından kullanılır: Bir deyim grubunun sonu. Aslında, partileri "GO" dışında bir şeye sonlandırmak için kullandıklarınızı bile değiştirebilirsiniz :

görüntü tanımını buraya girin

Bu ekran görüntüsünün SSMS içindeki yapılandırılabilir bir seçenektir.

Ama toplu iş nedir? Bu BOL referansı en iyisini söylüyor:

Toplu iş, aynı anda bir uygulamadan yürütme için SQL Server'a gönderilen bir veya daha fazla Transact-SQL ifadesi grubudur .

Bu kadar basit. Bu sadece bir uygulamanın (evet ... bir uygulamanın) özel bir yolunu SQL Server'a gönderir. Bunun uygulama görünümlü bir örneğini görelim. Bir uygulamanın SQL Server'a ifadeler ve gruplar göndermek için ne yapacağını taklit etmek için PowerShell kullanacağım:

$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
}

Yorumlar onu dağıtıyor, ancak yukarıda gördüğünüz gibi SQL Server'a programlı olarak iki parti gönderdiğimizi görebilirsiniz . Bunu doğrulayalım. Buradaki seçimim Extended Events kullanmak.

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

Tüm bu XEvents oturumu, adlı bir uygulamadan başlayan ve tamamlanan ifadeleri ve grupları yakalamaktır "BatchTesting"(PowerShell kod örneğindeki bağlantı dizgemi fark ederseniz, "uygulamayı kullanarak belirli bir etkinlik oluşturucuya bakmanın hızlı bir yoludur." "bağlantı dizesi parametresi adı ve filtreleme"

PowerShell kodunu bu partileri ve ifadeleri göndermek için yürüttükten sonra aşağıdaki sonuçları görüyorum:

görüntü tanımını buraya girin

Ekran görüntüsünden de görebileceğiniz gibi, ifadeleri iki farklı gruba nasıl ayırdığımızı ve aynı zamanda grupları çağırmak için kullandığımız yollarla da açıkça görülebiliyor. Ve batch_textilk oluşumuna sql_batch_startingbakarsak, o partide yer alan tüm ifadeleri görebiliriz:

    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;

Bir partinin ne olduğuna dair bu açıklama ile, şimdi partileri ne zaman sonlandıracağınıza dair sorunuzun cevabı geliyor . Partilerle ilgili kurallar, partilere ilişkin bu BOL referansında bulunur :

VARSAYILMIŞ OLUŞTURUN, İŞLEVİNİ OLUŞTURUN, İŞLEM OLUŞTURMA, KURAL OLUŞTURUN, ŞEMA OLUŞTURMA, YARATICI OLUŞTURMA ve CREATE VIEW ifadeleri toplu iş içindeki diğer ifadelerle birleştirilemez. CREATE deyimi toplu işlemi başlatmalıdır. Bu toplu işin ardından gelen diğer tüm ifadeler, ilk CREATE ifadesinin tanımının bir parçası olarak yorumlanacaktır.

Bir tablo değiştirilemez ve ardından aynı toplu işlemde yeni sütunlar referans alınır.

Bir EXECUTE ifadesi toplu işteki ilk ifade ise, EXECUTE anahtar sözcüğü gerekli değildir. EXECUTE ifadesi, toplu işteki ilk ifade değilse, EXECUTE anahtar sözcüğü gereklidir.

Benzer şekilde, bir toplu işlem sırasında gerçekleşen belirli çalışma zamanı hataları (derleme hataları bir toplu işlemin yürütülmesine izin vermez) farklı davranışlara neden olabilir: toplu işlemi tamamen iptal etmek veya toplu işleme devam etmek ve yalnızca rahatsız edici ifadeyi iptal etmek (yukarıdaki link iki gerçekten iyi örnek verir: Örneğin, aritmetik bir taşma hatası, toplu işin yürütülmesini durduracaktır, ancak bir kısıtlama ihlali hatası yalnızca mevcut ifadenin tamamlanmasını engelleyecektir, ancak toplu işlem yürütülmeye devam edecektir).

Yine de mesleğimizdeki pek çok şey gibi, kişisel tercih , T-SQL kodunu nasıl kişiselleştirdiğiniz ve T-SQL kodunu yazarken partileri nasıl sonlandıracağınız konusunda büyük bir itici güç olacaktır. Bazı insanlar yalnızca kesin olarak zorunlu olmaları durumunda (yalnızca bu gereksinimler için yukarıya bakınız) parti tanımları yapar ve diğerleri yalnızca SSMS'de bir Sorgu Penceresinde tek bir ifade yürütürken bile programın zamanının% 100'ünü seri olarak sonlandırır . Çoğu insan bu iki sınırın ortasında bir yere düşer. Buna değer, ifade sonlandırıcılar çok az zorunlu gereksinimleri ile aynı izler. Tüm bunların büyük bir kısmı zorlanmadığı durumlarda kod stilidir (SSMS ve SQLCMD'de).


Belki de saf bir yorum ama bana, SQL Server'ın ne yapacağı konusunda karar verebileceğini belirledi (aynı zamanda birçok optimizasyonun veritabanı motoru tarafından ele alındığı gibi). Örneğin, kullanıcının kendilerine yazması için onları kullanmaya güvenmek yerine açıkladığınız kuralları kullanmak, bu hataya açık olabilir ve komut dosyalarına gereksiz şişkinlik katıyor olabilir.
Steve Chambers,

1
@SteveBenim duygularımı aynen etkiliyor. Cevap, "bu kadar basit" diyor (Toplu iş, aynı anda bir uygulamadan SQL Server'a yürütülmek üzere gönderilen bir veya daha fazla Transact-SQL ifadesi grubudur.) Ama değil. Başarısız olan bir toplu iş içinde deneyip gönderebileceğim ifadeler var. Sonuçta anlamana gerek niçin ve nasıl : Sonunda bu işte, kendi cevabı katkıda yüzden - toplu gönderme bireysel tabloların bir dizi göndermekten daha farklıdır stackoverflow.com/a/56370223/3714936 - Ayrıca yorumunuza konuşur .
youcantryreachingme
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.