2011-10-31 24 views
10

Tôi đang cố gắng một drop column tuyên bố rất đơn giản:Số liệu thống kê tham chiếu một cột có ngăn không cho cột đó bị loại bỏ không?

alter table MyTable drop column MyColumn 

và nhận một số lỗi dọc theo dòng của

Msg 5074, Level 16, State 1, Line 1
_dta_stat_1268251623_3_2 Số liệu thống kê' 'phụ thuộc vào cột' MyColumn '.

sau đó cuối cùng bởi

Msg 4922, Level 16, State 9, Line 1
ALTER TABLE DROP COLUMN MyColumn thất bại vì một hoặc nhiều đối tượng truy cập vào cột này.

Tôi không nghĩ rằng thống kê ngăn không cho cột bị giảm. Họ có? Nếu vậy, vì đây rõ ràng là các thống kê được tạo tự động, tôi không thể phụ thuộc vào các tên giống nhau trên nhiều bản sao của cùng một cơ sở dữ liệu, vậy làm thế nào tôi có thể thả tất cả các số liệu thống kê trong kịch bản nâng cấp được thực thi trên cơ sở dữ liệu khác?

Trả lời

7

Số liệu thống kê được tạo tự động mà tôi đã thấy tất cả đều có tên của chỉ mục mà chúng đại diện hoặc bắt đầu bằng một cái gì đó như WA_Sys_.

Bạn có chắc chắn 100% đây không phải là bộ số liệu thống kê tùy chỉnh mà ai đó đã thiết lập không?

Kiểm tra này:

select * 
FROM sys.stats WHERE name = '_dta_stat_1268251623_3_2' 

... và xem những gì lĩnh vực user_created chỉ ra.

mỗi bình luận:

này chưa được kiểm chứng nhưng bạn có thể thử một cái gì đó như:

exec sp_MSforeachdb ' 
use ? 

DECLARE @SQL varchar(max) = '''' 

select @SQL = @SQL + ''DROP STATISTICS '' + OBJECT_NAME(c.object_id) + ''.'' + s.name + CHAR(10) + CHAR(13) 
from sys.stats s 
INNER JOIN sys.stats_columns sc 
ON sc.stats_id = s.stats_id 
INNER JOIN sys.columns c 
ON c.column_id = sc.column_id 
WHERE c.name = ''ClaimNbr'' 
--and s.user_created = 1 

PRINT @SQL' 

Thay đổi PRINT một EXEC nếu nó có vẻ tốt.

sp_msforeachdb là con trỏ ở chế độ nền nhưng phần còn lại của logic bạn có thể thực hiện làm bộ.

+0

Bạn nói đúng! Tôi tin rằng những điều này đã được tạo ra bởi Database Engine Tuning Advisor. Bạn có thể đề xuất một cách để xóa tất cả các thống kê do người dùng tạo tham chiếu đến một cột không? – Daniel

+0

Bạn có thể sử dụng các khung nhìn hệ thống khác 'sys.stats_columns' và' sys.columns' để lấy/JOIN thông tin đó. – JNK

+0

Aye, tôi phải dùng đến con trỏ cũ để thả chúng. Cảm ơn. – Daniel

12

Mã được đề xuất trong câu trả lời JNK không hoạt động, nhưng ý tưởng là tốt. Nếu bạn muốn xóa tất cả thống kê do người dùng tạo, giải pháp đã kiểm tra của tôi:

DECLARE @sql NVARCHAR(MAX) 

DECLARE statCursor CURSOR FOR 
SELECT 
    'DROP STATISTICS ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) 
         + '.' + QUOTENAME(t.name) 
         + '.' + QUOTENAME(st.name) AS sql 
FROM 
    sys.stats AS st 
    INNER JOIN sys.tables AS t 
     ON st.object_id = t.object_id 
WHERE 
    st.user_created = 1 
ORDER BY 1; 

OPEN statCursor; 

FETCH NEXT FROM statCursor INTO @sql 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    PRINT @sql 
    EXEC sp_executesql @sql 
    FETCH NEXT FROM statCursor INTO @sql 
END 
CLOSE statCursor 
DEALLOCATE statCursor 
+0

bạn thực sự là câu trả lời đúng JNK không hoạt động ở tất cả trên máy chủ sql 2008 (truy vấn không bao giờ kết thúc) chuyển ví dụ của bạn để sử dụng sys.columns – Harrison

+0

Cách hạn chế điều này bởi cơ sở dữ liệu không phải tất cả cơ sở dữ liệu – MonsterMMORPG

+0

Truy vấn chỉ áp dụng cho cơ sở dữ liệu hiện tại – psadac

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