テーブルのインデックスを再構築しようとすると:
ALTER INDEX ALL ON [dbo].[Allocations] REBUILD
それはうまくいきます。
しかし、私が電話するとき
EXECUTE sp_msForEachTable 'ALTER INDEX ALL ON ? REBUILD'
同じテーブルに到達しましたが、次のように失敗します。
メッセージ1934、レベル16、状態1、行2
次のSETオプションの設定が正しくないため、ALTER INDEXが失敗しました: '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(''?'')'
動作します罰金!
引用符で囲まれた識別子の設定は、各ストアドプロシージャに対して保存され、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 SQLServerの将来のバージョンで削除される予定です。この機能を新しい開発作業で使用しないでください。また、現在この機能を使用しているアプリケーションをできるだけ早く変更してください。代わりに
ALTER INDEX
を使用してください。
SET QUOTED_IDENTIFIER ON
には適切な設定がないため、sp_msForEachTable
にもsp_msForEachTable
が必要です。
EXECUTE sp_msForEachTable 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON ? REBUILD;'
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