Секция WITH позволяет описывать common table expressions (CTE), которые по сути являются поименованными запросами SELECT (аналогично представлениям), к которым можно обращаться в последующей команде DML. Использование CTE допустимо, если уровень совместимости для БД выставлен в значение 90. Следует отметить, что CTE может использовать рекурсию, т.е. команду SELECT, которая обращается к самому CTE. В общем виде секция WITH выглядит следующим образом:
WITH
имя_CTE [(перечень_имен_столбцов)]
AS
(перечень_запросов_SELECT)
[, и. т.п.]
Таким образом, в этой секции можно объединять несколько CTE. Перечень_запросов_SELECT является набором команд SELECT, объединенных каким-либо из операторов EXCEPT, INTERCEPT или UNION [ALL] (в случае нерекурсивного CTE). В случае рекурсивного CTE Перечень_запросов_SELECT выглядит следующим образом:
Нерекурсиный_запрос_SELECT_1
[
{EXCEPT | INTERSECT | UNION [ALL]}
Нерекурсиный_запрос_SELECT_2
{EXCEPT | INTERSECT | UNION [ALL]}
…
Нерекурсиный_запрос_SELECT_N
]
UNION ALL
Рекурсиный_запрос_SELECT_1
[
Рекурсиный_запрос_SELECT_2
UNION ALL
…
Рекурсиный_запрос_SELECT_N
]
Следует отметить, что количество столбцов объединяемых запросов должно быть одинаково, а их типы данных – совместимы.
Создание CTE подчиняется следующим правилам:
1. CTE может ссылаться само на себя или на ранее описанные CTE, но не может ссылаться на CTE, которые еще не описаны.
2. Нельзя использовать секцию WITH в CTE.
3. В запросах SELECT, которые образуют CTE, не могут быть использованы следующие секции:
· COMPUTE [BY].
· ORDER BY (кроме случая, когда используется опция TOP).
· INTO.
· OPTION с указанием настроек поведения запроса.
· FOR XML.
· FOR BROWSE.
4. Если команда, содержащая секцию WITH идет не 1-ой в пакете команд, то предшествующая ей команда должна завершаться символом ;.
Для рекурсивных CTE существует ряд дополнительных правил и ограничений:
1. Секция FROM рекурсивных запросов должна ссылаться на имя CTE, к которому они принадлежат, только 1 раз.
2. Следующие секции, операторы и конструкции не могут использоваться в запросах SELECT, которые образуют CTE:
· Опции DISTINCT и TOP.
· GROUP BY.
· HAVING.
· Операторы {LEFT | RIGHT | FULL} [OUTER] JOIN (INNER JOIN и CROSS JOIN- допустимы).
· Вложенные запросы SELECT.
· Скалярные агрегационные функции.
3. Все столбцы, возвращаемые рекурсивным CTE, имеют свойство NULL.
4. Представление, содержащее рекурсивные CTE, не может быть использовано для изменения данных в связанных с ним таблицах.
5. Если рекурсивный CTE содержится в команде SELECT, которая описывает курсор, то тип курсора может быть только STATIC или FAST_FORWARD. В противном случае - тип курсора будет приведен к типу STATIC.
6. В рекурсивном запросе должно содержаться условия остановки, прерывающее его выполнение. В противном случае получается бесконечный цикл выполнения рекурсивного запроса SELECT, что приводит к ошибке.