Статистические данные, ссылающиеся на столбец, предотвращают удаление этого столбца? - PullRequest
13 голосов
/ 31 октября 2011

Я пытаюсь сделать очень простое 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 не выполнен, так как один или несколько объектов имеют доступ к этому столбцу.

Я не думаю, что статистика предотвращает удаление столбца. Они? Если это так, поскольку это, по-видимому, автоматически созданные статистические данные, я не могу зависеть от одинаковых имен в нескольких копиях одной и той же базы данных, так как я могу отбросить всю такую ​​статистику в сценарии обновления, который будет выполняться в другой базе данных?

Ответы [ 2 ]

14 голосов
/ 26 октября 2012

Код, предложенный в ответе 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
7 голосов
/ 31 октября 2011

Все автоматически сгенерированные статистические данные, которые я видел, либо имеют имя индекса, который они представляют, либо начинаются с чего-то вроде 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 - курсор в фоновом режиме, но остальная часть логики вы можете сделать как набор.

...