使用动态sql(sp_executesql)删除和创建索引

使用动态sql(sp_executesql)删除和创建索引,sql,indexing,sql-server-2012,Sql,Indexing,Sql Server 2012,我有一个场景,我试图在30多个数据库上创建和维护索引,这些数据库定期从备份中恢复 我有以下存储过程: ALTER PROCEDURE Create_Index @DATABASE sysname AS BEGIN DECLARE @DROPFIRSTINDEX nvarchar(MAX) DECLARE @DROPSECONDINDEX nvarchar(MAX) DECLARE @CREATEFIRSTINDEX nvarchar(MAX) DE

我有一个场景,我试图在30多个数据库上创建和维护索引,这些数据库定期从备份中恢复

我有以下存储过程:

ALTER PROCEDURE Create_Index 
    @DATABASE sysname 

AS
BEGIN

    DECLARE @DROPFIRSTINDEX nvarchar(MAX)
    DECLARE @DROPSECONDINDEX nvarchar(MAX)
    DECLARE @CREATEFIRSTINDEX nvarchar(MAX)
    DECLARE @CREATESECONDINDEX nvarchar(MAX)


    SET @DROPFIRSTINDEX = 

    N'IF  EXISTS (SELECT * FROM ' + QUOTENAME(@DATABASE) + N'.[sys].[indexes] WHERE object_id = OBJECT_ID(N''' + QUOTENAME(@DATABASE) + N'.[dbo].[FirstTable]'') AND name = N''IX_FIRSTINDEX'')
    DROP INDEX [IX_FIRSTINDEX] ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[FirstTable] WITH ( ONLINE = OFF )'

    SET @DROPSECONDINDEX =

    N'IF  EXISTS (SELECT * FROM ' + QUOTENAME(@DATABASE) + N'.[sys].[indexes] WHERE object_id = OBJECT_ID(N''' + QUOTENAME(@DATABASE) + N'.[dbo].[SecondTable]'') AND name = N''IX_SECONDINDEX'')
    DROP INDEX [IX_SECONDINDEX] ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[SecondTable] WITH ( ONLINE = OFF )'

    SET @CREATEFIRSTINDEX = 

    N'CREATE NONCLUSTERED INDEX [IX_FIRSTINDEX] ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[FirstTable] 
    (
        [DateTime] ASC
    )WITH (STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF
         , IGNORE_DUP_KEY = OFF
         , DROP_EXISTING = OFF
         , ONLINE = OFF
         , ALLOW_ROW_LOCKS  = ON
         , ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]'

    SET @CREATESECONDINDEX =

    N'CREATE NONCLUSTERED INDEX [IX_SECONDINDEX]
    ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[SecondTable] ([CustomerID],[SessionID])
    INCLUDE ([Type])'

    EXEC sp_executesql @DROPFIRSTINDEX 

    EXEC sp_executesql @DROPSECONDINDEX 

    EXEC sp_executesql @CREATEFIRSTINDEX 

    EXEC sp_executesql @CREATESECONDINDEX 

    RETURN

END
GO
这样做很好,可以删除并重新创建索引,但是随着索引的增长,每次迭代的时间越来越长。 如果数据库已经包含适当的索引,是否有任何方法可以将其更改为跳过数据库?
我试着想出一种方法来做这件事,但还是画了一个空白。

您已经在检查索引是否存在,如果存在,就删除它。所以只要用IF-ELSE逻辑扩展它就行了

IF EXISTS...
   SET @FirstCommand='DROP INDEX...'
ELSE
   SET @FirstCommand='CREATE NONCLUSTERED INDEX...'

然后,您只需要为每个索引执行一个sp_executesql(而不是一次拖放和一次创建)。

我需要在动态sql中运行
IF EXISTS
,因为我必须指定许多数据库名称中的一个,如何在动态sql中运行它,但保持IF/ELSE结构?不久前我已经尝试过类似的方法,但我得到了一个错误:
索引'IX_FIRSTINDEX'在编译动态查询时已经存在?设置@FirstCommand=,如果存在。。。删除索引。。。否则创建非聚集索引…'如果它存在,我不想删除它,我只想创建它,如果它不存在。当然-发布以前的评论太快了。这实际上更简单:设置@FirstCommand=,如果不存在的话。。。创建非聚集索引…“当我再次尝试时,它起作用了,我以前肯定有语法问题,感谢您的时间。