Creé una tabla en un DB que ya existe en otro DB. Inicialmente se rellenó con los datos antiguos de DB. El PK de la tabla tenía que recibir los valores que ya existen en esos registros, por lo que no podría ser autoincrement.
Ahora necesito que la nueva tabla tenga su PK como autoincremento. Pero, ¿cómo puedo hacer eso después de que el PK ya exista y tenga datos?

IDENTITY?Respuestas:
La forma en que entiendo su pregunta es que tiene una tabla existente con una columna que hasta ahora se ha rellenado con valores manuales, y ahora desea (1) hacer que esta columna sea una
IDENTITYcolumna y (2) asegurarse de queIDENTITYcomience desde el valor más reciente en las filas existentes.En primer lugar, algunos datos de prueba para jugar:
El objetivo es crear la columna de clave principal de la tabla
id, unaIDENTITYcolumna que comenzará en 21 para el siguiente registro que se inserte. Para este ejemplo, la columnaxyzrepresenta todas las otras columnas de la tabla.Antes de hacer nada, lea las advertencias al final de esta publicación.
En primer lugar, en caso de que algo salga mal:
Ahora, agreguemos una columna de trabajo temporal
id_tempy configuremos esa columna a losidvalores de la columna existente :A continuación, debemos descartar la
idcolumna existente (no puede simplemente "agregar" unaIDENTITYa una columna existente, debe crear la columna como unaIDENTITY). La clave principal también tiene que ir, porque la columna depende de ella.... y agregue la columna nuevamente, esta vez como
IDENTITY, junto con la clave principal:Aquí es donde se pone interesante. Puede habilitar
IDENTITY_INSERTen la tabla, lo que significa que puede definir manualmente los valores de unaIDENTITYcolumna cuando inserta nuevas filas (sin embargo, no actualiza las filas existentes).Con ese conjunto,
DELETEtodas las filas de la tabla, pero las filas que está eliminando estánOUTPUTen la misma tabla, pero con valores específicos para laidcolumna (de la columna de copia de seguridad).Una vez hecho,
IDENTITY_INSERTapague nuevamente.Suelte la columna temporal que agregamos:
Y finalmente, vuelva a colocar la
IDENTITYcolumna, para que los siguientes registrosidse reanuden después del número más alto existente en laidcolumna:Verificando la tabla de ejemplo, el
idnúmero más alto es 20.Agregue otra fila y verifique su nuevo
IDENTITY:En el ejemplo, la nueva fila tendrá
id=21. Finalmente, si estás contento, confirma la transacción:Importante
Esta no es una operación trivial, y conlleva bastantes riesgos que debe tener en cuenta.
Haga esto en un entorno de prueba dedicado. Tener copias de seguridad. :)
Me gusta usarlo
BEGIN/COMMIT TRANSACTIONporque evita que otros procesos se enreden con la tabla mientras estás en medio de cambiarla, y te da la posibilidad de deshacer todo si algo sale mal. Sin embargo, cualquier otro proceso que intente acceder a su tabla antes de que haya confirmado su transacción terminará esperando. Esto puede ser bastante malo si tiene una mesa grande y / o está en un entorno de producción.OUTPUT .. INTOno funcionará si su tabla de destino tiene restricciones de clave externa o cualquiera de una serie de otras características que no puedo recordar en la parte superior de mi cabeza. En su lugar, puede descargar los datos en una tabla temporal y luego volver a insertarlos en la tabla original. Es posible que pueda usar el cambio de partición (incluso si no usa particiones).Ejecute estas declaraciones una por una, no como un lote o en un procedimiento almacenado.
Intente pensar en otras cosas que pueden depender de la
idcolumna que está soltando y volviendo a crear. Cualquier índice tendrá que descartarse y volver a crearse (como hicimos con la clave primaria). Recuerde escribir cada índice y restricción que necesitará recrear de antemano.Deshabilita cualquiera
INSERTyDELETEdisparadores en la mesa.Si volver a crear la tabla es una opción:
Si volver a crear la tabla es una opción para usted, todo es mucho más simple:
idcolumna como unIDENTITY,IDENTITY_INSERT ONpara la mesa,IDENTITY_INSERT OFF, yfuente
IDENTITY_INSERT ON, rellenarlo y desactivarlo. Eso es lo que quería hacer, pero no sabía que MSSQL lo soportaba.Usar ACTUALIZAR, ELIMINAR o INSERTAR para mover datos puede llevar bastante tiempo y usar recursos (IO) tanto en datos como en archivos / discos de registro. Es posible evitar llenar el registro de transacciones con potencialmente muchos registros mientras se trabaja en una tabla grande: mediante el cambio de partición, solo se modifican los metadatos.
No hay movimiento de datos involucrados y, por lo tanto, esto se realiza muy rápido (casi instantáneo).
Tabla de muestra
La pregunta no muestra la tabla original DDL. El siguiente DDL se usará como ejemplo en esta respuesta:
Se agregan media docena de identificadores aleatorios ficticios de 0 a 15 con esta consulta:
Datos de ejemplo en
IdTNueva mesa con
IDENTITY(0, 1)El único problema con
idTes la falta de laIDENTITY(0, 1)propiedad en la identificación. SeIDENTITY(0, 1)crea una nueva tabla con una estructura similar :Aparte de
IDENTITY(0, 1),idT_Switches idéntico aidT.Llaves extranjeras
idTDeben eliminarse las claves foráneas activadas para permitir el uso de esta técnica.Interruptor de partición
Las tablas
idTyidT_Switchtienen una estructura compatible. En lugar de utilizarDELETE,UPDATEyINSERTlas declaraciones de mover filas deidTaidT_Switcho sobreidTsí mismo,ALTER TABLE ... SWITCHse puede utilizar:La única 'partición' de
PK_idT(toda la tabla) se mueve aPK_idT_Switch(y viceversa).idTahora contiene 0 filas yidT_Switchcontiene 6 filas.Puede encontrar la lista completa de requisitos de compatibilidad de origen y destino aquí:
Transferencia de datos eficientemente mediante el cambio de partición
Tenga en cuenta que este uso de
SWITCHno requiere Enterprise Edition, porque no hay particiones explícitas. Se considera que una tabla sin particiones es una tabla con una única partición desde SQL Server 2005 en adelante.Reemplazar
idTidTahora está vacío e inútil y puede descartarse:idT_Switchse puede renombrar y reemplazará laidTtabla anterior:Llaves extranjeras
Las claves externas se pueden agregar nuevamente a la nueva
idTtabla. Cualquier otra cosa que se haya eliminado previamenteidTpara hacer que las tablas sean compatibles para el cambio también deberá rehacerse.Reseed
Este comando devuelve 0. La tabla idT contiene 6 filas con MAX (id) = 15. Se puede usar DBCC CHECKIDENT (nombre_tabla) :
Como 15 es mayor que 0, se reiniciará automáticamente sin buscar MAX (id):
IDENT_CURRENT ahora devuelve 15 .
Probar y agregar datos
Una
INSERTdeclaración simple :Agrega esta fila:
La
idcolumna ahora está usando la identidad y el valor recién insertado es de hecho 16 (15 + 1).Más información
Hay una pregunta y respuesta relacionada con más antecedentes sobre la
SWITCHtécnica aquí:¿Por qué no se admite la eliminación de la propiedad Identity en una columna?
fuente
Si desea comenzar con un nuevo valor de identidad, debe reiniciar su identidad. Echa un vistazo a la documentación para
CHECKIDENTfuente
ENABLE y DISABLE IDENTITY_INSERT
Si su tabla es TABLE_A entonces
fuente