TL; DR: Tengo una corrupción no reparable en una vista indizada. Aquí están los detalles:
Corriendo
DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS
en una de mis bases de datos produce el siguiente error:
Mensaje 8907, Nivel 16, Estado 1, Línea 1 El índice espacial, el índice XML o la vista indizada 'ViewName' (ID de objeto 784109934) contiene filas que no fueron producidas por la definición de la vista. Esto no representa necesariamente un problema de integridad con los datos en esta base de datos. (...)
CHECKDB encontró 0 errores de asignación y 1 errores de coherencia en la tabla 'ViewName'.
repair_rebuild es el nivel mínimo de reparación (...).
Entiendo que este mensaje indica que los datos materializados de la vista indexada 'ViewName' no son idénticos a los que produce la consulta subyacente. Sin embargo, la verificación manual de los datos no genera ninguna discrepancia:
SELECT * FROM ViewName WITH (NOEXPAND)
EXCEPT
SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...
SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...
EXCEPT
SELECT * FROM ViewName WITH (NOEXPAND)
NOEXPAND
se usó para forzar el uso del (único) índice en ViewName
. FORCESCAN
se usó para evitar que ocurriera coincidencia de vista indexada. El plan de ejecución confirma que ambas medidas están funcionando.
Aquí no se devuelven filas, lo que significa que las dos tablas son idénticas. (Solo hay columnas enteras y guid, las colaciones no entran en juego).
El error no se puede solucionar recreando el índice en la vista o ejecutando DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS
. Repetir las correcciones tampoco ayudó. ¿Por qué DBCC CHECKDB
informa este error? Cómo deshacerse de él?
(Incluso si la reconstrucción lo solucionaba, mi pregunta seguiría en pie: ¿por qué se informa un error aunque mis consultas de verificación de datos se ejecutan correctamente?)
Actualización: el error se ha solucionado en algunas versiones. Ya no puedo reproducirlo en SQL Server 2014 SP2 CU 5. El SP2 KB 2014 contiene una corrección sin artículo de KB: Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error
. Los dos errores de conexión sobre esto se han cerrado:
- https://connect.microsoft.com/SQLServer/feedback/details/847233/creating-non-clustered-index-causes-dbcc-checkdb-with-extended-logical-checks-to-raise-corruption-error
- https://connect.microsoft.com/SQLServer/feedback/details/795478/unfixable-dbcc-checkdb-error-that-is-also-a-false-positive-and-otherwise-strange
If the indexed view does not contain an aggregate over values of type float or real and you receive errors 8907 or 8708, drop the index on the view and re-create it. Do not use ALTER INDEX REBUILD to try to remove the differences between the stored and the computed view, because ALTER INDEX REBUILD does not recalculate the view before rebuilding the index. Then run DBCC CHECKTABLE on the View to verify no differences remain.
[1]
notación no funciona en el marcado de comentarios.