Hier sind einige Dinge zu beachten:
-
Wenn Sie genau sehen möchten, welches Zeichen dort steht, können Sie den Wert in
VARBINARY
umwandeln was Ihnen den hexadezimalen / binären Wert aller Zeichen in der Zeichenfolge gibt, und es gibt kein Konzept für "versteckte" Zeichen in hex:DECLARE @PostalCode NVARCHAR(20); SET @PostalCode = N'053000'+ NCHAR(0x2008); -- 0x2008 = "Punctuation Space" SELECT @PostalCode AS [NVarCharValue], CONVERT(VARCHAR(20), @PostalCode) AS [VarCharValue], CONVERT(VARCHAR(20), RTRIM(@PostalCode)) AS [RTrimmedVarCharValue], CONVERT(VARBINARY(20), @PostalCode) AS [VarBinaryValue];
Rückgabe:
NVarCharValue VarCharValue RTrimmedVarCharValue VarBinaryValue 053000 053000? 053000? 0x3000350033003000300030000820
NVARCHAR
Daten werden als UTF-16 gespeichert, das in 2-Byte-Sätzen funktioniert. Wenn wir uns die letzten 4 Hex-Ziffern ansehen, um zu sehen, was der versteckte 2-Byte-Satz ist, sehen wir "0820". Da Windows und SQL Server UTF-16 Little Endian (d. h. UTF-16LE) sind, sind die Bytes in umgekehrter Reihenfolge. Spiegeln der letzten 2 Bytes --08
und20
-- wir erhalten "2008", das ist das "Interpunktions-Leerzeichen", das wir überNCHAR(0x2008)
hinzugefügt haben .Beachten Sie außerdem, dass
RTRIM
hat hier überhaupt nicht geholfen. -
Vereinfacht gesagt können Sie die Fragezeichen einfach durch nichts ersetzen:
SELECT REPLACE(CONVERT(VARCHAR(20), [PostalCode]), '?', '');
-
Noch wichtiger ist, dass Sie den
[PostalCode]
konvertieren Feld zuVARCHAR
damit es diese Zeichen nicht speichert. Kein Land verwendet Buchstaben, die nicht im ASCII-Zeichensatz dargestellt werden und die für den VARCHAR-Datentyp nicht gültig sind, zumindest soweit ich darüber gelesen habe (siehe unterer Abschnitt für Referenzen). Tatsächlich ist eine ziemlich kleine Teilmenge von ASCII erlaubt, was bedeutet, dass Sie auf dem Weg hinein leicht filtern können (oder einfach dasselbeREPLACE
tun wie oben gezeigt beim Einfügen oder Aktualisieren):ALTER TABLE [table] ALTER COLUMN [PostalCode] VARCHAR(20) [NOT]? NULL;
Achten Sie darauf, den aktuellen
NULL
zu überprüfen /NOT NULL
Einstellung für die Spalte und machen Sie sie in der ALTER-Anweisung oben gleich, sonst könnte sie geändert werden, da der StandardwertNULL
ist falls nicht angegeben. -
Wenn Sie das Schema der Tabelle nicht ändern können und eine regelmäßige "Bereinigung" der fehlerhaften Daten durchführen müssen, können Sie Folgendes ausführen:
;WITH cte AS ( SELECT * FROM TableName WHERE [PostalCode] <> CONVERT(NVARCHAR(50), CONVERT(VARCHAR(50), [PostalCode])) ) UPDATE cte SET cte.[PostalCode] = REPLACE(CONVERT(VARCHAR(50), [PostalCode]), '?', '');
Bitte beachten Sie, dass die obige Abfrage nicht effizient funktionieren soll, wenn die Tabelle Millionen von Zeilen enthält. An diesem Punkt müsste es in kleineren Sätzen über eine Schleife gehandhabt werden.
Als Referenz finden Sie hier den Wikipedia-Artikel für Postleitzahl , die derzeit besagt, dass die einzigen jemals verwendeten Zeichen sind:
Und bezüglich der maximalen Größe des Feldes, hier ist die Wikipedia Liste der Postleitzahlen