SQL Server, если еще индексированное представление

В SQL Server 2012 я хотел бы запустить запрос, который проверяет, существует ли индексированное представление. Если это так, я хочу запустить оператор SELECT WITH(NOEXPAND). Если это не так, я хотел бы запустить оператор выбора без расширения. Ниже приведен код, который я использую:

DECLARE @x int

IF NOT EXISTS (SELECT * FROM sys.indexes
               WHERE object_id = OBJECT_ID('test'))
    SET @x = 0
ELSE
    SET @x = 1

IF(@x = 1)
    SELECT category, _TimeStamp 
    FROM test WITH (NOEXPAND) 
    WHERE _TimeStamp >= '2018-01-24 00:00:00' 
      AND _TimeStamp < DATEADD(hh, +24, '2018-01-24 00:00:00') 
    ORDER BY _TimeStamp ASC

ELSE 
    SELECT category, _TimeStamp 
    FROM test
    WHERE _TimeStamp >= '2018-01-24 00:00:00' 
      AND _TimeStamp < DATEADD(hh, +24, '2018-01-24 00:00:00') 
    ORDER BY _TimeStamp ASC

При выполнении этого запроса в базе данных нет индексированного представления для этой таблицы, и я получаю следующую ошибку:

Сообщение 8171, уровень 16, состояние 2, строка 13
Подсказка "noexpand" для объекта "test" недействительна.

У меня есть другая таблица с индексированным представлением, и если я запускаю тот же запрос в этой таблице (с небольшими изменениями, такими как имя таблицы), он работает нормально. Мне интересно, почему SQL Server жалуется на NOEXPAND, когда индексированное представление не существует, вместо того, чтобы запускать оператор в части Else.

Как еще я мог это реализовать?


РЕДАКТИРОВАТЬ: изменен код для использования exec() :

IF NOT EXISTS(
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('test'))

exec('SELECT category, _TimeStamp FROM test
WITH (NOEXPAND) Where _TimeStamp >= 2018-01-24 00:00:00 and _TimeStamp < DATEADD(hh, +24, 2018-01-24 00:00:00) ORDER BY _TimeStamp ASC')

Else 
SELECT cartegory, _TimeStamp FROM test
WHERE _TimeStamp >= '2018-01-24 00:00:00' and _TimeStamp < DATEADD(hh, +24, '2018-01-24 00:00:00') ORDER BY _TimeStamp ASC

_TimeStamp имеет формат даты и времени.

Получено следующее сообщение об ошибке:

Сообщение 102, уровень 15, состояние 1, строка 2 Неверный синтаксис рядом с «00».


person Dixie    schedule 17.04.2018    source источник
comment
Просто комментарий - для улучшения производительности измените IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('test')) на IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID('test')) - нет необходимости выбирать '*', когда вы выполняете проверку существования   -  person Daniel Marcus    schedule 17.04.2018


Ответы (1)


Планировщик запросов анализирует весь запрос перед его выполнением. Он пометит noexpand в представлении как недопустимый, даже если он находится в ветви предложения if, которое никогда не выполняется.

Вы можете решить это с помощью exec, который работает в отдельной области:

IF(@x = 1)
    exec (N'SELECT category, _TimeStamp 
            FROM test WITH (NOEXPAND) 
            ...')
else
    SELECT category, _TimeStamp 
    FROM test
    ...
person Andomar    schedule 17.04.2018
comment
Спасибо! Это помогло. Дополнительный вопрос: теперь у меня есть категория SELECT, _TimeStamp FROM test WHERE _TimeStamp ›= '2018-01-24 00:00:00' и _TimeStamp ‹ DATEADD(hh, +24, '2018-01-24 00:00 :00') ORDER BY _TimeStamp ASC... в остальной части моего запроса. SQL жалуется на время сейчас. Неправильный синтаксис рядом с «00» - person Dixie; 19.04.2018
comment
Почему бы не задать новый вопрос вместо добавления несвязанного вопроса к старому вопросу? Во всяком случае, дата в exec отсутствует в кавычках. Вы можете добавлять кавычки к строке, повторяя их, то есть две одинарные кавычки, как в ''2018-01-24 00:00:00'' - person Andomar; 19.04.2018