Podczas sprawdzania kodu w Internecie i skryptów generowanych przez SQL Server Management Studio zauważyłem, że niektóre instrukcje są zakończone średnikiem.
Więc kiedy powinienem go użyć?
Podczas sprawdzania kodu w Internecie i skryptów generowanych przez SQL Server Management Studio zauważyłem, że niektóre instrukcje są zakończone średnikiem.
Więc kiedy powinienem go użyć?
Odpowiedzi:
Z artykułu SQLServerCentral.Com autorstwa Kena Powersa:
Średnik
Średnik jest zakończeniem instrukcji. Jest częścią standardu ANSI SQL-92, ale nigdy nie był używany w Transact-SQL. Rzeczywiście, możliwe było kodowanie T-SQL przez lata bez żadnego średnika.
Stosowanie
Istnieją dwie sytuacje, w których musisz użyć średnika. Pierwszą sytuacją jest użycie wspólnego wyrażenia tabelowego (CTE), a CTE nie jest pierwszą instrukcją w partii. Drugi to miejsce, w którym wydaje się instrukcję Service Broker, a instrukcja Service Broker nie jest pierwszą instrukcją w partii.
THROW
oświadczenie brokera usług? W tym przykładzie musimy uwzględnić średnik przed rzutem:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
też na przykład). Jak wspomniano w innych odpowiedziach, są one wymagane w standardzie ANSI
Domyślnie instrukcje SQL są zakończone średnikami. Do zakończenia instrukcji używasz średnika, chyba że (rzadko) ustawiłeś nowy terminator instrukcji.
Jeśli wysyłasz tylko jedno oświadczenie, technicznie możesz zrezygnować z terminatora wyciągu; w skrypcie, ponieważ wysyłasz więcej niż jedną instrukcję, potrzebujesz jej.
W praktyce zawsze dołączaj terminator, nawet jeśli wysyłasz tylko jedną instrukcję do bazy danych.
Edycja: w odpowiedzi na te stwierdzenia, terminatory instrukcji nie są wymagane przez [konkretny RDBMS], chociaż może to być prawda, są wymagane przez ANSI SQL Standard. We wszystkich programach, jeśli możemy przestrzegać Standardu bez utraty funkcjonalności, powinniśmy, ponieważ wtedy ani nasz kod, ani nasze nawyki nie są powiązane z jednym zastrzeżonym dostawcą.
W przypadku niektórych kompilatorów C możliwe jest, że główny zwrot jest nieważny, nawet jeśli Standard wymaga, aby zwracał int. Ale dzięki temu nasz kod i my sami jesteśmy mniej przenośni.
Największą trudnością w programowaniu skutecznie nie jest uczenie się nowych rzeczy, to uczenie się złych nawyków. W zakresie, w jakim możemy przede wszystkim uniknąć nabywania złych nawyków, jest to wygrana dla nas, dla naszego kodu i dla każdego, kto czyta lub używa naszego kodu.
W BOL SQL2008 mówią, że w następnych wersjach wymagane będą średniki. Dlatego zawsze używaj go.
Odniesienie:
Państwo musi go używać.
Praktyka używania średnika do kończenia instrukcji jest standardowa i faktycznie jest wymagana na kilku innych platformach baz danych. SQL Server wymaga średnika tylko w szczególnych przypadkach - ale w przypadkach, gdy średnik nie jest wymagany, użycie go nie powoduje problemów. Zdecydowanie zalecam przyjęcie praktyki kończenia wszystkich instrukcji średnikiem. To nie tylko poprawi czytelność twojego kodu, ale w niektórych przypadkach może zaoszczędzić ci trochę smutku. (Gdy wymagany jest średnik i nie jest określony, komunikat o błędzie, który generuje SQL Server, nie zawsze jest bardzo wyraźny).
I najważniejsze:
Dokumentacja programu SQL Server wskazuje, że nie kończenie instrukcji T-SQL średnikiem jest przestarzałą funkcją. Oznacza to, że długoterminowym celem jest wymuszenie użycia średnika w przyszłej wersji produktu. To jeszcze jeden powód, aby nabrać nawyku kończenia wszystkich swoich oświadczeń, nawet jeśli nie jest to obecnie wymagane.
Źródło: Microsoft SQL Server 2012 Podstawy języka T-SQL autorstwa Itzika Ben-Gana.
Przykładem tego, dlaczego zawsze musisz używać, ;
są następujące dwa zapytania (skopiowane z tego postu ):
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
THROW
END CATCH
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
jest przestarzałą techniką, powinieneś ich użyć. Jeśli nie, istnieje ryzyko, że ucierpi w przyszłości. Jeśli nie planujesz uaktualnić / zmienić zadania i zawsze zamierzasz pracować z SQL Server 2000, jesteś bezpieczny :-)
Incorrect syntax near 'THROW'.
pokazuje SQL Server 2008 (10.0.6241.0), czyli wersję, z którą mam do czynienia w pracy. Działa tak, jak pokazano w 2012 roku. Przekonałem się, że zacząłem używać średników z powodu wycofania. Nie spodziewam się, że będzie to problem w 2008 roku przez większość czasu.
Jeśli przeczytam to poprawnie, konieczne będzie użycie średników do zakończenia instrukcji TSQL. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
EDYCJA: Znalazłem wtyczkę do SSMS 2008R2, która sformatuje twój skrypt i doda średniki. Myślę, że wciąż jest w fazie beta ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
EDYCJA: Znalazłem jeszcze lepsze darmowe narzędzie / wtyczkę o nazwie ApexSQL ... http://www.apexsql.com/
Osobista opinia: używaj ich tylko tam, gdzie są wymagane. (Zobacz powyższą odpowiedź TheTXI, aby uzyskać wymaganą listę).
Ponieważ kompilator nie wymaga od nich, to można je wszędzie, ale dlaczego? Kompilator nie powie ci, gdzie go zapomniałeś, więc skończysz z niespójnym użyciem.
[Niniejsza opinia dotyczy SQL Server. Inne bazy danych mogą mieć bardziej rygorystyczne wymagania. Jeśli piszesz SQL, aby uruchamiać go w wielu bazach danych, Twoje wymagania mogą się różnić.]
tpdi stwierdził powyżej: „w skrypcie, ponieważ wysyłasz więcej niż jedną instrukcję, potrzebujesz jej”. To właściwie nie jest poprawne. Nie potrzebujesz ich.
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';
Wynik:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
Nadal muszę się wiele nauczyć o języku T-SQL, ale pracując nad kodem dla transakcji (i opierając kod na przykładach z stackoverflow i innych witryn) znalazłem przypadek, w którym wydaje się, że wymagany jest średnik, a jeśli go brakuje, instrukcja wydaje się wcale nie działać i nie pojawia się żaden błąd. Nie wydaje się, aby było to uwzględnione w żadnej z powyższych odpowiedzi. (To było za pomocą MS SQL Server 2012.)
Gdy transakcja działała tak, jak chciałem, postanowiłem ją wypróbować, aby w razie wystąpienia błędów wycofać transakcję. Dopiero po wykonaniu tej transakcji transakcja nie została zatwierdzona (SSMS potwierdza to przy próbie zamknięcia okna ładnym komunikatem ostrzegającym o fakcie, że transakcja nie została zatwierdzona.
Więc to
COMMIT TRANSACTION
poza BEGIN TRY / END TRY blok działał dobrze, aby zatwierdzić transakcję, ale wewnątrz bloku musiał być
COMMIT TRANSACTION;
Uwaga: nie podano błędu ani ostrzeżenia ani żadnej informacji, że transakcja jest nadal niezatwierdzona do momentu próby zamknięcia karty zapytania.
Na szczęście powoduje to tak duży problem, że od razu widać, że jest problem. Niestety, ponieważ nie zgłoszono żadnego błędu (składniowego lub innego), nie było od razu oczywiste, na czym polega problem.
Przeciwnie, ROLLBACK TRANSACTION wydaje się działać równie dobrze w bloku BEGIN CATCH z lub bez średnika.
Może być w tym trochę logiki, ale wydaje się to arbitralne i Alice-in-Wonderland-ish.
COMMIT TRANSACTION
zaakceptowanie opcjonalnej nazwy transakcji / punktu zapisu (który zignoruje). Bez średnika kończącego COMMIT TRANSACTION
może jeść następny symbol, jeśli analizuje jako identyfikator, co może radykalnie zmienić semantykę kodu. Jeśli spowoduje to błąd, CATCH
może zadziałać bez COMMIT
wykonania. I odwrotnie, chociaż ROLLBACK TRANSACTION
akceptuje także opcjonalny identyfikator taki jak ten, błąd w jego analizie najprawdopodobniej spowoduje wycofanie transakcji.
Wydaje się, że średniki nie powinien być stosowany w połączeniu z operacjami kursora: OPEN
, FETCH
, CLOSE
i DEALLOCATE
. Właśnie zmarnowałem kilka godzin z tym. Przyjrzałem się bliżej BOL i zauważyłem, że [;] nie jest pokazane w składni tych instrukcji kursora !!
Więc miałem:
OPEN mycursor;
i to dało mi błąd 16916.
Ale:
OPEN mycursor
pracował
Zgodnie z konwencjami składni Transact-SQL (Transact-SQL) (MSDN)
Terminator instrukcji Transact-SQL. Chociaż średnik nie jest wymagany w przypadku większości instrukcji w tej wersji programu SQL Server, będzie on wymagany w przyszłej wersji.
(zobacz także komentarz @gerryLowry)
W przypadku użycia instrukcji DISABLE lub ENABLE TRIGGER w partii zawierającej inne instrukcje, instrukcja tuż przed nią musi kończyć się średnikiem. W przeciwnym razie pojawi się błąd składniowy. Zerwałem włosy tym ... A potem natknąłem się na ten przedmiot MS Connect o to samo. Jest zamknięty, ponieważ nie można go naprawić.
patrz tutaj
Uwaga: To odpowiada na pytanie, jak napisano, ale nie na problem, jak stwierdzono. Dodanie go tutaj, ponieważ ludzie będą go szukać
Średnik jest również używany wcześniej WITH
w rekurencyjnych instrukcjach CTE:
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
To zapytanie wygeneruje CTE o nazwie Liczby, które składa się z liczb całkowitych [1..10]. Odbywa się to poprzez utworzenie tabeli o wartości tylko 1, a następnie rekurencję aż do osiągnięcia 10.
Jeśli lubisz dostawać losowe błędy przekroczenia limitu czasu poleceń w SQLServer, zostaw średnik na końcu ciągów CommandText.
Nie wiem, czy jest to gdzieś udokumentowane, czy jest to błąd, ale tak się dzieje i nauczyłem się tego z gorzkich doświadczeń.
Mam weryfikowalne i odtwarzalne przykłady przy użyciu SQLServer 2008.
aka -> W praktyce zawsze dołączaj terminator, nawet jeśli wysyłasz tylko jedną instrukcję do bazy danych.
Średniki nie zawsze działają w złożonych instrukcjach SELECT.
Porównaj te dwie różne wersje trywialnej złożonej instrukcji SELECT.
Kod
DECLARE @Test varchar(35);
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.';);););
SELECT @Test Test;
zwroty
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.
Jednak kod
DECLARE @Test varchar(35)
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.')))
SELECT @Test Test
zwroty
Test
-----------------------------------
Semicolons do not always work fine.
(1 row(s) affected)