2

sp_MSforeachtable を使用してすべてのテーブルにインデックスを追加するにはどうすればよいですか? エラーが発生し続けます。

EXEC sp_MSforeachtable @precommand = 'declare @idx as char;',
@command1 = '
set @idx = ''idx_'' + ? + ''_modified_on'';
print @idx;
IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''[dbo].[?]'') AND name = N''@idx'')
    DROP INDEX [@idx] ON [dbo].[?]

CREATE NONCLUSTERED INDEX [@idx] ON [dbo].[?] 
(
    [modified_on] ASC
) ON [PRIMARY]
'

そのようなエラーの 1 つ:

Msg 137, Level 15, State 1, Line 2
Must declare the scalar variable "@idx".

コマンド内に宣言を配置しようとしましたが、次のエラーが発生しました。

Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "dbo.DIAG_contractAuditHistory" could not be bound.

これは構文エラーを修正するための更新された試みであり、テスト SQL も同様ですが、それでも奇妙なエラーが発生しました。結局、ストアド プロシージャで問題を解決し、各テーブルのストアド プロシージャを呼び出しました。

EXEC sp_MSforeachtable @command1 = '
declare @idx as varchar(256);
set @idx = ''idx_'' + SUBSTRING(''?'', 8, len(''?'')-8) + ''_modified_on'';
print @idx;
IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''?'') AND name = @idx   )
    DROP INDEX [@idx] ON ?

IF EXISTS (select * from sys.columns where object_id = OBJECT_ID(N''?'') and name = ''modified_on'')
    CREATE NONCLUSTERED INDEX [@idx] ON ?
    (
        [modified_on] ASC
    ) ON [PRIMARY]
'

declare @cat as char;
set @cat='dog';
print @cat;

EXEC sp_MSforeachtable 'print ''idx_'' + SUBSTRING(''?'', 8, len(''?'')-8) + ''_modified_on'';'
EXEC sp_MSforeachtable 'print ''?'''
print substring('[dbo].[merchantNotes]', 8, (len('[dbo].[merchantNotes]')-9))

select * from sys.columns where object_id = OBJECT_ID(N'[dbo].[banks]') and name = 'modified_on'
SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'contractPaymentHistory') AND name = 'idx_contractPaymentHistory_modified_on'

これは約2ダースのテーブルで機能しますが、次のような奇妙なエラーが発生します

メッセージ 1934、レベル 16、状態 1、行 9 次の SET オプションの設定が正しくないため、CREATE INDEX が失敗しました: 'QUOTED_IDENTIFIER'。計算列のインデックス付きビューやインデックス、フィルター選択されたインデックス、クエリ通知、XML データ型メソッド、空間インデックス操作で使用する SET オプションが正しいことを確認します。

そこで、別の戦略を使用することになり、ストアド プロシージャを作成してインデックスを作成しました。ストアド プロシージャ内でインデックスを作成するにはどうすればよいですか?

4

2 に答える 2

1

コマンドで idx を宣言できます。他の構文エラーもあります。投票。あなたのエラーは、declare ステートメントとは関係ありません。それは使い方が?間違っているからです。sp_msforeachtable簡単な交換を行います。したがって、使用するには、それを引用する必要があります(または、外側の文字列を引用解除しないでください.

なぜこれがまだ機能しないのかについては、他の質問に対する私の回答を参照してください。

フリーハンドで修正したようなバージョンを次に示します。

EXEC sp_MSforeachtable
@command1 = '
declare @idx nvarchar(1000);
declare @tbl nvarchar(1000);
set @tbl = replace(''?'', ''[dbo].'', '''');
set @tbl = left(@tbl, len(@tbl) - 1);
set @idx = ''idx_'' + @tbl + ''_modified_on'';
print @idx;
IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''?'') AND name = N''@idx'')
    DROP INDEX [@idx] ON ?;
declare @sql nvarchar(1000);
set @sql = ''
CREATE NONCLUSTERED INDEX ['' + @idx + ''] ON ? 
(
    [modified_on] ASC
) ON [PRIMARY]'';
exec sp_executesql @sql;
';

なぜこんなことをするのかと問うべきです。そのフィールドだけのインデックス作成は、あなたが思っているほど良くはありません。インデックスのカバーについて読んでください。

于 2013-06-21T19:45:08.917 に答える