2011-12-28 1 views
5

SQL Server 2008 R2で作業していて、データベース内の複数の表のいくつかの列に制約を追加するストアドプロシージャを作成しました。しかし、列のインデックスのために特定の列を主キーとして設定できないため、ストアドプロシージャが失敗することがわかりました。これは、さまざまな表の多くの列の場合です。列がインデックス付けされているときに列を変更するときに列を変更しないでください。

ALTER COLUMNをNOT NULLに設定し、インデックスを削除せずにPRIMARY KEYとして設定する方法はありますか?それ以外の場合は、索引を使用不可にするか、索引を削除してからALTER COLUMN文の後で索引を有効または再作成するとよいでしょうか?

+1

インデックスを削除して再作成する必要があります。 SSMSのインデックスを右クリックし、「スクリプトインデックス」を – Andomar

+0

@Andomarで実行すると、両方のアクションをスクリプトできます。お返事ありがとうございます。ストアドプロシージャでこれを動的に行うことは可能ですか?前述したように、これは多くの表の多くの列で発生します。とにかくフィールドを変更する前に、インデックスをプログラムでチェックし、インデックスを削除して、それを後で再作成しますか? – Brian

+1

このブログの投稿は、あなたが開始する必要があります:http://blog.sqlauthority.com/2009/07/23/sql-server-puzzle-write-script-to-generate-primary-key-and-foreign-key/ – Andomar

答えて

2

ご意見ありがとうございます。いくつかの調査の後、私は@mwigdahlで述べた正確なテーブルを使って動的にこれを行う方法を決定することができました。以下のコードを参照してください:

DECLARE @indexName nvarchar(254), 
    @tableName nvarchar(254), 
    @indexType nvarchar(254), 
    @columnName nvarchar(254), 
    @isPadded integer, 
    @ignore_dup_key integer, 
    @allow_row_locks integer, 
    @allow_page_locks integer, 
    @fillFactor integer 

SELECT 
    @indexName = i.name, 
    @tableName = o.name, 
    @indexType = i.type_desc, 
    @columnName = co.[name], 
    @isPadded = i.is_padded, 
    @ignore_dup_key = i.[ignore_dup_key], 
    @allow_row_locks = i.[allow_row_locks], 
    @allow_page_locks = i.[allow_page_locks], 
    @fillFactor = i.fill_factor 
FROM sys.indexes AS i 
    INNER JOIN sys.objects AS o ON i.object_id = o.object_id 
    INNER JOIN sys.index_columns ic on ic.object_id = i.object_id AND ic.index_id = i.index_id 
    INNER JOIN sys.columns co on co.object_id = i.object_id AND co.column_id = ic.column_id 
WHERE 
    i.[type] = 2 AND 
    o.[type] = 'U' 

DECLARE @sql varchar(max) 

SET @sql = 'DROP INDEX [' + @indexName + '] ON [' + @tableName + ']' 

EXEC (@sql) 

PRINT 'Dropped Index' 

-- Do work here 

DECLARE @pad_index nvarchar(3), 
    @ignore_dup nvarchar(3), 
    @row_locks nvarchar(3), 
    @page_locks nvarchar(3) 

IF @isPadded = 0 SET @pad_index = 'OFF' 
ELSE SET @pad_index = 'ON' 

IF @ignore_dup_key = 0 SET @ignore_dup = 'OFF' 
ELSE SET @ignore_dup = 'ON' 

IF @allow_row_locks = 0 SET @row_locks = 'OFF' 
ELSE SET @row_locks = 'ON' 

IF @allow_page_locks = 0 SET @page_locks = 'OFF' 
ELSE SET @page_locks = 'ON' 

SET @sql = 'CREATE ' + @indexType + ' INDEX [' + @indexName + '] ON [' + @tableName + ']' + 
    '(' + 
    '[' + @columnName + '] ASC' + 
    ') WITH (' + 
    'PAD_INDEX = ' + @pad_index + ',' + 
    'STATISTICS_NORECOMPUTE = OFF,' + 
    'SORT_IN_TEMPDB = OFF,' + 
    'IGNORE_DUP_KEY = ' + @ignore_dup + ',' + 
    'DROP_EXISTING = OFF,' + 
    'ONLINE = OFF,' + 
    'ALLOW_ROW_LOCKS = ' + @row_locks + ',' + 
    'ALLOW_PAGE_LOCKS = ' + @page_locks + ',' + 
    'FILLFACTOR = ' + CONVERT(nvarchar(100),@fillFactor) + ')' + 
    'ON [PRIMARY]' 

PRINT @sql 

EXEC (@sql) 

PRINT 'Created Index' 

を、私は、インデックスがT-SQLで作成される方法を確認するためにSSMSでScript Index As機能を使用していました。

次に、sys.indexessys.index_columnsテーブルを照会して、利用可能なプロパティを確認しました。

コードは、これらのプロパティを変数に保存してからインデックスを削除して再作成するテーブルに対してクエリを表示します。これらの表では使用できないオプションがいくつかありましたが、ハードコードする必要がありました。これらのオプションがシステムテーブルのどこかで利用可能かどうかは誰にも分かりますか?

私はこれが将来他の誰かに役立つことを願っています。

関連する問題