Introdução
Recentemente, durante uma atualização de um aplicativo, recebi a seguinte mensagem de erro:
Msg 5074 Level 16 State 1 Line 1 The statistics 'BreakingStuff' is dependent on column 'TaskText'. Msg 4922 Level 16 State 9 Line 1 ALTER TABLE ALTER COLUMN TaskText failed because one or more objects access this column.
Exemplo de mensagem de erro baseada em análise
Esta foi uma estatística criada manualmente em uma coluna de uma tabela. Na verdade, havia várias estatísticas criadas manualmente referenciando a coluna em questão.
Gambiarra
Depois de descartar as estatísticas da tabela, executar a atualização e recriar as estatísticas, tudo estava funcionando bem.
Análise
Comecei com uma simulação trivial em db<>fiddle para ver se conseguia reproduzir o problema. Depois de alguns ajustes (trocadilhos), descobri que a mensagem de erro só é acionada se eu reduzir o tamanho da coluna.
por exemplo varchar(50)
-->varchar (40)
Aqui está o db<>fiddle .
Os únicos avisos que encontrei no Microsoft Learn foram:
-
Modificar o tipo de dados de uma coluna que já contém dados pode resultar na perda permanente de dados quando os dados existentes são convertidos para o novo tipo. Além disso, o código e os aplicativos que dependem da coluna modificada podem falhar. Isso inclui consultas, visualizações, procedimentos armazenados, funções definidas pelo usuário e aplicativos cliente. Observe que essas falhas ocorrerão em cascata. Por exemplo, um procedimento armazenado que chama uma função definida pelo usuário que depende da coluna modificada pode falhar. Considere cuidadosamente quaisquer alterações que você deseja fazer em uma coluna antes de fazê-la.
Referência: Modificar colunas (Microsoft Learn | SQL)
Eu estava ciente de que reduzir o tamanho da coluna possivelmente resultaria em perda de dados, mas não foi o caso, pois os dados eram todos menores que varchar(40)
.
Questões
- Por que reduzir o tamanho da coluna resulta em erro devido às estatísticas criadas manualmente?
- Por que aumentar o tamanho de uma coluna não resulta em erro nas estatísticas criadas manualmente?
O SQL Server 2022 tem uma nova opção ao criar estatísticas que podem automatizar isso conforme a documentação (ênfase minha):
Colunas que possuem estatísticas anexadas criadas manualmente não podem ter suas propriedades modificadas sem primeiro eliminar o objeto de estatísticas – isso é para garantir que o objeto de estatísticas reflita com precisão o conteúdo da coluna. Quando uma coluna de estatísticas criada manualmente é detectada, o SQL Server retorna uma mensagem de erro informando “ALTER TABLE ALTER COLUMN falhou porque um ou mais objetos acessam esta coluna”.
Escrevi um post sobre isso aqui
Curiosamente, se o SQL Server tiver criado automaticamente um objeto de estatísticas em uma coluna e você modificar posteriormente essa coluna, você não receberá esse erro. O SQL Server descarta silenciosamente o objeto de estatísticas e modifica a coluna. O objeto de estatísticas criado automaticamente não é recriado automaticamente até que seja executada uma consulta que precise do objeto de estatísticas.
Aumentar o tamanho da coluna é uma operação somente de metadados que na verdade não altera nenhum dos dados existentes, portanto, o objeto stats ainda é válido.
Diminuir o tamanho de uma coluna pode significar que os valores serão truncados, o que pode invalidar as estatísticas.