Bevor Sie etwas unternehmen, sollten Sie die von @RDFozz gestellten Fragen in einem Kommentar zur Frage berücksichtigen, nämlich:
Gibt es irgendwelche anderen Quellen außer [Q].[G]
dieser Tabelle bevölkern ?
Wenn die Antwort nicht "Ich bin zu 100% sicher, dass dies die einzige Datenquelle für diese Zieltabelle ist" lautet , nehmen Sie keine Änderungen vor, unabhängig davon, ob die aktuell in der Tabelle enthaltenen Daten konvertiert werden können oder nicht Datenverlust.
Gibt es irgendwelche Pläne / Diskussionen im Zusammenhang mit zusätzlichen Quellen Addiert man diese Daten in naher Zukunft zu bevölkern ?
Und ich möchte eine verwandte Frage hinzufügen: Gab es eine Diskussion darüber, ob mehrere Sprachen in der aktuellen Quelltabelle (dh [Q].[G]
) unterstützt werden, indem sie in konvertiert werden NVARCHAR
?
Sie müssen herumfragen, um ein Gefühl für diese Möglichkeiten zu bekommen. Ich gehe davon aus, dass Ihnen derzeit nichts gesagt wurde, was in diese Richtung weisen würde, ansonsten würden Sie diese Frage nicht stellen. Wenn jedoch angenommen wurde, dass diese Fragen "nein" lauten, müssen sie von a gestellt und gestellt werden breit genug Publikum, um die genaueste / vollständigste Antwort zu erhalten.
Das Hauptproblem hierbei ist nicht so sehr, dass Unicode-Codepunkte (jemals) nicht konvertiert werden können , sondern vielmehr, dass Codepunkte nicht alle auf eine einzelne Codepage passen. Das ist das Schöne an Unicode: Es kann Zeichen aus ALLEN Codepages enthalten. Wenn Sie von NVARCHAR
- wo Sie sich nicht um Codepages kümmern müssen - nach konvertieren , müssen VARCHAR
Sie sicherstellen, dass für die Sortierung der Zielspalte dieselbe Codepage wie für die Quellspalte verwendet wird. Dies setzt voraus, dass entweder eine Quelle oder mehrere Quellen dieselbe Codepage verwenden (jedoch nicht unbedingt dieselbe Kollatierung). Wenn jedoch mehrere Quellen mit mehreren Codepages vorhanden sind, kann möglicherweise das folgende Problem auftreten:
DECLARE @Reporting TABLE
(
ID INT IDENTITY(1, 1) PRIMARY KEY,
SourceSlovak VARCHAR(50) COLLATE Slovak_CI_AS,
SourceHebrew VARCHAR(50) COLLATE Hebrew_CI_AS,
Destination NVARCHAR(50) COLLATE Latin1_General_CI_AS,
DestinationS VARCHAR(50) COLLATE Slovak_CI_AS,
DestinationH VARCHAR(50) COLLATE Hebrew_CI_AS
);
INSERT INTO @Reporting ([SourceSlovak]) VALUES (0xDE20FA);
INSERT INTO @Reporting ([SourceHebrew]) VALUES (0xE820FA);
UPDATE @Reporting
SET [Destination] = [SourceSlovak]
WHERE [SourceSlovak] IS NOT NULL;
UPDATE @Reporting
SET [Destination] = [SourceHebrew]
WHERE [SourceHebrew] IS NOT NULL;
SELECT * FROM @Reporting;
UPDATE @Reporting
SET [DestinationS] = [Destination],
[DestinationH] = [Destination]
SELECT * FROM @Reporting;
Rückgabe (2. Ergebnismenge):
ID SourceSlovak SourceHebrew Destination DestinationS DestinationH
1 Ţ ú NULL Ţ ú Ţ ú ? ?
2 NULL ט ת ? ? ט ת ט ת
Wie Sie sehen können, alle diese Zeichen können konvertieren VARCHAR
, nur nicht in der gleichen VARCHAR
Spalte.
Verwenden Sie die folgende Abfrage, um die Codepage für jede Spalte Ihrer Quelltabelle zu bestimmen:
SELECT OBJECT_NAME(sc.[object_id]) AS [TableName],
COLLATIONPROPERTY(sc.[collation_name], 'CodePage') AS [CodePage],
sc.*
FROM sys.columns sc
WHERE OBJECT_NAME(sc.[object_id]) = N'source_table_name';
DAS GESAGT WERDEN ....
Sie haben erwähnt, dass Sie unter SQL Server 2008 R2 arbeiten, aber Sie haben nicht gesagt, welche Edition. WENN Sie sich zufällig in der Enterprise Edition befinden, vergessen Sie all dieses Konvertierungsmaterial (da Sie es wahrscheinlich nur tun, um Speicherplatz zu sparen) und aktivieren Sie die Datenkomprimierung:
Implementierung der Unicode-Komprimierung
Wenn Sie die Standard Edition verwenden (und es scheint, dass Sie you sind), gibt es eine weitere Möglichkeit, die noch zu lange reicht: ein Upgrade auf SQL Server 2016, da SP1 die Möglichkeit enthält, dass alle Editionen die Datenkomprimierung verwenden (denken Sie daran, ich habe "Long Shot" gesagt) "😉).
Nachdem jetzt klargestellt wurde, dass es nur eine Quelle für die Daten gibt, müssen Sie sich natürlich keine Sorgen mehr machen, da die Quelle keine reinen Unicode-Zeichen oder Zeichen außerhalb ihres spezifischen Codes enthalten darf Seite. In diesem Fall sollten Sie nur die gleiche Kollatierung wie die Quellenspalte verwenden oder mindestens eine, die dieselbe Codepage verwendet. Das heißt, wenn die Quellenspalte verwendet wird SQL_Latin1_General_CP1_CI_AS
, können Sie sie Latin1_General_100_CI_AS
am Ziel verwenden.
Sobald Sie wissen, welche Sortierung verwendet werden soll, können Sie entweder:
ALTER TABLE ... ALTER COLUMN ...
zu sein VARCHAR
(achten Sie darauf, die aktuelle NULL
/ NOT NULL
Einstellung anzugeben ), was ein wenig Zeit und viel Transaktionsprotokollspeicher für 87 Millionen Zeilen erfordert, ODER
Erstellen Sie für jede Spalte neue "ColumnName_tmp" -Spalten und füllen Sie diese langsam über " UPDATE
doing" aus TOP (1000) ... WHERE new_column IS NULL
. Sobald alle Zeilen ausgefüllt sind (und überprüft wurden, dass sie alle korrekt kopiert wurden!), Müssen Sie möglicherweise einen Trigger zum Behandeln von UPDATEs (sofern vorhanden) in einer expliziten Transaktion verwenden sp_rename
, um die Spaltennamen der "aktuellen" zu verwendenden Spalten auszutauschen. " _Old "und dann die neuen Spalten" _tmp ", um einfach das" _tmp "aus den Namen zu entfernen. Rufen Sie dann sp_reconfigure
die Tabelle auf, um zwischengespeicherte Pläne, die auf die Tabelle verweisen, ungültig zu machen. Wenn Ansichten vorhanden sind, die auf die Tabelle verweisen, müssen Sie sie aufrufen sp_refreshview
(oder so ähnlich). Sobald Sie die App validiert haben und die ETL ordnungsgemäß damit funktioniert, können Sie die Spalten löschen.
[G]
werden an ETL übergeben[P]
. Wenn dies der Fall[G]
istvarchar
und der ETL-Prozess der einzige Weg ist, auf dem Daten[P]
eingehen, sollte es keinen geben, sofern der Prozess keine echten Unicode-Zeichen hinzufügt. Wenn andere Prozesse Daten hinzufügen oder ändern[P]
, müssen Sie vorsichtiger sein - nur weil alle aktuellen Daten vorhanden sein können,varchar
bedeutet dies nicht, dassnvarchar
Daten morgen nicht hinzugefügt werden können. Ebenso ist es möglich, dass alles, was Daten verbraucht, Daten[P]
benötigtnvarchar
.