Mengapa CTE harus dimulai dengan semi-colon?

14

Saya hanya melihat posting di StackOverflow di mana Aaron Bertrand mengusulkan menggunakan CTE daripada tabel angka, yang merupakan cara yang elegan untuk melakukan tugas yang ada. Pertanyaan saya adalah, mengapa baris pertama CTE dimulai dengan titik koma?

;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!

Apakah ini untuk memastikan pernyataan DENGAN tidak diurai menjadi sebelumnya SELECTatau sesuatu? Saya tidak melihat apa pun di SQL Server 2005 BOL tentang penggunaan titik koma sebelum DENGAN.

Max Vernon
sumber

Jawaban:

26

Saya selalu melakukannya ketika memposting di sini atau di StackOverflow karena untuk WITH- karena kata kunci dibebani berlebihan - perintah sebelumnya memerlukan semi-colon terminating. Jika saya menempelkan contoh kode yang menggunakan CTE, pasti beberapa pengguna akan menempelkannya ke dalam kode mereka yang ada, dan pernyataan sebelumnya tidak akan memiliki titik koma. Jadi kodenya rusak, dan saya mendapat keluhan seperti:

Kode Anda rusak! Saya mendapat pesan kesalahan ini:

Incorrect syntax near 'WITH'...

Sementara saya ingin percaya bahwa orang-orang menjadi lebih baik tentang selalu mengakhiri pernyataan mereka dengan titik koma , saya lebih suka mengurangi kebisingan dan selalu memasukkannya. Beberapa orang tidak menyukainya, tetapi <shrug />. Anda dapat memasukkan semi-titik dua sebelum atau sesudah pernyataan yang valid seperti yang Anda inginkan. Ini valid:

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

Jadi tidak ada salahnya ada tambahan semi-colon sebelum pernyataan yang menurut definisi mengharuskannya. Lebih aman melakukannya meskipun tidak cantik.

Itu harus diucapkan dengan aneh untuk mendapatkan maksud, tetapi "tidak mengakhiri pernyataan yang valid dengan titik koma" sebenarnya sudah ditinggalkan sejak SQL Server 2008. Jadi seperti yang saya jelaskan dalam posting blog saya tautkan ke atas, bahkan dalam kasus di mana itu tidak diperlukan untuk mem-bypass kesalahan, itu harus digunakan dimanapun valid. Anda dapat melihat ini di sini:

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

(Cari halaman terakhir untuk "semi-colon")

Tentu saja itu bukan SQL Server jika tidak ada pengecualian. Coba ini:

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

Ini bukan satu-satunya pengecualian pada aturan, tetapi itu satu-satunya yang saya temukan paling tidak intuitif.

Aaron Bertrand
sumber
1
Pada 2012 bahkan saya mendapatkan pesan kesalahan yang sama, tetapi hanya karena titik koma setelah END TRY: i.stack.imgur.com/rc6dw.png - jika saya menghapus titik koma itu, semuanya berfungsi.
Aaron Bertrand
Saya pikir Anda tidak dapat meletakkan titik koma sebelumnya BEGIN CATCHhanya karena itu adalah bagian dari pernyataan majemuk tunggal yang diperkenalkan BEGIN TRY. Ini sama dengan meletakkan tanda titik koma di depan IFpernyataan ELSE.
Andriy M
@AndriyM Saya sudah mengetahui rahasia percakapan yang jauh lebih rinci tentang aturan di sini. Saya menyebutkannya karena ini mengejutkan semua orang yang menemukannya, bukan karena saya tidak mengerti alasannya. :-)
Aaron Bertrand
10

Ini untuk memastikan bahwa itu tidak termasuk dalam pernyataan sebelumnya karena WITHdapat melayani berbagai tujuan dalam T-SQL.

Jika ini adalah pernyataan pertama dalam kumpulan, saya tidak berpikir Anda membutuhkannya.

swasheck
sumber