Ram*_*ale 4 t-sql sql-server unicode collation character-encoding
我在NVarchar名为“邮政编码”的字段中有一些 Unicode 字符。当我将它们转换为 时,结果中Varchar有一个。?
我的代码是:
select PostalCode, cast((PostalCode) as varchar)) as val from table
Run Code Online (Sandbox Code Playgroud)
结果是:
PostalCode | val
053000 | 053000?
Run Code Online (Sandbox Code Playgroud)
在这里我得到了?结果。有什么办法可以删除这些特殊字符吗?
这里有几点需要注意:
如果您想准确查看其中有哪个字符,可以将值转换为该值,VARBINARY该值将为您提供字符串中所有字符的十六进制/二进制值,并且十六进制中没有“隐藏”字符的概念:
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];
Run Code Online (Sandbox Code Playgroud)
返回:
NVarCharValue VarCharValue RTrimmedVarCharValue VarBinaryValue
053000 053000? 053000? 0x3000350033003000300030000820
Run Code Online (Sandbox Code Playgroud)
NVARCHAR数据以 UTF-16 格式存储,以 2 字节集工作。查看最后 4 个十六进制数字来查看隐藏的 2 字节集是什么,我们看到“0820”。由于Windows和SQL Server是UTF-16 Little Endian(即UTF-16LE),因此字节顺序相反。翻转最后 2 个字节——08然后20——我们得到“2008”,这是我们通过添加的“标点符号空间” NCHAR(0x2008)。
另外,请注意,这RTRIM根本没有帮助。
简单地说,您可以将问号替换为任何内容:
SELECT REPLACE(CONVERT(VARCHAR(20), [PostalCode]), '?', '');
Run Code Online (Sandbox Code Playgroud)更重要的是,您应该将该[PostalCode]字段转换为VARCHAR,以便它不存储这些字符。没有哪个国家/地区使用未在 ASCII 字符集中表示的字母,并且这些字母对 VARCHAR 数据类型无效,至少就我所读到的而言是如此(请参阅底部部分以获取参考资料)。事实上,允许的是 ASCII 的一个相当小的子集,这意味着您可以轻松地过滤(或者REPLACE在插入或更新时执行与上面所示相同的操作):
ALTER TABLE [table] ALTER COLUMN [PostalCode] VARCHAR(20) [NOT]? NULL;
Run Code Online (Sandbox Code Playgroud)
请务必检查该列的当前NULL/NOT NULL设置,并使其与上面的 ALTER 语句中的设置相同,否则NULL如果未指定,则可能会更改为默认值。
如果您无法更改表的架构并且需要定期“清理”坏数据,您可以运行以下命令:
;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]), '?', '');
Run Code Online (Sandbox Code Playgroud)
请记住,如果表有数百万行,上述查询就无法高效工作。那时,需要通过循环以较小的集合进行处理。
作为参考,这里是关于邮政编码的维基百科文章,其中目前指出曾经使用的唯一字符是:
- 阿拉伯数字“0”到“9”
- ISO 基本拉丁字母表中的字母
- 空格、连字符
关于字段的最大大小,这里是维基百科邮政编码列表
| 归档时间: |
|
| 查看次数: |
19821 次 |
| 最近记录: |