Sql server 从sp_msForEachTable运行时,由于引用了_标识符,ALTER INDEX失败
当我尝试在表上重建索引时:Sql server 从sp_msForEachTable运行时,由于引用了_标识符,ALTER INDEX失败,sql-server,sql-server-2008-r2,reindex,sp-msforeachtable,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,第16级,状态1,第2行 ALTER INDEX失败,因为以下集合选项的设置不正确:“QUOTED_IDENTIFIER”。验证集合选项是否正确用于索引视图和/或计算列上的索引和/
ALTER INDEX ALL ON [dbo].[Allocations] REBUILD
那很好
但是当我打电话的时候
EXECUTE sp_msForEachTable 'ALTER INDEX ALL ON ? REBUILD'
我到达了同一张表,但它失败了:
Msg 1934,第16级,状态1,第2行ALTER INDEX失败,因为以下集合选项的设置不正确:“QUOTED_IDENTIFIER”。验证集合选项是否正确用于索引视图和/或计算列上的索引和/或筛选索引和/或查询通知和/或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(''?'')'
很好您还需要
sp\u msForEachTable
中的设置带引号的\u标识符,因为sp\u msForEachTable
没有正确的设置
EXECUTE sp_msForEachTable 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON ? REBUILD;'
引用的标识符设置针对每个存储过程存储,并且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
设置,并用于该存储过程的后续调用
当然,插入关于spmsforeachtable
未记录的常见警告,因此您不能依赖它的任何行为是稳定的
因为-所有的赌注都输掉了DBCC
生活在它自己小小的、非常定制的代码世界中。但是,当然,未来的工作也不应该依赖它:
此功能将在Microsoft SQL Server的未来版本中删除。请勿在新的开发工作中使用此功能,请尽快修改当前使用此功能的应用程序。改用
不要使用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
代码示例中缺少下划线:
是
ELECT @reindex = 'SET QUOTED IDENTIFIER ON; ALTER INDEX ALL ON '
+ @table + ' REBUILD;'
ELECT @reindex = 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON '
+ @table + ' REBUILD;'
是
ELECT @reindex = 'SET QUOTED IDENTIFIER ON; ALTER INDEX ALL ON '
+ @table + ' REBUILD;'
ELECT @reindex = 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON '
+ @table + ' REBUILD;'
如果会话默认设置没有正确的设置,您可能会认为直接的ALTER INDEX
调用也会失败。“我没有做错什么?”-这个问题可能有很多答案:-)这就是我在使用ALTER INDEX
时发现“bug”的原因;我使用的是DBCC
很好,我想切换到“首选”语法会让我的生活更痛苦。如果你给sql创建一个等价的sp_forEachTable
,会更酷,而且会更有用。然后我会把它放到我接触的每一个数据库里,这真的是一个等价物。您可以将其转换为存储过程,添加数据库名称和命令作为参数,然后在需要时调用它。