Zde je několik věcí, které je třeba poznamenat:
-
Pokud chcete přesně vidět, který znak tam je, můžete hodnotu převést na
VARBINARY
což vám dá hexadecimální / binární hodnotu všech znaků v řetězci a neexistuje žádný koncept "skrytých" znaků v 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];
Vrátí:
NVarCharValue VarCharValue RTrimmedVarCharValue VarBinaryValue 053000 053000? 053000? 0x3000350033003000300030000820
NVARCHAR
data jsou uložena jako UTF-16, které funguje ve 2bajtových sadách. Když se podíváme na poslední 4 hexadecimální číslice, abychom viděli, co je skrytá 2bajtová sada, vidíme „0820“. Protože Windows a SQL Server jsou UTF-16 Little Endian (tj. UTF-16LE), jsou bajty v obráceném pořadí. Otočení posledních 2 bajtů --08
a20
-- dostaneme "2008", což je "mezera pro interpunkci", kterou jsme přidali pomocíNCHAR(0x2008)
.Vezměte prosím na vědomí, že
RTRIM
zde vůbec nepomohlo. -
Zjednodušeně můžete otazníky nahradit ničím:
SELECT REPLACE(CONVERT(VARCHAR(20), [PostalCode]), '?', '');
-
Ještě důležitější je, že byste měli převést
[PostalCode]
pole naVARCHAR
aby tyto znaky neukládal. Žádná země nepoužívá písmena, která nejsou zastoupena ve znakové sadě ASCII a která nejsou platná pro datový typ VARCHAR, alespoň pokud jsem o tom kdy četl (odkazy viz spodní část). Ve skutečnosti je povolena poměrně malá podmnožina ASCII, což znamená, že můžete snadno filtrovat na cestě dovnitř (nebo prostě udělat to saméREPLACE
jak je uvedeno výše při vkládání nebo aktualizaci):ALTER TABLE [table] ALTER COLUMN [PostalCode] VARCHAR(20) [NOT]? NULL;
Nezapomeňte zkontrolovat aktuální hodnotu
NULL
/NOT NULL
nastavení pro sloupec a udělejte jej stejné v příkazu ALTER výše, jinak by se mohlo změnit, protože výchozí jeNULL
pokud není uvedeno. -
Pokud nemůžete změnit schéma tabulky a potřebujete provádět pravidelné „čištění“ od špatných dat, můžete spustit následující:
;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]), '?', '');
Mějte prosím na paměti, že výše uvedený dotaz nemá fungovat efektivně, pokud má tabulka miliony řádků. V tom okamžiku by to muselo být zpracováno v menších sadách pomocí smyčky.
Zde je článek na wikipedii pro PSČ , který v současnosti uvádí, že jediné kdy byly použity znaky:
A pokud jde o maximální velikost pole, zde je Wikipedia seznam poštovních směrovacích čísel