引用列的统计信息是否会阻止该列被删除?

时间:2011-10-31 16:31:03

标签: sql-server sql-server-2005 ddl

我正在尝试一个非常简单的drop column语句:

alter table MyTable drop column MyColumn

并接受

的几个错误
  

Msg 5074,Level 16,State 1,Line 1
  统计信息'_dta_stat_1268251623_3_2'取决于“MyColumn”列。

最后是

  

Msg 4922,Level 16,State 9,Line 1   ALTER TABLE DROP COLUMN MyColumn失败,因为一个或多个对象访问此列。

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

2 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分: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是后台的游标,但你可以将其余的逻辑作为一组来完成。