Modifier le type de données de la colonne PK de table volumineuse

Maintenant que nous n'avons plus de capacité int sur une colonne PK (qui est une IDENTITY ), je voudrais faire cela à bigint , mais ALTER TABLE semble être incapable de gérer ce gros tableau. Donc ma question est: comment puis-je changer le type d'une colonne PK en gardant les valeurs réelles en place et dois-je aussi modifier les tables de referencement?

En plus de la suggestion de KLE, les requêtes suivantes peuvent aider:

Pour désactiver toutes les contraintes sur les tables qui referencent oldTable, essayez d'exécuter la sortie de la requête suivante:

 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' 

Pour déplacer toutes datatables dans la nouvelle table, avec une modification du champ, essayez ceci:

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

Pour déposer l'ancienne table:

 DROP TABLE oldTable 

Pour renommer la nouvelle table en ancien nom:

 sp_rename newTable, oldTable 

Pour réactiver toutes les contraintes sur les tables qui referencent oldTable, essayez d'exécuter la sortie de la requête suivante:

 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' 

J'espère que cela aide…

Ce que nous ferions est:

save votre table

  1. créer une nouvelle table avec la bonne structure
  2. désactiver toutes les contraintes sur ces tables, et celles qui les referencent
  3. déplacer toutes datatables dans la nouvelle table, avec modification du champ; cela peut être fait par lots
  4. supprime l'ancienne table quand elle est vide
  5. renommer la nouvelle table en ancien nom
  6. activer toutes les contraintes sur toutes les tables (certaines colonnes et contraintes FK ont probablement besoin d'être corrigées aussi … Mais elles ne sont pas PK, donc elles sont modifiables)

    6 édité (merci à Alexey)

C'est propre, faisable par lots, bien compris.

Vous devrez également modifier les tables enfant. Après tout, vous allez maintenant essayer d'insert un gros int en eux aussi. Je changerais d'abord les tables des enfants

Ce n'est pas un process facile ou court. Je vous suggère que vous dites à vos users que la database va être en maintenance (vous pouvez évaluer combien de time il faut pour faire dev) à une date fixe et réinitialiser la database en mode mono-user pendant que vous faites ces changements. Vous ne voulez pas perdre datatables ajoutées (ou modifiées) par les users à une table pendant que vous passez à l'autre. Si pour une raison quelconque vous ne pouvez pas avoir de window de maintenance (et je suggère fortement pour l'intégrité des données que vous faites), alors vous devez d'abord changer les tables enfants pour éviter les erreurs d'insertion si vous êtes vraiment proche de la limite. voir les grands nombres presque immédiatement.

Assurez-vous de scripter toute la structure de la database, y compris les valeurs par défaut, les sortingggers, vérifiez les index des conssortingctions, etc., car vous voudrez tout recréer.

Assurez-vous de faire tout cela à travers des scripts sur dev. Cela rendra beaucoup plus facile de faire un prod une fois que vous avez testé le process.

Je pense que vous ne pouvez créer une nouvelle database avec le type de données PK modifié, puis exporter / importer des données, ou en vrac insert dans nouveau, puis renommer la nouvelle database. Bien sûr, cela est vrai si vous avez de nombreuses tables référencées et que votre nouveau type de données PK n'est pas compatible avec les précédentes.