我正在尝试一个非常简单的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失败,因为一个或多个对象访问此列。
我认为统计数据不会阻止列被删除。他们呢?如果是这样,因为这些显然是自动创建的统计信息,我不能依赖于同一数据库的多个副本中的名称相同,那么我怎样才能在升级脚本中删除所有这些统计信息以在不同的数据库上执行?
答案 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
是后台的游标,但你可以将其余的逻辑作为一组来完成。