Pregunta

Ahora que nos hemos quedado sin capacidad int en una columna PK (que es una IDENTITY ) me gustaría hacer esto para bigint , pero la simple ALTER TABLE parece ser incapaz de manejar esa gran tabla. Entonces mi pregunta es: ¿cómo cambio el tipo de una columna PK manteniendo los valores reales en su lugar y necesito alterar también las tablas de referencia?

¿Fue útil?

Solución

Además de la sugerencia de KLE, las siguientes consultas pueden ayudar:

Para deshabilitar todas las restricciones en las tablas que hacen referencia a oldTable, intente ejecutar el resultado de la siguiente consulta:

SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'

Para mover todos los datos a la nueva tabla, con alteración del campo, intente esto:

INSERT INTO newTable
SELECT CONVERT(BIGINT, ID) AS ID, COL1, COL2, ..., COLN
FROM oldTable

Para descartar la tabla anterior:

DROP TABLE oldTable

Para cambiar el nombre de la nueva tabla al antiguo nombre:

sp_rename newTable, oldTable

Para volver a habilitar todas las restricciones en las tablas que hacen referencia a oldTable, intente ejecutar el resultado de la siguiente consulta:

SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'

Espero que ayude ...

Otros consejos

Lo que haríamos es:

  

guarda tu tabla

  1. crear una nueva tabla con la estructura correcta
  2. deshabilitar todas las restricciones en estas tablas, y las que hacen referencia a ellas
  3. mover todos los datos a la nueva tabla, con alteración del campo; se puede hacer por lotes
  4. elimine la tabla anterior cuando esté vacía
  5. cambie el nombre de la nueva tabla al antiguo nombre
  6. habilite todas las restricciones en todas las tablas (algunas columnas y restricciones FK probablemente también necesiten arreglarse ... Pero no son PK, por lo que son modificables)

      

    6 editados (gracias a Alexey)

Esto es limpio, factible en lotes, bien entendido.

Deberá modificar también las tablas secundarias. Después de todo, ahora también intentarás insertar un int grande en ellos. Cambiaría primero las tablas secundarias

Este no es un proceso fácil o corto. Te sugiero que les digas a tus usuarios que la base de datos estará inactiva por mantenimiento (puedes calcular cuánto tiempo se tarda en realizar el desarrollo) en una fecha establecida y restablecer la base de datos al modo de usuario único mientras haces estos cambios. No desea perder los datos que los usuarios agregan (o cambian) a una tabla mientras cambia a la otra. si por alguna razón no puede tener una ventana de mantenimiento (y sugiero encarecidamente por la integridad de los datos que haga), entonces debe cambiar las tablas secundarias primero para evitar errores de inserción si está realmente cerca del límite y estará viendo los grandes números casi de inmediato.

Asegúrese de realizar un script de toda la estructura de la base de datos, incluidos los valores predeterminados, los desencadenantes, los índices de verificación de restricciones, etc., ya que querrá volver a crear todo.

Asegúrese de hacer todo esto a través de scripts en dev. Eso hará que sea mucho más fácil hacer una producción una vez que haya probado el proceso.

Creo que solo puede crear una nueva base de datos con un tipo de datos PK modificado, y luego exportar / importar datos, o insertar en masa en una nueva, luego renombrar una nueva base de datos. Por supuesto, esto es real si tiene muchas tablas referenciadas y su nuevo tipo de datos PK no es compatible con los anteriores.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top