2011-10-31 53 views
10

我想一个很简单的drop column声明:引用列的统计信息是否防止该列被丢弃?

alter table MyTable drop column MyColumn 

和接收几个错误沿

消息5074,级别16,状态1,第1行的行
统计“_dta_stat_1268251623_3_2 '依赖于'MyColumn'列。

最终其次是

消息4922,级别16,状态9,1号线
ALTER TABLE DROP COLUMN MyColumn失败,因为一个或多个对象访问此列。

我不认为统计数据会阻止列被丢弃。他们呢?如果是这样,因为这些显然是自动创建的统计信息,所以我不能依赖同一数据库的多个副本中的名称是相同的,那么如何将所有这些统计信息放在升级脚本中以便在不同的数据库上执行?

回答

7

我所看到的自动生成的统计信息都有它们代表的索引的名称,或者以WA_Sys_之类的内容开头。

您是否100%确定这不是某个人设置的自定义统计集?

检查:

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

...并看看有什么user_created字段表示。

根据注释:

这是未经测试,但你可以尝试这样的:

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' 

更改PRINT如果它看起来不错的EXEC

sp_msforeachdb是一个游标在后台,但其余的逻辑,你可以做一组。

+0

你说得对!我相信这些是由数据库引擎优化顾问创建的。您能否推荐一种方法来删除所有引用列的用户创建的统计信息? – Daniel

+0

您可以使用其他系统视图'sys.stats_columns'和'sys.columns'来获取/ JOIN该信息。 – JNK

+0

是的,我必须诉诸老旧的光标放下它们。谢谢。 – Daniel

12

在JNK答案中提出的代码不起作用,但这个想法很好。如果你想删除所有用户创建的统计数据,我测试过的解决方案如下:

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

你确实是正确的JNK答案没有工作完全在SQL Server 2008上(查询从未完成)切换您的示例以使用sys.columns – Harrison

+0

如何限制数据库而不是所有数据库 – MonsterMMORPG

+0

该查询仅适用于当前数据库 – psadac

相关问题