Dlaczego CTE powinien zaczynać się od średnika?

14

Właśnie patrzyłem na post na StackOverflow, w którym Aaron Bertrand proponuje użycie CTE zamiast tabeli liczb, co jest eleganckim sposobem wykonania danego zadania. Moje pytanie brzmi: dlaczego pierwsza linia CTE zaczyna się średnikiem?

;WITH n AS (SELECT TOP (10000) n FROM 
  (SELECT n = ROW_NUMBER() OVER
    (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
  ) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!

Czy ma to na celu zapewnienie, że instrukcja WITH nie zostanie przeanalizowana w poprzednim SELECTlub czymś innym ? W BOL programu SQL Server 2005 nie widzę nic o używaniu średnika przed Z.

Max Vernon
źródło

Odpowiedzi:

26

Zawsze robię to, pisząc tutaj lub na StackOverflow, ponieważ WITH- ponieważ słowo kluczowe jest przeciążone - poprzednie polecenie wymaga kończącego średnika. Jeśli wkleję przykładowy kod, który używa CTE, nieuchronnie jakiś użytkownik wklei go do swojego istniejącego kodu, a poprzednie oświadczenie nie będzie zawierało średnika. Więc kod się psuje i dostaję takie skargi, jak:

Twój kod się zepsuł! Otrzymałem ten komunikat o błędzie:

Incorrect syntax near 'WITH'...

Chociaż chciałbym wierzyć, że ludzie stają się coraz lepsi w tym, że zawsze kończą swoje wypowiedzi średnikiem , wolałbym uprzedzić hałas i po prostu zawsze go uwzględniać. Niektórym się to nie podoba, ale <shrug />. Możesz dołączyć tyle średników przed lub po prawidłowym wyciągu, ile chcesz. Jest to ważne:

;;;;SELECT 1;;;;;;;;;;;;SELECT 2;;;;;;;;SELECT 3;;;;;

Zatem nie ma żadnej szkody, że istnienie dodatkowego średnika przed stwierdzeniem, że z definicji tego wymaga. Jest to bezpieczniejsze, nawet jeśli nie jest tak ładne.

To musi być dziwnie sformułowane, aby uzyskać sens, ale „nie kończenie prawidłowego wyrażenia średnikiem” jest w rzeczywistości przestarzałe od SQL Server 2008. Tak więc, jak opisuję w blogu, odsyłam do powyższego, nawet w przypadkach, w których nie jest wymagane obejście błędu, powinno być stosowane wszędzie tam, gdzie jest ważne. Możesz to zobaczyć tutaj:

http://msdn.microsoft.com/en-us/library/ms143729.aspx

(Wyszukaj na ostatniej stronie „średnik”)

Oczywiście nie byłby to SQL Server, gdyby nie było wyjątków. Spróbuj tego:

BEGIN TRY;
  SELECT 1/1;
END TRY;
BEGIN CATCH;
  SELECT 1/1;
END CATCH;

Nie jest to jedyny wyjątek od reguły, ale najbardziej nieintuicyjny.

Aaron Bertrand
źródło
1
Nawet w 2012 roku pojawia się ten sam komunikat o błędzie, ale tylko z powodu średnika po END TRY: i.stack.imgur.com/rc6dw.png - jeśli usunę ten średnik, wszystko będzie działać .
Aaron Bertrand
Myślę, że nie można wcześniej wstawić średnika, BEGIN CATCHponieważ jest on częścią pojedynczej instrukcji złożonej wprowadzonej za pomocą BEGIN TRY. To tak samo, jak wstawienie średnika przed IFwyrażeniem ELSE.
Andriy M
@AndriyM Byłem wtajemniczony w znacznie bardziej szczegółową rozmowę na temat zasad tutaj. Wspomniałem o tym, ponieważ jest to niespodzianka dla każdego, kto się z nim spotka, nie dlatego, że nie rozumiem powodu. :-)
Aaron Bertrand
10

Ma to na celu zapewnienie, że nie zostanie uwzględnione w żadnych poprzednich instrukcjach, ponieważ WITHmoże służyć do różnych celów w języku T-SQL.

Jeśli to pierwsze stwierdzenie w partii, nie sądzę, żebyś go potrzebował.

swasheck
źródło