-SQL Server 2005 (en SQL Server 2008 todavía no lo he probado).
-Heditor hexadecimal (en mi caso utilizo XVI32, es freeware)
El error que os voy a describir es de fácil solución, puesto que vamos a corromper un índice nonclustered, pero puede serviros a la hora de practicar posibles soluciones a un error y posiblemente para alguna cosilla más xDDD.
Necesitamos saber la página dónde está nuestro índice nonclustered, ¿cómo podemos obtenerla?
Ahora bien, rebuscando un poco he encontrado que Kalen Delaney's tiene una función mediante la cual podemos transformar una dirección hexadecimal en una página:
create function [dbo].[convert_page_nums] (@page_num binary(6))
RETURNS varchar(11)
AS
BEGIN
RETURN(convert(varchar(2), (convert(int, substring(@page_num, 6, 1)) * power(2, 8)) +
(convert(int, substring(@page_num, 5, 1)))) + ':' +
convert(varchar(11),
(convert(int, substring(@page_num, 4, 1)) * power(2, 24)) +
(convert(int, substring(@page_num, 3, 1)) * power(2, 16)) +
(convert(int, substring(@page_num, 2, 1)) * power(2, 8)) +
(convert(int, substring(@page_num, 1, 1)))) )
END
SELECT dbo.convert_page_nums(0x7E0000000100)
que nos da como resultado en mi caso la página (1:126)
Después de toda la información que hemos recabado tenemos que hacer un volcado de los datos que contiene esa página, ¿cómo? (sigue leyendo que esto se pone interesante)
Primero activamos la visualización del DBCC PAGE en pantalla mediante:
DBCC TRACEON(3604, -1)
GO
Y después obtenemos el volcado de los datos de la página
DBCC PAGE(Corrupta, 1, 126, 1)
Una vez tenemos los datos nos tenemos que fijar en el Slot 0, que nos indica la primera fila en la página, y en el Slot 8 que nos indica la última página.
Slot 0, Offset 0x60, Length 14, DumpStyle BYTE
Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x4E85C060
00000000: 06312020 20205a00 00000100 0000††††††.1 Z.......
Slot 8, Offset 0xd0, Length 14, DumpStyle BYTE
Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x4E85C0D0
00000000: 06392020 20205a00 00000100 0800††††††.9 Z.......
Volvemos a iniciar nuestra instancia y ejecutamos una comprobación de la BD
DBCC CHECKDB('Corrupta') que nos muestra el siguiente resultado:
Resultados de DBCC para 'Datos'.
Mens. 8928, Nivel 16, Estado 1, Línea 1
Id. de objeto 5575058, Id. de índice 2, Id. de partición 72057594038845440, Id. de unidad de asignación 72057594043957248 (tipo In-row data): no se pudo procesar la página (1:126). Vea otros errores para obtener información detallada.
Mens. 8941, Nivel 16, Estado 55, Línea 1
Error de tabla: Id. de objeto 5575058, Id. de índice 2, Id. de partición 72057594038845440, Id. de unidad de asignación 72057594043957248 (tipo In-row data), página (1:126). Error de prueba (dbccAuditRecSucceeded == TRUE). Zona 0, el desplazamiento 0x60 no es válido.
Hay 9 filas in 1 páginas para el objeto "Datos".
CHECKDB detectó 0 errores de asignación y 2 errores de coherencia en la tabla 'Datos'. (Id. de objeto 5575058).
Y al final de todo:
CHECKDB detectó 0 errores de asignación y 2 errores de coherencia en la base de datos 'Corrupta'.
repair_allow_data_loss es el nivel mínimo de reparación para los errores detectados por DBCC CHECKDB (Corrupta).
Ejecución de DBCC completada. Si hay mensajes de error, consulte al administrador del sistema.
¿Bien y ahora qué? la reparamos mediante un REPAIR_REBUILD, REPAIR_ALLOW_DATA_LOSS, restauramos una copia de seguridad.
Lo primero que podríamos hacer es verificar el objeto que tiene el error y para eso lo podemos hacer de la siguiente manera:
SELECT object_name(object_id)AS 'Table',name,index_id,type_desc FROM sys.indexes
WHERE object_id = '5575058'
AND index_id = 2
ALTER INDEX SK_Datos ON dbo.Datos REBUILD
CHECKDB detectó 0 errores de asignación y 0 errores de coherencia en la base de datos 'Corrupta'.
Ejecución de DBCC completada. Si hay mensajes de error, consulte al administrador del sistema.