当我尝试在表上重建索引时:
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(''?'')'
很好!
答案 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 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;'