Чому CTE слід починати з напівколонки?


14

Я просто дивився на публікацію в StackOverflow, де Аарон Бертран пропонує використовувати CTE замість таблиці цифр, що є елегантним способом виконання завдання. Моє запитання: чому перший рядок CTE починається з напівколонки?

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

Це для того, щоб оператор WITH не розбирався на попередній SELECTчи щось таке? У SQL Server 2005 BOL я нічого не бачу щодо використання крапки з двокрапкою до початку.


Відповіді:


26

Я завжди це роблю, коли розміщую тут або в StackOverflow, оскільки для WITH- оскільки ключове слово перевантажене - попередня команда вимагає закінчувати крапку з двокрапкою. Якщо я вставити зразок коду, який використовує CTE, неминуче хтось користувач вставить його у свій існуючий код, а попередній вислів не матиме крапки з комою. Таким чином код порушується, і я отримую скарги на зразок:

Ваш код зламався! Я отримав це повідомлення про помилку:

Incorrect syntax near 'WITH'...

Хоча я хотів би вважати, що людям стає все краще, коли вони завжди припиняють свої висловлювання комою з двокрапкою , я б краще заздалегідь видав шум і просто завжди включав його. Деяким це не подобається, але <shrug />. Ви можете включити стільки напівколонок до чи після дійсного твердження, скільки хочете. Це дійсно:

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

Тож немає ніякої шкоди в тому, що перед твердженням, яке цього вимагає, потрібна додаткова крапка з двократкою. Це безпечніше робити, навіть якщо це не так красиво.

Це має бути дивно сформульовано, щоб зрозуміти крапку, але "не закінчується дійсна заява з крапкою з двократкою" насправді застаріла з часу SQL Server 2008. Так що, як я описую в публікації в блозі, на яку я посилаюся вище, навіть у випадках, коли не потрібно обходити помилку, вона повинна використовуватися там, де це дійсно. Ви можете побачити це тут:

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

(Пошук на останній сторінці "напівколонки")

Звичайно, це не було б SQL Server, якби не було винятків. Спробуйте це:

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

Це не єдиний виняток із правила, але саме це я вважаю неінтуїтивним.


1
У 2012 році я навіть отримую те саме повідомлення про помилку, але лише через напівколонку після END TRY: i.stack.imgur.com/rc6dw.png - якщо я видалю це напівколону, все працює.
Аарон Бертран

Я думаю, що ви не можете ставити крапку з комою раніше, BEGIN CATCHпросто тому, що це частина єдиного складеного оператора, введеного в BEGIN TRY. Це те саме, що ставити крапку з комою перед IFзаявою ELSE.
Андрій М

@AndriyM Мені було присвячено набагато більш детальну розмову про правила тут. Я згадував це, тому що це несподіванка для всіх, хто натрапив на нього, а не тому, що я не розумію причини. :-)
Аарон Бертран

10

Це потрібно для того, щоб воно не було включено до жодних попередніх висловлювань, оскільки WITHможе слугувати різним цілям у T-SQL.

Якщо це перша заява в партії, я не думаю, що вона вам потрібна.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.