从sp_msForEachTable运行时,由于QUOTED_IDENTIFIER,ALTER INDEX失败

时间:2012-10-01 13:53:53

标签: sql-server sql-server-2008-r2 reindex sp-msforeachtable

当我尝试在表上重建索引时:

ALTER INDEX ALL ON [dbo].[Allocations] REBUILD

工作正常。

但是当我打电话时

EXECUTE sp_msForEachTable 'ALTER INDEX ALL ON ? REBUILD'

我到达同一张桌子,它失败了:

  

Msg 1934,Level 16,State 1,Line 2
  ALTER INDEX失败,因为以下SET选项的设置不正确:'QUOTED_IDENTIFIER'。验证SET选项是否正确,以便与计算列和/或筛选索引和/或查询通知和/或XML数据类型方法和/或空间索引操作的索引视图和/或索引一起使用。


并确认它是同一张表:

EXECUTE sp_msForEachTable 'print ''Rebuilding ?'';
ALTER INDEX ALL ON ? REBUILD;
PRINT ''   Done ?'''

给出了结果:

Rebuilding [dbo].[SystemConfiguration]
   Done [dbo].[SystemConfiguration]
Rebuilding [dbo].[UserGroups]
   Done [dbo].[UserGroups]
Rebuilding [dbo].[Groups]
   Done [dbo].[Groups]
Rebuilding [dbo].[UserPermissions]
   Done [dbo].[UserPermissions]
Rebuilding [dbo].[AllocationAdmins]
   Done [dbo].[AllocationAdmins]
Rebuilding [dbo].[Allocations]
Msg 1934, Level 16, State 1, Line 2
ALTER INDEX failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.

我做错了什么?


注意

EXECUTE sp_msForEachTable 'DBCC DBREINDEX(''?'')' 

很好!

4 个答案:

答案 0 :(得分:21)

针对每个存储过程存储带引号的标识符设置,sp_MSforeachtable将其定义为OFF。但是,您可以解决此问题 - 在执行重新索引之前将其设置为ON

create table dbo.T (
    ID int not null,
    constraint PK_T PRIMARY KEY (ID)
)
go
create view dbo.V ( ID)
with schemabinding
as
    select ID from dbo.T
go
create unique clustered index IX_V on dbo.V(ID)
go
ALTER INDEX ALL ON dbo.V REBUILD --Fine
go
exec sp_MSforeachtable  'ALTER INDEX ALL ON ? REBUILD' --Errors
go
exec sp_MSforeachtable  'SET QUOTED_IDENTIFIER ON;
ALTER INDEX ALL ON ? REBUILD' --Fine

SET QUOTED_IDENTIFIER

  

创建存储过程时,将捕获SET QUOTED_IDENTIFIERSET ANSI_NULLS设置,并将其用于后续调用该存储过程。


当然,插入关于sp_MSforeachtable未记录的常见警告,因此您不能依赖其任何稳定的行为。


对于DBCC DBREINDEX - 所有投注都已关闭。 DBCC生活在自己的小型,非常定制的代码世界中。但是,当然,它不应该依赖于未来的工作:

  

此功能将在Microsoft SQL Server的未来版本中删除。请勿在新的开发工作中使用此功能,并尽快修改当前使用此功能的应用程序。请改用ALTER INDEX

答案 1 :(得分:4)

您也需要SET QUOTED_IDENTIFIER ON中的sp_msForEachTable,因为sp_msForEachTable没有正确的设置。

EXECUTE sp_msForEachTable 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON ? REBUILD;'

答案 2 :(得分:1)

不要使用sp_msforeachtable。它已被记录为错过对象。使用sys.tables迭代表列表会好得多。

DECLARE @id INT ,
    @table NVARCHAR(256) ,
    @reindex NVARCHAR(4000)
SELECT  @id = MIN(object_id)
FROM    sys.tables
WHILE @id IS NOT NULL 
    BEGIN
        SELECT  @table = QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
        FROM    sys.tables t
                INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
        WHERE   t.object_id = @id

        SELECT  @reindex = 'SET QUOTED IDENTIFIER ON; ALTER INDEX ALL ON '
                + @table + ' REBUILD;'
        PRINT @reindex --prints the reindex command
        --EXEC @reindex --uncomment to actually reindex

        SELECT  @id = MIN(object_id)
        FROM    sys.tables
        WHERE   object_id > @id
   END

例如:

CREATE PROCEDURE dbo.sp_ForEachTable @query varchar(8000) AS

  --todo

答案 3 :(得分:0)

在代码示例中缺少下划线:

WAS

ELECT  @reindex = 'SET QUOTED IDENTIFIER ON; ALTER INDEX ALL ON '
                + @table + ' REBUILD;'

IS

ELECT  @reindex = 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON '
                + @table + ' REBUILD;'