SQL:将列中的 Unicode 数据更新为重音字符

Posted

技术标签:

【中文标题】SQL:将列中的 Unicode 数据更新为重音字符【英文标题】:SQL: Update Unicode Data in column to Accented characters 【发布时间】:2019-01-11 12:25:51 【问题描述】:

我有一列设置为 Varchar,数据库设置为 SQL_Latin1_General_CP1_CI_AS。

当用户在我们的网络前端输入他们的名字并保存数据时,它没有正确保存重音字符。

网络用户输入了以下内容,“Béala”,但它被保存在数据库中,如下所示,“Béala”。

我相信将列从 Varchar 更改为 NVarchar 应该可以防止这种情况继续发生(?),但是,我有两个问题。

1) 如何对列中的现有数据进行选择并正确显示?

select CONVERT(NVARCHAR(100),strAddress1) from [dbo].[tblCustomer]

这仍然无法正确显示数据。

2) 转换为 NVarchar 后如何更新列中的数据以正确保存重音字符?

非常感谢, 雷。

【问题讨论】:

@a_horse_with_no_name - 感谢您对标签的更改建议。 您的应用程序已保存 mojibake -- UTF-8 编码数据存储为 Windows-1252 编码字符串。在 SQL Server 2019 之前,引擎根本不支持 UTF-8,因此在纯 T-SQL 中修复这个问题基本上是不可能的。在 .NET 中,您可以使用 Encoding.UTF8.GetString(Encoding.GetEncoding("Windows-1252").GetBytes("Béala")) 解决此问题。将存储类型更改为 NVARCHAR 可能 会使客户端应用程序正常工作,但实际上您可能会得到相同的、错误编码的结果(或不同的损坏)。您可能需要修复数据发送到数据库的方式。 好的,所以我对“不可能”的说法是错误的——只是very cumbersome,但有人已经完成了这项工作。不过,这只是为了修复存储不正确的数据——它不应用于解决客户端的问题,它需要自己修复。 【参考方案1】:

我想到的唯一想法是你必须准备一个更新来欺骗这个加载严重的数据,即一个标志 'é' 将始终匹配一个字符(在本例中为 'é'),您必须捕获所有特殊字符,并且 已更改(只是带有案例和替换的简单更新)。当然,第一列必须是 nvarchar 类型。 它解决了问题1和2(表格中的数据会正确,数据会正确显示,我在上面描述了更新)

【讨论】:

【参考方案2】:

这是在普通字符方案中获取它的方法。

select 'Réunion', cast('Réunion' as varchar(100)) COLLATE SQL_Latin1_General_CP1253_CI_AI

此外,要检查 SQL Server 中所有可能的排序规则,您可以尝试此查询


SELECT name, description
  FROM sys.fn_helpcollations();

【讨论】:

问题不是“我们如何去除拉丁字符的重音符号”。 Réunion 可以无损地存储在 SQL_Latin1_General_CP1_CI_AS 中。即使我们想去除重音符号,这仍然无法对现有数据做任何事情——它只会将其进一步破坏到BA©ala。列排序规则不是这里的问题。 那行不通。 select 'Béala', cast('Béala' as varchar(100)) COLLATE SQL_Latin1_General_CP1253_CI_AI获得以下BA©ala

以上是关于SQL:将列中的 Unicode 数据更新为重音字符的主要内容,如果未能解决你的问题,请参考以下文章

将列更新为连接列中的值

SQL 将列值拆分为 Netezza 中的行

SQL Server,将列中的所有值与另一个值的一些值连接起来

SQL将列中的所有行设置为其他列的倍数

将列中的唯一值分隔到同一数据框中的单独列中

如何将列中的连接值转置为行