SQL服务器 - 将varchar转换为其它归类(代码页)来解决字符编码

问题描述 投票:19回答:4

我询问使用该SQL_Latin1_General_CP850_BIN2归类的SQL Server数据库。一个表中的行具有与包括+/-字符(十进制代码177在Windows 1252代码页)的值的VARCHAR。

当我在SQL Server Management Studio中直接查询表,我得到一个乱码字符,而不是在此行中的+/-字符。当使用该表中的SSIS包源,目的地表(它使用典型SQL_Latin1_General_CP1_CI_AS核对),用正确的字符+/-结束。

我现在要建立一个直接查询源表而不SSIS的机制。如何做到这一点的方式,我得到了正确的字符,而不是废话吗?我的猜测是,我需要转换/转换列到SQL_Latin1_General_CP1_CI_AS排序规则,但不工作,我不断收到存在乱码。

我试过,没有运气如下:

select 
columnName collate SQL_Latin1_General_CP1_CI_AS
from tableName

select 
cast (columnName as varchar(100)) collate SQL_Latin1_General_CP1_CI_AS
from tableName

select 
convert (varchar, columnName) collate SQL_Latin1_General_CP1_CI_AS
from tableName

我究竟做错了什么?

sql-server character-encoding collation
4个回答
13
投票

字符集转换在数据库连接级别隐式进行。您可以强制自动转换掉在ODBC或ADODB连接字符串参数“自动翻译=假”。不建议这样做。请参阅:https://msdn.microsoft.com/en-us/library/ms130822.aspx

已经有一个代码页不兼容SQL Server 2005中,当数据库和客户端的代码页不匹配。 https://support.microsoft.com/kb/KbView/904803

SQL-管理控制台2008年和向上是Unicode应用程序。进入或要求所有的值都被解释为这样的应用水平。谈话从列排序规则是隐式进行。您可以验证这一点:

SELECT CAST(N'±' as varbinary(10)) AS Result

这将返回0xB100这是Unicode字符U + 00B1(在管理控制台窗口中输入)。您无法关闭“自动翻译”为管理工作室。

如果您在选择指定不同的归类,则最终在双转换(可能丢失数据)结束了,只要“自动翻译”仍然有效。原来的字符首先转换成在选择新的归类,进而获得“自动翻译”,以“正确”的应用程序的代码页。这就是为什么你的各种整理的测试仍然显示所有相同的结果。

您可以验证指定的排序规则确实有效果的选择,如果你把结果作为VARBINARY代替VARCHAR,因此它呈现之前在SQL Server转型不是由客户端失效:

SELECT cast(columnName COLLATE SQL_Latin1_General_CP850_BIN2 as varbinary(10)) from tableName
SELECT cast(columnName COLLATE SQL_Latin1_General_CP1_CI_AS as varbinary(10)) from tableName

这将让你0xF1或分别0xB1如果columnName只包含字符“±”

你仍然可以得到正确的结果,但错误的字符,如果你正在使用的字体不提供适当的字形。

请仔细检查你的角色的实际内部表示铸造查询到VARBINARY在一个适当的样品并验证该代码是否确实对应于定义的数据库排序规则SQL_Latin1_General_CP850_BIN2

SELECT CAST(columnName as varbinary(10)) from tableName

只要在应用程序整理和数据库排序规则差异可能被忽视,作为转换进行时,总是以同样的方式进出。为你增添一份客户端不同的排序规则的麻烦尽快出现。然后,你可能会发现,内部转换是无法将字符正确匹配。

说了这么多,你应该记住,Management Studio中解释结果集时通常不是最后的参考。即使它看起来杂乱在MS,它可能仍然是正确的输出。现在的问题是记录是否在应用程序中正确显示。


5
投票

必须使用转换,不投:

SELECT
 CONVERT(varchar(50), N'æøåáäĺćçčéđńőöřůýţžš')
 COLLATE Cyrillic_General_CI_AI

(Qazxswpoi)


1
投票

我们可能需要更多的信息。下面是我做的重现SQL Server 2008上:

http://blog.sqlpositive.com/2010/03/using-convert-with-collate-to-strip-accents-from-unicode-strings/

结果显示原始字符。在查询声明整理应返回从SQL Server的角度来看,正确的字符但它可能是表示层,然后转换成类似UTF-8又不同的情况。


1
投票

尝试:

CREATE DATABASE [Test] ON  PRIMARY 
    ( 
    NAME = N'Test'
    , FILENAME = N'...Test.mdf' 
    , SIZE = 3072KB 
    , FILEGROWTH = 1024KB 
    )
    LOG ON 
    ( 
    NAME = N'Test_log'
    , FILENAME = N'...Test_log.ldf' 
    , SIZE = 1024KB 
    , FILEGROWTH = 10%
    )
    COLLATE SQL_Latin1_General_CP850_BIN2
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MyTable]
    (
    [SomeCol] [varchar](50) NULL
    ) ON [PRIMARY]
GO
Insert MyTable( SomeCol )
Select '±' Collate SQL_Latin1_General_CP1_CI_AS
GO
Select SomeCol, SomeCol Collate SQL_Latin1_General_CP1_CI_AS
From MyTable
© www.soinside.com 2019 - 2024. All rights reserved.