Posts etiquetados ‘dbcc’

Algunas veces cuando tenemos campos definidos como Identity y borramos registros, luego al insertar otros registros vemos que el correlativo que SQL Server usa, no corresponde al registro (tupla) que a nuestro entender debería usar. Esto es pues aunque hubiéramos borrado registros, el número correlativo (seed) que toca para la tabla propiamente dicha, no se resetea con el borrado de registros, por lo que los nuevos registros de esa tabla toman el siguiente que asigno la última vez.

Esto tiene lógica, pues supongamos que insertamos registros que en otras tablas están relacionados al número asignado en el campo Identity, si borramos e insertamos nuevamente, puede ser que se cree una relación no correcta, es decir una desintegridad de datos. Esto no daría error, pero sabemos que los datos no corresponderían.

Si nosotros queremos tener control de estos Identity y aun así queremos reiniciar a nuestra discreción el número que la base de datos asigna en una siguiente inserción usamos el comando

DBCC CHECKIDENT ( NombreTabla, RESEED, Numero)

Donde NombreTabla
corresponde al nombre de la tabla que deseamos alterar, y Numero
es el número que le indicamos a la base de datos que fue el último asignado, por lo que en un nuevo INSERT asignará ese número más uno, es decir el siguiente a ese número indicado.

BORRADO DE TODOS LOS REGISTROS DE UNA TABLA:

Cuando hacemos esto, esperaríamos que el nuevo número sea 1, pero no sucede así, y asigna el siguiente número basado en el último INSERT más uno. Para solucionar esto podemos hacer dos cosas:

1) Si borramos todos los registros lo podemos hacer con el comando TRUNCATE TABLE, en lugar de DELETE.

Esto lo reinicia y el próximo será «1».

2) Si borramos todos los registros con DELETE y queremos reiniciar el Identity,

lo hacemos con DBCC CHECKIDENT ([TablaEjemplo], RESEED, 0)

Sin embargo, hay momentos en que queremos no empezar con el 1, si no que en un número a nuestro criterio. Para ello dejo el siguiente query, donde se hacen varios ensayos. Véanlos detenidamente, quizá acá me explique mejor. Espero sea de gran ayuda. Dios les bendiga.  

ACLARACION:  Por favor revisen la sintaxis pues este blog lo cargue desde Word y algunas veces con este proceso altera las comillas por comillas inclinadas y de esa misma manera otras cosas.  Pueden usar REPLACE para reemplazarlas.  Es algo del editor de  Wordpress.

QUERY DE EJEMPLO:

-------------------------------------------------------------------------------------------------------------
 -- EJEMPLO:        Control del correlativo automatico que establecen los campos tipo IDENTITY
 -- AUTOR:          Jorge Zapeta, Septiembre 2013.  Guatemala, C.A.
 -- OBSERVACIONES:  Este tutorial o guia  pretende solamente apoyarles. La responsabilidad del uso es suya
-- EJECUTAR ESTE SCRIPT PARA VER EL DESEMPLEÑO DEL EJEMPLO
 --   **  Si la salida esta Result to Grid y quieren verlo en Result to Text presionar CTRL+T  **
 --   **  Si la salida esta Result to Text y quieren verlo en Result to Grid presionar CTRL+D  **
 -------------------------------------------------------------------------------------------------------------
-- Borramos cualquier definicion previa de la TablaEjemplo (cambiar nombre si ya tienen una asi para otro uso).
 IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TablaEjemplo]') AND type in (N'U'))
 DROP TABLE [dbo].[TablaEjemplo]
 GO
-- Se crea la TABLA llamada TablaEmeplo
 CREATE TABLE [dbo].[TablaEjemplo](
 [CodigoID] [int] IDENTITY(1,1) NOT NULL,  -- La clausula IDENTITY es para que SQL asigne el numero automaticamente (no se puede modificar)
 [Descripcion] [varchar](50) NULL,
 [Comentarios] [varchar](100) NULL,
 )
 GO
SELECT 'En el comando INSERT INTO [TablaEjemplo] no se incluye el campo [CodigoID] pues este es asignado automaticamente por SQL SERVER' AS Descripcion_del_Proceso
SELECT 'Se insertan registros de forma correlativa 1, 2, 3, 4, 5. Vemos que cada registro coincide con el numero de CodigoID' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 1', '1er. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 2', '1er. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 3', '1er. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 4', '1er. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 5', '1er. INSERT')
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Borraremos los resgistros 4 y 5' AS Descripcion_del_Proceso
 DELETE FROM [TablaEjemplo] WHERE [Descripcion] = 'REGISTRO 4'
 DELETE FROM [TablaEjemplo] WHERE [Descripcion] = 'REGISTRO 5'
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Ahora volveremos a insertar los REGISTROS 4 y 5. Veremos que nuevamente estan del 1 al 5,' AS Descripcion_del_Proceso
 SELECT 'pero aunque el REGISTRO 4 y 5 corresonden al registro de la tabla (tupla) 4 y 5, el CodigoID ahora es 6 y 7' AS Descripcion_del_Proceso
 SELECT 'pues lo asigna de forma automatica y conserva el numero que tocaba, aunque se hubiera borrado' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 4', '2do. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 5', '2do. INSERT')
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Borraremos nuevamente los resgistros 4 y 5' AS Descripcion_del_Proceso
 DELETE FROM [TablaEjemplo] WHERE [Descripcion] = 'REGISTRO 4'
 DELETE FROM [TablaEjemplo] WHERE [Descripcion] = 'REGISTRO 5'
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Ahora reiniciaremos el Identity, Seed o correlativo automtico (como le llamen) para el campo CodigoID en "3" para que el siguiente que asigne sea "4"' AS Descripcion_del_Proceso
 SELECT 'OBSERVACION:  Se establece en el numero ultimo usado, es decir uno menos del que toca para que al insertar haga el siguiente, osea el "4".' AS Descripcion_del_Proceso
 DBCC CHECKIDENT ([TablaEjemplo], RESEED, 3)
 GO
SELECT 'Ahora volveremos a insertar los REGISTROS 4 y 5. Veremos que nuevamente estan del 1 al 5,' AS Descripcion_del_Proceso
 SELECT 'y vemos que el REGISTRO 4 y 5 corresonden al renglon (tupla) 4 y 5, el CodigoID tambien es 4 y 5' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 4', '3er. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 5', '3er. INSERT')
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'El Identity pudimos haberlo puesto si quisieramos en el numero que se nos ocurra' AS Descripcion_del_Proceso
 SELECT 'Por ejemplo ahora estableceremos a CodigoID en "10", para que el siguiente automatico que asigne sea 11 (uno mas)' AS Descripcion_del_Proceso
 DBCC CHECKIDENT ([TablaEjemplo], RESEED, 10)
 GO
SELECT 'Insertaremos los REGISTROS 6 y 7 y veremos que corresonden al renglon (tupla) 6 y 7,' AS Descripcion_del_Proceso
 SELECT 'pero el CodigoID ahora es 11 y 12. Por lo que podemos manejarlo a nuestro criterio' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 6', '4to. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 7', '4to. INSERT')
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'OBSERVACION:  Si el CodigoID SI es una llave, ver que nunca se establezca el Identity en un numero previo a uno existente, pues dará error al insertar' AS Descripcion_del_Proceso
 SELECT '              Si el CodigoID NO es una llave, el Identity si puede ser un numero existente. Veamos el ejemplo siguiente:' AS Descripcion_del_Proceso
SELECT 'Para el ejemplo presente CodigoID NO es una llave.  Por lo que insertaremos registros con numeros existentes' AS Descripcion_del_Proceso
SELECT 'Estableceremos a CodigoID en "0", para que el siguiente automatico que asigne sea 1 (uno mas)' AS Descripcion_del_Proceso
 DBCC CHECKIDENT ([TablaEjemplo], RESEED, 0)
 GO
SELECT 'Insertaremos los REGISTROS 8 y 9 y veremos que corresonden al renglon (tupla) 8 y 9,' AS Descripcion_del_Proceso
 SELECT 'pero el CodigoID ahora es 1 y 2. Por lo que podemos manejarlo a nuestro criterio' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 8', '5to. INSERT')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 9', '5to. INSERT')
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Si el campo CodigoID fuera una llave, es decir un campo que no permite repeditos, hubieramos tenido un ERROR.' AS Descripcion_del_Proceso
-- BORRAR TODOS LOS REGISTROS CON DELETE:
 SELECT '***  AHORA VERMOS OTRAS FORMAS DE MANEJAR EL IDENTITY ***' AS Descripcion_del_Proceso
 SELECT 'Borraremos todos los registros con el comando DELETE' AS Descripcion_del_Proceso
 DELETE FROM [TablaEjemplo]
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Se insertan registros de forma correlativa 1, 2, 3, 4, 5. Vemos que cada registro NO coincide con el numero CodigoID' AS Descripcion_del_Proceso
 SELECT 'El numero CodigoID inicia en "3", pues en el último INSERT quedo en "2" (ver 5to. INSERT)' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 1', '6to. INSERT, despues de borrar todo con DELETE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 2', '6to. INSERT, despues de borrar todo con DELETE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 3', '6to. INSERT, despues de borrar todo con DELETE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 4', '6to. INSERT, despues de borrar todo con DELETE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 5', '6to. INSERT, despues de borrar todo con DELETE')
 GO
SELECT * FROM [TablaEjemplo]
-- BORRAR TODOS LOS REGISTROS CON TRUNCATE TABLE:
SELECT 'Ahora Borraremos todos los registros con el comando TRUNCATE TABLE' AS Descripcion_del_Proceso
 TRUNCATE TABLE [TablaEjemplo]
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'Se insertan registros de forma correlativa 1, 2, 3, 4, 5. Vemos que cada registro SI coincide con el numero CodigoID' AS Descripcion_del_Proceso
 SELECT 'El numero CodigoID reinicio en "0", por lo que comenzara asigando 1.' AS Descripcion_del_Proceso
 SELECT 'Para esto NO se ejecuto el comando DBCC CHECKIDENT, pues el comando TRUNATE TABLE lo hace automaticamente' AS Descripcion_del_Proceso
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 1', '7mo. INSERT, despues de borrar todo con TRUNCATE TABLE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 2', '7mo. INSERT, despues de borrar todo con TRUNCATE TABLE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 3', '7mo. INSERT, despues de borrar todo con TRUNCATE TABLE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 4', '7mo. INSERT, despues de borrar todo con TRUNCATE TABLE')
 INSERT INTO [TablaEjemplo] ([Descripcion], [Comentarios]) VALUES ('REGISTRO 5', '7mo. INSERT, despues de borrar todo con TRUNCATE TABLE')
 GO
SELECT * FROM [TablaEjemplo]
SELECT 'OBSERVACION:  Mucho quidado con el uso de estos comandos. Siempre hagan sus pruebas en otras tablas y hagan BACKUP' AS Descripcion_del_Proceso
 SELECT '              Esta es solamente una guia o tutorial de apoyo. Uds. asumen la responsabilidad de su uso. Espero les sirva mucho. Bendiciones.' AS Descripcion_del_Proceso

_________________________________________________________________________

Jorge Zapeta, Guatemala, C.A. Septiembre, 2013.

DAME UN LIKE O DEJA UN COMENTARIO
Si te sirvió de algo, te gusto, o aprendiste algo nuevo por favor deja un Like o un comentario para saber cuánto estamos ayudando a otros compartiendo conocimiento.