#sql-server #tsql #ssms
#sql-server #tsql #ssms
Вопрос:
Мой план обслуживания содержит эти инструкции T-SQL:
IF NOT EXISTS(
SELECT *
FROM sys.indexes
WHERE name='_Document415_Fld13294_Fld13301' AND object_id = OBJECT_ID('my_db.dbo._Document415')
) BEGIN
create index [_Document415_Fld13294_Fld13301] on my_db.[dbo].[_Document415] ([_Fld13294RRef],[_Fld13301RRef])
END
но я получаю эту ошибку:
Индекс [_Document415_Fld13294_Fld13301] уже существует
Похоже IF NOT EXISTS
, что он не работает при использовании в плане обслуживания (потому что в простом запросе он работает просто отлично — без ошибок).
Ответ №1:
Этот точный пакет должен везде выдавать ошибку. Не рассматривайте только часть пакета (например IF NOT EXISTS
, изолированно.
Почему это ошибка? Потому что ошибка, которую вы видите, является ошибкой компиляции.
Почему проверка во время выполнения не защищает вас от ошибки компиляции? По той же причине это не поможет на большинстве языков 1. Компиляция предшествует выполнению.
Вам необходимо запретить компиляцию внутреннего оператора до завершения проверки во время выполнения. Это проще всего сделать, переместив его в EXEC sp_executesql
:
IF NOT EXISTS(
SELECT *
FROM sys.indexes
WHERE name='_Document415_Fld13294_Fld13301' AND object_id = OBJECT_ID('my_db.dbo._Document415')
)
BEGIN
EXEC sp_executesql N'create index [_Document415_Fld13294_Fld13301] on my_db.[dbo].[_Document415] ([_Fld13294RRef],[_Fld13301RRef])'
END
1 Предполагается, что язык используется с компилятором, и компиляция не происходит на уровне оператора.
Комментарии:
1. Спасибо за ваш ответ! У меня нет опыта работы с компилируемыми языками (как вы можете видеть). 🙁 И, к сожалению, не повезло
EXEC sp_executesql
. Получил ту же ошибку после изменения инструкции T-SQL, как вы предложили.2. Я что-то еще упускаю?