2011-12-28 19 views
5

Tôi đang làm việc trong SQL Server 2008 R2 và tôi đã viết một thủ tục được lưu trữ thêm ràng buộc vào một số cột trong một số bảng trong cơ sở dữ liệu của tôi. Tuy nhiên, tôi thấy rằng các thủ tục được lưu trữ không thành công vì nó không thể đặt một cột cụ thể làm khóa chính do một chỉ mục trên cột. Đây là trường hợp của nhiều cột trong các bảng khác nhau.Làm thế nào tôi có thể ALTER COLUMN để NOT NULL khi cột được lập chỉ mục

Có cách nào để ALTER COLUMN thành NOT NULL không và đặt nó làm khóa CHÍNH mà không xóa chỉ mục? Nếu không, có cách nào tốt để vô hiệu hóa hoặc xóa chỉ mục sau đó bật hoặc tạo lại chỉ mục sau câu lệnh ALTER COLUMN?

+1

Bạn phải thả và tạo lại chỉ mục. Bạn có thể viết cả hai hành động bằng cách nhấp chuột phải vào chỉ mục trong SSMS và sau đó "Chỉ mục tập lệnh là" – Andomar

+0

@Andomar - Cảm ơn bạn đã trả lời. Có thể thực hiện điều này một cách năng động trong quy trình được lưu trữ không? Như tôi đã đề cập, điều này xảy ra với nhiều cột trong nhiều bảng. Có anyway để programatically kiểm tra cho một chỉ số trên lĩnh vực này trước khi thay đổi nó, thả chỉ số, và tạo lại nó afterword? – Brian

+1

Bài đăng trên blog này sẽ giúp bạn bắt đầu: http://blog.sqlauthority.com/2009/07/23/sql-server-puzzle-write-script-to-generate-primary-key-and-foreign-key/ – Andomar

Trả lời

2

Cảm ơn tất cả các nhận xét của bạn. Sau một số nghiên cứu, tôi đã có thể xác định cách thực hiện điều này bằng cách sử dụng các bảng chính xác được đề cập bởi @mwigdahl. Xem mã bên dưới:

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ôi đã sử dụng chức năng Script Index As trong SSMS để xem chỉ mục sẽ được tạo ra như thế nào trong T-SQL.

Sau đó, tôi truy vấn các bảng sys.indexessys.index_columns để xác định thuộc tính nào có sẵn.

Mã hiển thị truy vấn đối với các bảng đó lưu các thuộc tính đó vào biến và sau đó thả và tạo lại chỉ mục. Có một số tùy chọn không có sẵn trong những bảng mà tôi đã phải viết mã cứng. Có ai biết nếu những OPTIONS có sẵn ở đâu đó trong một bảng hệ thống?

Tôi hy vọng điều này sẽ giúp người khác trong tương lai.

Các vấn đề liên quan