2010-12-14 47 views
2

J'ai une table message dans une base de données de près d'un million de lignes. Il a une colonne externalId qui est . Les valeurs stockées sont guidées mais je souhaite mettre à jour cette colonne pour qu'elle soit uniqueidentifier. Je pense que je vais ajouter une nouvelle colonne qui est uniqueidentifier. Copiez toutes les valeurs dans cette colonne, puis supprimez la colonne d'origine. Ensuite, je vais renommer cette colonne à externalId. Mon problème est qu'il y a des centaines de procédures stockées etc. et je dois m'assurer que je ne casse rien. Je dois aussi passer en revue tout le code et apporter des modifications pour que nous attendions un Guid et pas une chaîne. (J'utilise C#)SQL Server refactorise une colonne de varchar (50) à uniqueidentifier et aux problèmes environnants

Est-ce que quelqu'un a des conseils ou des recommandations? Je ferais mieux de simplement dupliquer cette colonne et de ne pas toucher à la colonne existante et de faire du code qui fait une sélection sur elle, utilisez la colonne guid au lieu de la chaîne (actuellement, elle arrive parfois à expiration!). Je devrais également mettre à jour n'importe quel code puis insère dans cette table pour également insérer un guid ...)

J'aime la merde d'héritage ................... ....

+0

op dit 'J'adore la merde héritage ...', et vous commencez votre propre héritage pour que quelqu'un pleurer dans quelques années ... –

+0

Ouais mais je n'utilise pas de procs stockés. Donc, si je veux refactoriser, je peux le faire dans le code, dans un endroit et je sais que cela fonctionnera. – superlogical

Répondre

0

Il se trouve bien après avoir mis un index non clusterisé sur cette colonne c'est assez rapide. Je viens de sélectionner la requête dans le studio de gestion Sql Server et j'ai cliqué et j'ai passé 'Analyser la requête dans le moteur de paramétrage du moteur de base de données'. Il m'a dit que cette colonne a besoin d'un index et génère même le script SQL que vous devez l'ajouter :)

CREATE NONCLUSTERED INDEX [IX_message_external_id] ON [dbo].[message] 
(
    [external_id] ASC 
) 
INCLUDE ([message_id], 
[message_type_id], 
[message_status_id], 
[template_id], 
[user_id], 
[raw_message_body]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY] 
1

Le seul véritable conseil que je peux vous donner est de le faire en même temps. Ne faites pas ce repas à la pièce car vous aurez des problèmes.

Ajoutez la colonne, copiez les valeurs, supprimez l'ancienne colonne et renommez la nouvelle. Recompilez ensuite toutes vos procédures stockées. Cela vous donnera une liste de problèmes. Corrigez-les tous et recompilez. Si cette partie semble bonne, alors passez au code. En tant qu'héritage, vous trouverez probablement un certain nombre d'autres problèmes ici que vous ne saviez même pas.

Le code va être la zone la plus difficile. Très probablement, les problèmes vont impliquer des erreurs d'exécution. Faites un plan de test qui couvre absolument tout et passez par là.

+0

Comment recompiler toutes les procédures stockées? – superlogical

+0

@Jake Scott: Il suffit de les écrire et d'exécuter le script. Comme le serveur sql essaie d'exécuter les instructions alter, il lancera toutes les erreurs que vous avez. – NotMe

+0

@Jake Scott: BTW, vous pouvez facilement scripter tous les proc en une seule fois. – NotMe

4

Vous pouvez simplement

alter table message 
    alter column externalId uniqueidentifier 

Le risque est que si l'une des valeurs stockées dans la colonne ne sont pas GUIDs, vous verrez une erreur comme:

Conversion failed when converting from a character string to uniqueidentifier. 
4

Je probablement approcher cela comme si:

  • travail sur une copie
  • ajouter un nouvelle colonne externalIdGuid de type uniqueidentifier
  • essayer de convertir tous externalId dans le nouveau externalIdGuid

Si cela fonctionne, tous vos externalId sont GUID valide de - dans ce cas, vous pouvez tout simplement convertir la colonne de taper uniqueidentifier:

ALTER TABLE dbo.Message 
    ALTER COLUMN externalID uniqueidentifier 
0

une façon très rapide et en toute sécurité pour vérifier si vous cassez quoi que ce soit sur votre système de dev est de renommer votre table le message_legacy et faire un message visite appelé qui jette ExternalId à uniqueIdentifier.Cela ne devrait pas gâcher avec les données sous-jacentes, mais vous donnera une interface fonctionnelle pour voir comment vos proc stockés et autres codes se comporteront. N'oubliez pas d'accorder les mêmes autorisations à cette vue que vous avez sur la table ou vous pourriez obtenir des erreurs qui sont liées à la permission au lieu du type lié, ce que vous voulez vraiment tester.

Si vous obtenez un résultat acceptable, alors allez-y et changez la définition de la colonne. Personnellement, je renommer la table, créer une nouvelle table avec le type de colonne changé, insérer dans new_table sélectionner * à partir de old_table, puis laisser tomber l'ancienne table.

Bonne chance!

1

Je ne ferais pas cela du tout. Oui, il aurait mieux valu que ce soit un identifiant unique, mais à moins d'avoir un problème spécifique qui ne peut pas être surmonté sans le modifier, quelle est la valeur que les utilisateurs obtiennent.

Si vous décidez de le faire. Vous pouvez interroger le sys.procedures. C'est mieux que d'utiliser syscomments ou INFORMATION_SCHEMA.ROUTINES

+0

Je dois accélérer ce code car il est temps de rechercher la valeur de chaîne dans les 980 000+ lignes. – superlogical