SQL Server'da noktalı virgülleri ne zaman kullanmalıyım?


221

Web üzerindeki bazı kodları ve SQL Server Management Studio tarafından oluşturulan komut dosyalarını kontrol ederken bazı ifadelerin noktalı virgülle sonlandığını fark ettim.

Ne zaman kullanmalıyım?


23
SQL Server 2008 R2 msdn.microsoft.com/tr-tr/library/ms177563.aspx "Transact-SQL Sözdizimi Kuralları (Transact-SQL)" ; == Transact-SQL deyim sonlandırıcı. Noktalı virgül, SQL Server'ın bu sürümündeki çoğu ifade için gerekli olmasa da , gelecekteki bir sürümde gerekli olacaktır .
gerryLowry

2
Gelecekteki bir sürümde noktalı virgül gerekli olacağını iddia etseler de, bu asla gerçekleşmeyecektir. Uyumluluk nedeniyle bunu zorunlu kılmazlar. Uygulamaların yaklaşık% 100'ünü bozacaktır.
usr

1
Şimdi 2019 ve SQL Server'ın son sürümünde hiçbir noktalı virgül hala kabul edilmiyor. @Usr'un söylediği gibi, Microsoft% 100 temiz bir mola vermek istemedikçe, bunu uygulayabilmeleri mümkün değildir.
Ian Kemp

Yanıtlar:


152

Ken Powers'ın SQLServerCentral.Com makalesinden :

Noktalı virgül

Noktalı virgül karakteri bir deyim sonlandırıcıdır. ANSI SQL-92 standardının bir parçasıdır, ancak Transact-SQL içinde hiç kullanılmamıştır. Gerçekten de, noktalı virgülle karşılaşmadan yıllarca T-SQL kodlamak mümkün oldu.

kullanım

Noktalı virgül kullanmanız gereken iki durum vardır. İlk durum, Ortak Tablo İfadesi (CTE) kullandığınız yerdir ve CTE toplu işteki ilk ifade değildir. İkincisi, bir Service Broker deyimi verdiğiniz ve Service Broker deyimi toplu işteki ilk deyim değildir.


9
THROWbir Service Broker deyimi? Bu örnekte atıştan önce noktalı virgül eklememiz gerekiyor:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
Chris Walsh

1
Temel olarak, noktalı virgülün son yıllarda kullanılmaya başlanan tüm yeni ifade türlerinden önce istenmesini temel olarak teşvik ettikleri anlaşılıyor. ( MERGEörneğin). Diğer cevaplarda belirtildiği gibi, ANSI standardında gereklidirler
Mark Sowul

2
@maurocam Sanırım belgeyi yanlış okudunuz. Eğer bu bağlantı bakarsanız "diyor Değil noktalı virgülle Transact-SQL deyimleri biten." kullanımdan kaldırıldı.
Caltor

Gördüğüm kadarıyla, bu gerçekten bir zaman sorusunu ele almaz gerektiğini (karşıt olarak mutlaka ) noktalı virgül kullanın.
Stewart

81

Varsayılan olarak, SQL ifadeleri noktalı virgülle sonlandırılır. (Nadiren) yeni bir deyim sonlandırıcısı ayarlamadığınız sürece deyimleri sonlandırmak için noktalı virgül kullanırsınız.

Sadece bir ifade gönderiyorsanız, teknik olarak ifade sonlandırıcısından vazgeçebilirsiniz; bir komut dosyasında, birden fazla ifade gönderirken buna ihtiyacınız vardır.

Uygulamada, veritabanına yalnızca bir ifade gönderiyor olsanız bile, sonlandırıcıyı her zaman dahil edin.

Düzenleme: deyim sonlandırıcıları [belirli RDBMS] tarafından gerekli olmadığını söyleyenlere yanıt olarak, bu doğru olsa da, ANSI SQL Standardı tarafından gereklidir. Tüm programlamalarda, işlevsellik kaybı olmadan bir standarda bağlı kalabilirsek, yapmamız gerekir, çünkü o zaman ne kodumuz ne de alışkanlıklarımız bir tescilli satıcıya bağlı değildir.

Bazı C derleyicilerinde, Standart int'in geri dönmesini gerektirse de ana dönüşün geçersiz olması mümkündür. Ancak bunu yapmak, kodumuzu ve kendimizi daha az taşınabilir hale getirir.

Programlamanın etkili olmasının en büyük zorluğu yeni şeyler öğrenmek değil, kötü alışkanlıkları öğrenmektir. İlk etapta kötü alışkanlıklar edinmekten kaçınabildiğimiz sürece, bu bizim için, kodumuz için ve kodumuzu okuyan veya kullanan herkes için bir kazanç.



25

Sen gerekir kullanabilirsiniz.

İfadeleri sonlandırmak için noktalı virgül kullanma uygulaması standarttır ve aslında diğer bazı veritabanı platformlarında bir gerekliliktir. SQL Server, yalnızca belirli durumlarda noktalı virgül gerektirir; ancak noktalı virgülün gerekli olmadığı durumlarda, noktalı virgül kullanmak sorun yaratmaz. Tüm ifadeleri noktalı virgülle sonlandırma uygulamasını benimsemenizi önemle tavsiye ederim. Bunu yapmak sadece kodunuzun okunabilirliğini artırmakla kalmaz, bazı durumlarda size biraz keder kazandırabilir. (Noktalı virgül gerektiğinde ve belirtilmediğinde, SQL Server'ın ürettiği hata iletisi her zaman çok net değildir.)

Ve en önemlisi:

SQL Server belgeleri, noktalı virgülle T-SQL deyimlerinin sonlandırılmasının kullanımdan kaldırılmış bir özellik olduğunu gösterir. Bu, uzun vadeli hedefin noktalı virgülün ürünün gelecekteki bir sürümünde kullanımını zorlamak olduğu anlamına gelir. Bu, şu anda gerekli olmasa bile, tüm ifadelerinizi sonlandırma alışkanlığına girmek için bir neden daha.

Kaynak: Microsoft SQL Server 2012 T-SQL Temelleri Itzik Ben-Gan.


Her zaman kullanmalısınız neden bir örneği ;(bu kopyalanan iki sorgu şunlardır yazı ):

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE()
    THROW
END CATCH

resim açıklamasını buraya girin

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException;
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE();
    THROW
END CATCH

resim açıklamasını buraya girin


7
Bu, noktalı virgül (tırnak işaretleri ile yedeklenmiş) kullanmanız gerektiğine dair güçlü bir argüman gibi görünüyor , ancak sadece bir zorunluluk olan tek bir durum .
Gregor Thomas

3
@Gregor, noktalı virgül kullanmanın bir zorunluluk olduğu ve not using themkullanımdan kaldırılmış bir teknik olduğu açıklanırsa bunları kullanmalısınız. Değilse, gelecekte acı çekme riski vardır. İşi yükseltmeyi / değiştirmeyi planlamıyorsanız ve her zaman SQL Server 2000 ile çalışacaksanız, güvendesiniz :-)
gotqn

5
Doğru, kabul etmeliyim . Ama cevap verdiğin ilk satır, şart değil, en azından henüz değil.
Gregor Thomas

2
Noktalı virgüllerle örnek Incorrect syntax near 'THROW'., iş yerinde uğraşmam gereken sürüm olan SQL Server 2008 (10.0.6241.0) ile sonuçlanır. 2012'de gösterildiği gibi çalışıyor. Kullanımdan kaldırılma nedeniyle noktalı virgül kullanmaya başlamaya ikna oldum. Bunun 2008'de çoğu zaman bir sorun olacağını sanmıyorum.
Pilot_51

1
Cevabınız en iyisi! Çok daha fazla oyu hak ediyor.
Stewart

22

Bunu doğru okursam, TSQL deyimlerini sonlandırmak için noktalı virgül kullanmak gerekir. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx

DÜZENLEME: SSMS 2008R2 için komut dosyanızı biçimlendirecek ve noktalı virgül ekleyecek bir eklenti buldum. Yine de beta aşamasında olduğunu düşünüyorum ...

http://www.tsqltidy.com/tsqltidySSMSAddin.aspx

EDIT: ApexSQL adlı daha iyi bir ücretsiz araç / eklenti buldum ... http://www.apexsql.com/


11

Kişisel görüş: Bunları yalnızca gerektiği yerde kullanın. (Gerekli liste için yukarıdaki TheTXI'nin cevabına bakınız.)

Derleyici bunları gerektirmez olduğundan, olabilir baştan koydu, ama neden? Derleyici size nerede unuttuğunuzu söylemeyecektir, bu nedenle tutarsız kullanım elde edersiniz.

[Bu görüş SQL Server'a özgüdür. Diğer veritabanlarının daha katı gereksinimleri olabilir. SQL'i birden çok veritabanında çalışacak şekilde yazıyorsanız, gereksinimleriniz değişebilir.]

tpdi, "bir senaryoda, birden fazla ifade gönderirken buna ihtiyacınız var." Aslında bu doğru değil. Onlara ihtiyacınız yok.

PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';

Çıktı:

Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional

1
Bu tartışma hakkında ne düşünüyorsunuz? sqlservercentral.com/Forums/Topic636549-8-1.aspx (Hesabınız yoksa bugmenot@bugmenot.com: bugmenot kullanabilirsiniz)
Anwar Pinto

2
Bunun sadece sizin fikriniz olduğunu açıkça belirttiğiniz için teşekkür ederim, ancak hem Microsoft belgeleriyle hem de ANSI standardıyla çakıştığı için iyi bir yanıt verdiğini düşünmüyorum. Bu görüş bir yorumda daha iyi olacağını düşünürdüm. (Sizi
ezmeye

4

Hala T-SQL hakkında bilgi edinmek için çok şey var, ama bir işlem için bazı kod çalışırken (ve stackoverflow ve diğer sitelerden örnekleri temel alarak) Ben noktalı virgül gerekli görünüyor ve eksikse, bir durum buldum ifade hiç yürütülmüyor gibi görünüyor ve herhangi bir hata oluşmuyor. Bu, yukarıdaki cevapların hiçbirinde ele alınmamış gibi görünüyor. (Bu MS SQL Server 2012 kullanıyordu.)

İşlemin istediğim şekilde çalışmasını sağladıktan sonra, etrafında bir deneme yakalamaya karar verdim, böylece herhangi bir hata varsa geri alınır. Ancak bunu yaptıktan sonra işlem gerçekleştirilmedi (SSMS, pencereyi kapatılmayacak bir işlem olduğu konusunda sizi onaylamayan bir işlem olduğu konusunda uyaran güzel bir mesajla onaylar.

Yani bu

COMMIT TRANSACTION 

BEGIN TRY / END TRY bloğunun dışında işlem yapmak için iyi çalıştı, ancak blok içinde olması gerekiyordu

COMMIT TRANSACTION;

Herhangi bir hata veya uyarı bulunmadığını ve sorgu sekmesini kapatmaya çalışılıncaya kadar işlemin hala devam etmediğini belirten bir işaret bulunmadığını unutmayın.

Neyse ki bu o kadar büyük bir soruna neden oluyor ki, bir sorun olduğu hemen belli oluyor. Ne yazık ki hiçbir hata (sözdizimi veya başka türlü) bildirilmediğinden, sorunun ne olduğu hemen belli değildi.

Aksine, ROLLBACK TRANSACTION noktalı virgül ile veya noktalı virgülsüz BEGIN CATCH bloğunda eşit derecede iyi çalışıyor gibi görünüyor.

Bunun bir mantığı olabilir ama keyfi ve Alice Harikalar Diyarında.


Bunun olası bir nedeni, COMMIT TRANSACTIONisteğe bağlı bir işlem / kaydetme noktası adını (yok sayacağı) kabul etmesidir. Sonlandırma noktalı virgül olmadan, COMMIT TRANSACTIONtanımlayıcı olarak ayrışırsa bir sonraki sembolü yiyebilir ve bu da kod anlambilimini kökten değiştirebilir. Bu bir hatayla sonuçlanırsa CATCH, COMMIThiç yürütülmeden tetiklenebilir . Tersine, ROLLBACK TRANSACTIONbunun gibi isteğe bağlı bir tanımlayıcı da kabul etse de, orada ayrıştırmadaki bir hata, işlemin yine de geri alınmasına neden olabilir.
Jeroen Mostert

3

: Noktalı virgül imleç operasyonları ile birlikte kullanılmaması gerekir görünür OPEN, FETCH, CLOSEve DEALLOCATE. Bununla birkaç saatini boşa harcadım. BOL yakından bir göz vardı ve [;] bu imleç ifadeleri için sözdiziminde gösterilmediğini fark ettim!

Bu yüzden:

OPEN mycursor;

ve bu bana 16916 hatası verdi.

Fakat:

OPEN mycursor

çalıştı.


2
Bunun doğru olduğunu düşünmüyorum. BOL, deyim sözdizimindeki noktalı virgülten bahsederken çok tutarlı değildir, örneğin SELECT'e bir göz atın. Ayrıca bazı Cursor'a AÇIK tanık oldum; iyi çalışıyor, FETCH, CLOSE ve DEALLOCATE için aynı ...
Valentino Vranken

Bu bana ayrıştırıcıda bir hata olduğunu gösteriyor. Hangi SQL Server sürümünü kullanıyordunuz?
Stewart


0

İçinde başka ifadeler bulunan bir toplu işte DISABLE veya ENABLE TRIGGER deyimini kullanırken, noktalı virgülle bitmeden hemen önce ifade gerekir. Aksi takdirde, bir sözdizimi hatası alırsınız. Saçımı bununla yırttım ... Ve daha sonra, aynı MS Connect öğesinde tökezledim. Sabitlenmeyeceği için kapalı.

buraya bakın


0

Not: Bu, soruyu yazılı olarak yanıtlar, ancak belirtildiği gibi sormaz. Buraya eklemek, çünkü insanlar onu arayacak

Noktalı virgül, daha önce WITHözyinelemeli CTE ifadelerinde de kullanılır :

;WITH Numbers AS
(
    SELECT n = 1
    UNION ALL
    SELECT n + 1
    FROM Numbers
    WHERE n+1 <= 10
)
SELECT n
FROM Numbers

Bu sorgu, tamsayılardan oluşan Sayılar adlı bir CTE üretecektir [1..10]. Yalnızca 1 değerine sahip bir tablo oluşturarak ve sonra 10'a ulaşıncaya kadar yinelenerek yapılır.


8
Teknik olarak 'önce' değil, daha önce ne gelirse gelsin. Eğer toplu işteki ilk ifade ise, noktalı virgül gerekmez.
Tor Haugen

O değil de İLE önce kullanılmış. Bu sadece önceki ifadeyi sonlandıran noktalı virgül. Görünüşe göre bazı insanlar noktalı virgülün burada olması gerektiğine karar vermişlerdir, çünkü bu, noktalı virgülün gerekli olduğu bir senaryodur. Neden bu insanlar bunun noktalı virgülle ifadeleri her zaman sonlandırmaktan üstün olduğuna karar verdiler , hiçbir fikrim yok.
Stewart

0

SQLServer'da rasgele Komut Zaman Aşımı hataları almak isterseniz , CommandText dizelerinizin sonunda noktalı virgül bırakın.

Bunun herhangi bir yerde belgelenip belgelenmediğini veya bir hata olup olmadığını bilmiyorum, ama oluyor ve bunu acı deneyimlerden öğrendim.

SQLServer 2008 kullanarak doğrulanabilir ve tekrarlanabilir örneklerim var.

aka -> Uygulamada, veritabanına yalnızca bir ifade gönderiyor olsanız bile, sonlandırıcıyı her zaman ekleyin.


Eğer başka bir şey dayalı bir sorgu için zaman aşımı alıyorsanız ancak bu üzerinde eşleme tarafından önbelleğe olarak neredeyse kesin, farklı bir yürütme planları sahip kaynaklanıyordur sonra sonunda bir noktalı virgül, orada olsun veya olmasın tam sorgu metni aksi semantik olarak alakasız dahil boşluk, yorum ve sonlandırma noktalı virgül gibi şeyler. Noktalı virgülün kendisi, herhangi bir zamanlama sorununa neden olmaktan tamamen masum olacaktır.
Jeroen Mostert

-2

Noktalı virgüller her zaman bileşik SELECT deyimlerinde çalışmaz.

Önemsiz bir bileşik SELECT deyiminin bu iki farklı sürümünü karşılaştırın.

Kod

DECLARE @Test varchar(35); 
SELECT @Test=
    (SELECT 
        (SELECT 
            (SELECT 'Semicolons do not always work fine.';););); 
SELECT @Test Test;

İadeler

Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.

Ancak, kod

DECLARE @Test varchar(35)
SELECT @Test=
    (SELECT 
        (SELECT 
            (SELECT 'Semicolons do not always work fine.'))) 
SELECT @Test Test

İadeler

Test
-----------------------------------
Semicolons do not always work fine.

(1 row(s) affected)

11
[Bir yıl sonra]: Vay canına, henüz bu cevaba kimse yorum yapmadı! Elbette işe yaramaz, noktalı virgül ifadeler ayırıcıdır, bu nedenle noktalı virgül ile kodunuz: 1- SELECT @ Test = (SELECT (SELECT (SELECT 'SELico' her zaman iyi çalışmaz. ') - Bu doğru değil ifadesi 2-); - ikisi de bu değil 3-); --ne biri 4-); - ne noktalı virgül biri 3 parantez sonra olmalıdır
PhpLou

1
Deyimleri sonlandırmak için yalnızca noktalı virgül kullanırsınız . Alt sorgu bir ifade değildir. İfadeler sırayla yürütülen şeylerdir. Örneğinizde, üç ifade vardır: 1. DECLARE @ Test varchar (35) 2. SELECT @ Test = (SELECT (SELECT (SELECT 'noktalı virgül her zaman işe yaramaz.'))) 3. SELECT @ Test Testi
Stewart
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.