Birisi bana SQL Server'ı ne zaman ve nerede kullanmam begin
ve end
engellemem gerektiğini söyleyebilir mi?
Ayrıca, Go
anahtar kelime tam olarak ne yapar ?
Yanıtlar:
GO bir senaryonun sonu gibidir.
GO ile ayrılmış birden çok CREATE TABLE deyiminiz olabilir. Bu, komut dosyasının bir bölümünü diğerinden ayırmanın, ancak hepsini tek bir blokta göndermenin bir yoludur.
BEGIN ve END, C / ++ / #, Java vb .'deki {and} gibidir.
Mantıksal bir kod bloğu bağladılar. BEGIN ve END'i saklı yordamın başında ve sonunda kullanma eğilimindeyim, ancak burada kesinlikle gerekli değil. Gerekli olduğu yerde, birden fazla adıma ihtiyaç duyduğunuz döngüler ve EĞER ifadeleri vb.
IF EXISTS (SELECT * FROM my_table WHERE id = @id)
BEGIN
INSERT INTO Log SELECT @id, 'deleted'
DELETE my_table WHERE id = @id
END
Birden fazla ifadeyi kapsayan bir blok oluşturmak için BEGIN ... END gerekir. Öyleyse, bir IF ifadesinin bir 'ayağında' 2 şey yapmak istiyorsanız veya bir WHILE döngüsünün gövdesinde birden fazla şey yapmak istiyorsanız, bu ifadeleri BEGIN ile parantez içinde tutmanız gerekir ... SON.
GO anahtar sözcüğü SQL'in bir parçası değildir. Yalnızca Query Analyzer tarafından komut dosyalarını bağımsız olarak yürütülen "toplu işlere" bölmek için kullanılır.
GO, SQL Server'da bir anahtar sözcük değildir; bu bir toplu ayırıcıdır. GO, bir grup deyimi sonlandırır. Bu, özellikle SQLCMD gibi bir şey kullanırken kullanışlıdır. Komut satırında SQL ifadeleri girdiğinizi hayal edin. Bir ifadeyi her sonlandırdığınızda bir şeyin yürütülmesini istemezsiniz, bu nedenle SQL Server siz "GO" girene kadar hiçbir şey yapmaz.
Aynı şekilde, grubunuz başlamadan önce, genellikle bazı nesnelerin görünür olması gerekir. Diyelim ki bir veritabanı oluşturuyorsunuz ve ardından sorguluyorsunuz. Yazamazsın:
CREATE DATABASE foo;
USE foo;
CREATE TABLE bar;
çünkü CREATE TABLE oluşturan toplu iş için foo mevcut değildir. Bunu yapmanız gerekir:
CREATE DATABASE foo;
GO
USE foo;
CREATE TABLE bar;
BEGIN ve END diğerleri tarafından iyi yanıtlanmıştır.
Gary'nin belirttiği gibi GO, isql, sqlcmd, sorgu analizörü ve SQL Server Management stüdyosu gibi Microsoft tarafından sağlanan istemci araçlarının çoğu tarafından kullanılan bir toplu ayırıcıdır. (Araçlardan en azından bazıları parti ayırıcının değiştirilmesine izin veriyor. Parti ayırıcıyı değiştirmek için hiç bir kullanım görmedim.)
GO'nun ne zaman kullanılacağı sorusuna cevap vermek için, SQL'in ne zaman gruplara ayrılması gerektiğini bilmek gerekir.
Bazı ifadeler bir grubun ilk ifadesi olmalıdır.
select 1
create procedure #Zero as
return 0
SQL Server 2000'de hata şudur:
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 Server 2005'te hata daha az yararlıdır:
Msg 178, Level 15, State 1, Procedure #Zero, Line 5
A RETURN statement with a return value cannot be used in this context.
Bu nedenle, bir GO
grubun başlangıcı olması gereken ifadeleri bir komut dosyasında kendisinden önce gelen ifadelerden ayırmak için kullanın.
Bir komut dosyası çalıştırırken, birçok hata toplu işin yürütülmesinin durmasına neden olur, ancak daha sonra istemci bir sonraki toplu işi gönderir, komut dosyasının yürütülmesi durmaz. Bunu genellikle test ederken kullanırım. Betiğe işlem başlangıcıyla başlayıp geri alma ile bitireceğim, tüm testleri ortada yapacağım:
begin transaction
go
... test code here ...
go
rollback transaction
Bu şekilde, her zaman başlangıç durumuna geri dönüyorum, test kodunda bir hata olsa bile, ayrı bir partinin parçası olan başlama ve geri alma işlem ifadeleri hala devam ediyor. Ayrı gruplar halinde değillerse, bir sözdizimi hatası, bir toplu iş bir birim olarak ayrıştırıldığından, işlemin başlamasını engeller. Ve bir çalışma zamanı hatası, geri dönüşün gerçekleşmesini engeller.
Ayrıca, bir yükleme betiği yapıyorsanız ve bir dosyada birden fazla toplu iş varsa, bir toplu işteki bir hata, betiğin çalışmaya devam etmesini engellemez ve bu da karışıklığa neden olabilir. (Yüklemeden önce daima yedekleyin.)
Dave Markel'in işaret ettiği şeyle ilgili olarak, SQL Server toplu işin başında oluşturulmuş nesneler için veri sözlüğüne baktığı için ayrıştırmanın başarısız olacağı durumlar vardır, ancak herhangi bir ifade çalıştırılmadan önce ayrıştırma yapılabilir. Bazen bu bir sorundur, bazen değil. İyi bir örnek bulamıyorum. Ama eğer bir 'X yok' hatası alırsanız, bu ifade ile açıkça var olacaksa toplu işlere bölünür.
Ve son bir not. İşlem toplu işlere yayılabilir. (Yukarıya bakın.) Değişkenler yığınları kapsamaz.
declare @i int
set @i = 0
go
print @i
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "@i".
GO bir grubu bitirir, kodda çok nadiren kullanmanız gerekir. Kaydedilmiş bir işlemde kullanırsanız, siz proc'u çalıştırdığınızda GO'dan sonra hiçbir kod çalıştırılmayacağını unutmayın.
BEGIN ve END, işlenecek çok satırlı kod içeren herhangi bir yordamsal tip deyimi için gereklidir. Bunlara WHILE döngüleri ve imleçleri (elbette mümkünse kaçınmanız gereken) ve EĞER ifadeleri (teknik olarak, yalnızca bir satır kod içeren bir IF ifadesi için bunlara ihtiyacınız yoktur, ancak daha kolay her zaman bir IF'den sonra koyarsanız kodu koruyun). CASE ifadeleri de END kullanır, ancak BEGIN'e sahip değildir.
Bugün bu problemle boğuştuktan sonra benim fikrim şudur: BEGIN ... END, {....} 'nın C dillerinde yaptığı gibi kodu parantezler, örneğin if ... else ve döngüler için kod blokları
GO, sonraki ifadeler önceki bir ifade ile tanımlanan bir nesneye dayandığında kullanılır (kullanılmalıdır). USE veritabanı, yukarıdaki iyi bir örnektir, ancak aşağıdakiler de sizi ısırır:
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.
Bana öyle geliyor ki sorun şudur: SQL Server SQL Ayrıştırıcısı, Oracle'ın aksine, ilk satırda yeni bir sembol tanımladığınızı ve aşağıdaki satırlarda referans vermenin uygun olduğunu anlayamıyor. Son GO'dan bu yana önceki SQL'i yürütmesini söyleyen bir GO belirteciyle karşılaşana kadar sembolü "görmez", bu noktada sembol veritabanına uygulanır ve ayrıştırıcı tarafından görünür hale gelir.
Neden noktalı virgülü anlamsal bir kırılma olarak ele alıp ifadeleri tek tek uygulamıyor, bilmiyorum ve olmasını diliyorum. Görebildiğim tek bonus, GO'dan hemen önce bir print () ifadesi koyabilmeniz ve ifadelerden herhangi biri başarısız olursa, print çalışmayacaktır. Küçük bir kazanç için çok fazla sorun.