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
VARBINARYcož 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? 0x3000350033003000300030000820NVARCHARdata 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ů --08a20-- dostaneme "2008", což je "mezera pro interpunkci", kterou jsme přidali pomocíNCHAR(0x2008).Vezměte prosím na vědomí, že
RTRIMzde 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 naVARCHARaby 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éREPLACEjak 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 NULLnastavení pro sloupec a udělejte jej stejné v příkazu ALTER výše, jinak by se mohlo změnit, protože výchozí jeNULLpokud 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