首页 > 解决方案 > 为什么“如果不存在”在维护计划中不起作用?

问题描述

我的维护计划包含以下 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不起作用(因为在简单的查询中它工作得很好 - 没有错误)。

标签: sql-servertsqlssms

解决方案


那个确切的批次应该到处出错。不要只考虑批次的一部分(例如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假设该语言与编译器一起使用并且编译不会发生在语句级别。


推荐阅读