Bei direkter Beantwortung der Frage gibt es zwei Möglichkeiten, die Operation auszuführen.
- Wenn die Anzahl der in der Tabelle enthaltenen Varchar-Spalten gering ist (eine oder zwei), ist es praktischer, Pseudo-temporäre Spalten zu erstellen
- Wenn die Anzahl der Varchar-Spalten größer ist, ist der oben beschriebene Weg nicht sehr praktisch. Sie erstellen also eine Pseudotabelle. Dies wird am häufigsten für Metadatenaktualisierungsskripte einiger Datenbank-Tools wie ErWin oder ER / Studio verwendet (ich habe beide Tools verwendet und die vor der Anwendung generierten Skripte überprüft).
Hinweis zu großen Tabellen : Wenn die Tabelle nur wenige Tausend Datensätze oder weniger enthält, können Sie den Vorgang sofort ausführen. Bei Tabellen mit Millionen Datensätzen ist es praktischer, in Stapeln zu arbeiten (sagen wir jedes Mal 1000 oder 100 Datensätze).
Pseudo-temporäre Spalten
Pseudo-temporäre Spalten (ich habe vergessen, ob es einen anderen, passenderen Namen gibt) sind Spalten, in denen das Ergebnis einer Konvertierung gespeichert wird. In diesem Fall wären sie auch die letzten Spalten nach dem Prozess.
- Erstellen Sie die neuen Spalten mit der beabsichtigten Länge. Vergessen Sie nicht, Prüfbeschränkungen oder Standardeinstellungen in die neue Definition aufzunehmen
- Führen Sie ein Update durch (oder Updates, siehe obige Beobachtung), um die Daten der alten Spalte in der neuen zu speichern.
- Führen Sie die Protokollsicherung durch und führen Sie den Prüfpunkt durch, damit das Protokoll nicht absurd groß wird.
- Wenn der alten Spalte Einschränkungen zugeordnet sind, löschen Sie diese.
- Lass die alte Spalte fallen.
- Benennen Sie die neue Spalte in den alten Spaltennamen um
- Erstellen Sie die betroffenen Indizes neu (oder alle, wenn die betroffene Spalte auch Teil einer Einschränkung für gruppierte Primärschlüssel war - es ist selten, dass jemand einen (n) varchar als PK verwendet, aber ich habe einige gesehen).
Dies ist der gleiche Prozess, der in Aarons Antwort beschrieben wird .
Pseudo-Temp-Tabellen
Wenn sich die Änderung in mehr als einer Handvoll Spalten befindet, ist es praktischer, eine neue Tabelle basierend auf dem Schema der alten zu erstellen.
- Erstellen Sie eine neue Tabelle ohne Tabelleneinschränkungen (PK, FK usw.). Bringen Sie zu diesem Zeitpunkt nur Spalten mit (NICHT NULL, DEFAULT, CHECK usw.)
- Fügen Sie die Daten an der alten Tabelle in die neue Tabelle ein (siehe Hinweis zu großen Tabellen oben). SET IDENTITY_INSERT ist hier ein Muss.
- Löschen Sie nun alle Tabelleneinschränkungen (PK, FKs, Prüfungen) und Trigger für die alte Tabelle. Erstellen Sie diese Einschränkungen und Trigger für die neue Tabelle neu.
- Erstellen Sie alle anderen Indizes (alle auf einmal oder einzeln, abhängig von Ihrem Wartungsfenster) der alten Tabelle in der neuen Tabelle. Sofern die Tabelle keinen Clustered-Index hat, muss dies nach Schritt 3 oder zumindest nach der Erstellung der PK-Einschränkung erfolgen.
- Überprüfen Sie, ob alles richtig gelaufen ist (wenn Sie dabei keinen Auslöser oder eine Einschränkung vergessen haben), und löschen Sie die alte Tabelle, wenn alles in Ordnung ist.
- Benennen Sie die neue Tabelle in den Namen der alten Tabelle um
Hinweis zu Schritt 4 : Wenn Sie doppelte Indizes erkannt haben (das Erkennen doppelter Indizes ist ein sehr langes Thema, siehe Kimberly Tripps Blog auf SQLSkills.com), ist dies Ihre Chance, diese zu entfernen, wenn dies der Fall ist.
Auswirkungen auf die Leistung
Der Wechsel von VARCHAR zu NVARCHAR hat einige Auswirkungen auf die Leistung, zumindest für jeden SQL Server unter 2008R2. Für SQL 2008 R2 hat Aaron Bertrand einige Blog-Beiträge zur Unicode-Komprimierungsfunktion, die das Gleichgewicht ausgleichen können, wenn NVarchar-Spalten zum Speichern von Inhalten verwendet werden, die in VARCHAR-Spalten gespeichert werden können. Ich habe sie nicht vollständig gelesen, wie es die Artikel verdienen, aber das Thema ist interessant.
In NVARCHAR-Spalten (IOW, vor 2008R2) werden alle Zeichen in den Spalten mit 2 Byte pro Zeichen gespeichert. Beispielsweise wird die Zeichenfolge 'MSSQL' in 5 Bytes in einer VARCHAR-Spalte und 10 in einer NVARCHAR-Spalte gespeichert. Da Nicht-LOB-Zeichenfolgenspalten maximal 8000 Byte speichern dürfen , bedeutet dies, dass VARCHAR 8000 Zeichen speichern kann, während NVARCHR auf 4000 Zeichen beschränkt ist.
Implikationen dieser Tatsachen:
- Da Indexschlüssel auf 900 Byte begrenzt sind (siehe Dokumente zu CREATE INDEX), schlägt der Befehl nicht fehl, wenn Sie versuchen, eine NVARCHAR (500) -Spalte zu indizieren (wenn dies die einzige Spalte im Indexschlüssel ist), sondern wenn Sie UPDATE oder Fügen Sie eine Zeile mit mehr als 450 - (Gesamtgröße anderer Spalten auf dem Indexschlüssel, falls dies der Fall ist) Zeichen ein. Der Vorgang schlägt fehl.
- Je mehr Bytes zu betreiben sind, desto mehr Arbeit ist zu erledigen. Sie lesen / schreiben / vergleichen / cachen das Doppel von Bytes.
- Abhängig von der Größe der Tabelle, dem Einfluss der Zeichenfolgenspalten auf die gespeicherte Größe der Tabelle und der Beteiligung der Tabelle an der Datenbankgröße können Sie eine Zunahme der (verwendeten) Datenbankgröße und aller davon betroffenen Variablen erwarten direkt oder nicht (wie Sicherungs- / Wiederherstellungszeit, Indexpflege usw.).
BEARBEITEN: Wie von gbn angegeben, lohnt es sich nicht, etwas zu erstellen, nur um VARCHARs zu verwenden, wenn Sie eine eindeutige Anforderung haben, bei der NVARCHAR-Spalten vollständig ausgefüllt werden müssen.