KB2322209 — FIX: неверные результаты при использовании круглых скобок для выделения в инструкции, которая содержит общее табличное выражение в SQL Server 2008


Проблемы


На компьютере под управлением Microsoft SQL Server 2008 рассматривайте следующие сценарии.

Сценарий 1

Вы указываете общее табличное выражение (CTE) с помощью оператора WITH. Например, вы запускаете следующий запрос:
WITH common_table_expression AS (SELECT * FROM sys.objects)(SELECT * FROM common_table_expression)
Затем вы запускаете этот запрос.
SELECT *FROM sys.dm_exec_query_statsWHERE statement_start_offset > statement_end_offsetANDstatement_end_offset <> -1
В этом сценарии кэшированный план запроса для этого запроса хранит неправильные statement_start_offsetные и statement_end_offset значения. В частности, обратите внимание на то, что statement_end_offset значение меньше значения statement_start_offset при выполнении sys.dm_exec_query_stats динамического административного представления (DMV). Из-за этой проблемы может произойти сбой отчета о производительности, если предполагается, что значение statement_start_offset всегда меньше значения statement_stop_offset.

Сценарий 2

Вы указываете общее табличное выражение с помощью оператора WITH, и вы используете функцию повторной компиляции. Например, вы создаете функцию в SQL Server 2008 с помощью следующего сценария.
CREATE FUNCTION function1() RETURNS int ASBEGINDECLARE @x intSET @x=1;WITH common_table_expression AS (SELECT @x AS column1) (SELECT @x=column1 FROM common_table_expression) OPTION(RECOMPILE)RETURN @xEND
При выполнении запроса "Select dbo. function1 ()" появляется следующее сообщение об ошибке:
При текущей команде возникла серьезная ошибка. Результаты, если таковые имеются, должны быть удалены.
Кроме того, эта ошибка может возникать без возможности повторной компиляции в случае, если сервер SQL Server испытывает существенный трафик сервера.

Сценарий 3

Вы указываете общее табличное выражение с помощью оператора WITH. В операторе WITH вы указываете несуществующую таблицу. Например, вы запускаете следующий запрос:
WITH computed_table (id) AS(SELECT id FROM this_table_does_not_exist) (SELECT id FROM dbo.computed_table) GO
При выполнении этого запроса не появляется сообщение об ошибке для отсутствующей таблицы.

Причина


Эти проблемы возникают из-за того, что в инструкции SELECT, которая следует за оператором WITH, произошла неправильное выполнение. Оператор WITH использует следующий синтаксис:
WITH common_table_expression AS(CTE_query_definition)
Затем эта инструкция создает набор результатов, назначаемый указанному имени общего табличного выражения. Затем вы подпишитесь на этот оператор с помощью инструкции SELECT. Если второй оператор заключен в круглые скобки и вы пытаетесь выполнить операцию с результатами или вы пытаетесь запустить динамическое административное представление sys.dm_exec_query_stats, получены неверные результаты или ошибка.

Решение


Сведения о пакете обновления Чтобы устранить эту проблему, установите последнюю версию пакета обновления для SQL Server 2008. Дополнительные сведения см. в следующей статье базы знаний Майкрософт:
968382 Как получить последний пакет обновления для SQL Server 2008

Обходное решение


Чтобы обойти эти проблемы, необходимо удалить скобки из оператора, который следует за общим табличным выражением. Например, предположим, что используется следующий оператор WITH, использующий такие скобки.
WITH common_table_expression AS (SELECT *FROM sys.objects)(SELECT * FROM common_table_expression)
Чтобы решить эту проблему, перейдите к следующему оператору WITH, который не использует эти круглые скобки.
WITH common_table_expression AS (SELECT *FROM sys.objects)SELECT * FROM common_table_expressio

Статус


Корпорация Майкрософт подтвердила, что эта проблема связана с продуктами Майкрософт, которые перечислены в разделе "относится к". Впервые эта проблема была исправлена в SQL Server 2008 с пакетом обновления 2 (SP2).

Дополнительная информация


Для получения дополнительных сведений об использовании оператора WITH с общим табличным выражением посетите веб-страницу MSDN по следующему адресу:Для получения дополнительных сведений о sys.dm_exec_query_stats посетите веб-страницу MSDN по следующему адресу: