14

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

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

效果很好。

但是当我打电话

EXECUTE sp_msForEachTable 'ALTER INDEX ALL ON ? REBUILD'

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

消息 1934,级别 16,状态 1,第 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

4 回答 4

25

带引号的标识符设置针对每个存储过程进行存储,并将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

于 2012-10-01T14:01:29.167 回答
5

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

EXECUTE sp_msForEachTable 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON ? REBUILD;'
于 2012-10-01T13:57:10.500 回答
2

不要使用 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
于 2012-10-01T23:16:14.917 回答
0

代码示例中缺少下划线:

曾是

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

ELECT  @reindex = 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON '
                + @table + ' REBUILD;'
于 2020-04-28T15:34:02.730 回答