2010-12-14 1 views
2

Ich habe eine Tabelle message in einer Datenbank, die fast eine Million Zeilen hat. Es hat eine externalId Spalte, die varchar(50) ist. Die darin gespeicherten Werte sind guid, aber ich möchte diese Spalte auf uniqueidentifier aktualisieren.SQL Server refactor eine Spalte von Varchar (50) zu Uniqueidentifier und umgebenden Ausgaben

Also ich denke, ich werde eine neue Spalte hinzufügen, die uniqueidentifier ist. Kopieren Sie alle Werte in diese Spalte und legen Sie die ursprüngliche Spalte ab. Dann werde ich diese Spalte in externalId umbenennen.

Mein Problem ist, es gibt Hunderte von gespeicherten Procs etc und ich muss sicherstellen, dass ich nichts zerbrechen. Ich muss auch den ganzen Code grep und Änderungen vornehmen, so dass wir ein Guid und nicht eine Zeichenfolge erwarten. (Ich verwende C#)

Hat jemand einige Tipps oder Empfehlungen?

Würde ich besser sein, nur diese Spalte duplizieren und nicht die vorhandene Spalte und machen Sie keinen Code, der eine Auswahl auf sie die Guid-Spalte statt der Zeichenfolge (derzeit manchmal manchmal Time-Out!). Ich müsste auch jeden Code aktualisieren, der in diese Tabelle eingefügt wird, um auch eine GUID einzufügen ...)

Ich liebe Legacy Mist ................... ....

+0

op :) hinzufügen müssen, sagte 'Ich Vermächtnis Mist lieben ...', und Sie beginnen, Ihr eigenes Vermächtnis für jemanden weinen über in ein paar Jahren ... –

+0

Ja, aber ich verwende keine gespeicherten Procs. Also, wenn ich Refactoring möchte, kann ich es in Code tun, an einem Ort und weiß, dass es funktionieren wird. – superlogical

Antwort

0

Gut stellt sich heraus, nachdem ich einen Non Clustered-Index auf dieser Spalte ist es ziemlich schnell. Ich habe gerade die Abfrage in Sql Server Management Studio ausgewählt und rught geklickt und ging 'Analyse in Datenbank Engine Tuning Advisor analysieren'. Es hat mir gesagt, dass diese Spalte einen Index benötigt und erzeugt auch das SQL-Skript Sie es

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

Der einzige wirkliche Hinweis, den ich Ihnen geben kann, ist es, alles auf einmal zu tun. Mach dieses Stück Mahlzeit nicht, da du Probleme haben wirst.

Fügen Sie die Spalte hinzu, kopieren Sie die Werte, löschen Sie die alte Spalte und benennen Sie die neue um. Dann kompilieren Sie alle Ihre gespeicherten Prozeduren neu. Dadurch erhalten Sie eine Liste der Problembereiche. Fix sie alle und neu kompilieren. Wenn dieser Teil gut aussieht, dann gehe zum Code. Als Vermächtnis werden Sie hier wahrscheinlich eine Reihe anderer Probleme finden, von denen Sie noch gar nichts wussten.

Der Code wird der härteste Bereich sein. Wahrscheinlich werden die Probleme Laufzeitfehler beinhalten. Machen Sie einen Testplan, der absolut alles abdeckt und durchgeht.

+0

Wie kompiliere ich alle gespeicherten Prozeduren neu? – superlogical

+0

@Jake Scott: Nur Skript sie und führen Sie das Skript aus. Da sql server versucht, die alter-Anweisungen auszuführen, wirft er alle Fehler, die Sie haben. – NotMe

+0

@Jake Scott: BTW, können Sie einfach alle Procs in einem Rutsch Skript. – NotMe

4

Sie könnten einfach

alter table message 
    alter column externalId uniqueidentifier 

Das Risiko besteht darin, dass, wenn eine der in der Spalte gespeicherten Werte sind nicht guids, ein Fehler angezeigt werden wie:

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

Ich würde wahrscheinlich nähern dies wie folgt:

  • Arbeit auf einer Kopie
  • ein hinzufügen neue Spalte externalIdGuid vom Typ uniqueidentifier
  • versuchen alle externalId in die neue externalIdGuid

zu konvertieren Wenn das funktioniert, dann werden alle Ihre externalId gültige GUID sind - in diesem Fall könnten Sie einfach nur die Spalte konvertieren uniqueidentifier eingeben:

ALTER TABLE dbo.Message 
    ALTER COLUMN externalID uniqueidentifier 
0

eine sehr schnelle und sichere Art und Weise zu überprüfen, ob Sie alles auf Ihrem dev System brechen ist Ihre Tabelle message_legacy umbenennen und eine Ansicht namens Nachricht machen, die uniqueidentifier ExternalID wirft.Das sollte nicht mit den zugrunde liegenden Daten verwechselt werden, sondern gibt Ihnen eine praktikable Schnittstelle, um zu sehen, wie sich Ihre gespeicherten Procs und anderer Code verhalten. Denken Sie daran, dieser Ansicht die gleichen Berechtigungen zu erteilen, die Sie für die Tabelle haben, oder Sie erhalten Fehler, die mit der Berechtigung verknüpft sind und nicht mit dem Typ, was Sie wirklich testen möchten.

Wenn Sie ein akzeptables Ergebnis erhalten, dann ändern Sie die Spaltendefinition. Persönlich würde ich die Tabelle umbenennen, eine neue Tabelle mit dem geänderten Spaltentyp erstellen, in new_table einfügen * aus old_table auswählen und dann die alte Tabelle löschen.

Viel Glück!

1

Ich würde das überhaupt nicht tun. Ja, es wäre besser gewesen, wenn es zuerst ein Uniqueneidentifier gewesen wäre, aber wenn Sie nicht ein bestimmtes Problem haben, das nicht überwunden werden kann, ohne es zu ändern, was ist der Wert, den Sie Benutzer bekommen.

Wenn Sie sich entscheiden, es zu tun. Sie können die sys.procedures abfragen. Es ist besser, als mit syscomments oder INFORMATION_SCHEMA.ROUTINES

+0

Ich muss diesen Code beschleunigen, da es nach dem Zeichenfolgenwert in den 980.000 Zeilen sucht. – superlogical