SQL Server链接服务器到PostgreSQL土耳其语字符问题

时间:2016-10-12 19:54:20

标签: sql-server postgresql character-encoding collation linked-server

我在this blog post的帮助下向我的SQL Server添加了一个PostgreSQL链接服务器。我的问题是当我使用下面的查询时,我遇到土耳其字符问题。

在Microsoft SQL Server 2012上查询:

SELECT * 
FROM OpenQuery(CARGO, 'SELECT taxno  ASACCOUNTNUM, title AS NAME FROM view_company');

实际结果:

  

MUSTAFAÞAHÝNALP

预期结果:

  

MUSTAFAŞAHİNALP

1 个答案:

答案 0 :(得分:1)

问题是源编码是使用Code Page 1254 - Windows Latin 5 (Turkish)的8位扩展ASCII。如果您按照该链接,您将看到Latin5字符图表的值。 Ş字符的价值 - "拉丁语大写字母S与Cedilla" - 222 (十进制)/ DE (十六进制)。您的本地服务器(即SQL Server)的默认排序规则为SQL_Latin1_General_CP1_CI_AS,它也是8位扩展ASCII,但使用代码页1252 - Windows Latin 1 (ANSI)。如果您关注该链接,您将看到显示Þ字符的拉丁文1图表 - "拉丁文大写字母刺" - 也具有 222 (十进制)/ DE (十六进制)的值。这就是你的角色以这种方式翻译的原因。

您可以尝试一些事项:

  1. 使用sp_serveroption设置以下两个选项:

    EXEC sp_serveroption @server=N'linked_server_name',
                         @optname='use remote collation',
                         @optvalue=N'true';
    
    EXEC sp_serveroption @server=N'linked_server_name',
                         @optname='collation name',
                         @optvalue=N'Turkish_100_CI_AS';
    

    不确定这是否适用于PostgreSQL作为远程系统,但它至少值得尝试。请注意,这要求将所有远程列排序规则设置为此特定值:土耳其语/代码页1254。

  2. 强制每列的整理:

    SELECT [ACCOUNTNUM], [NAME] COLLATE Turkish_100_CI_AS
    FROM   OPENQUERY(CARGO, 'SELECT taxno AS ACCOUNTNUM, title AS NAME FROM view_company');
    
  3. 将字符串值(只是具有字符映射问题的值)转换为VARBINARY并插入临时表,其中列设置为正确的排序规则:

    CREATE TABLE #Temp ([AccountNum] INT, [Name] VARCHAR(100) COLLATE Turkish_100_CI_AS);
    
    INSERT INTO #Temp ([AccountNum], [Name])
      SELECT [ACCOUNTNUM], CONVERT(VARBINARY(100), [NAME])
      FROM  OPENQUERY(CARGO, 'SELECT taxno AS ACCOUNTNUM, title AS NAME FROM view_company');
    
    SELECT * FROM #Temp;
    

    此方法首先将传入的字符转换为二进制/十六进制表示(例如Ş - > 0xDE),然后将0xDE插入{{1}在临时表中,它会将VARCHAR转换为代码页的值的预期字符(因为那是该列的排序规则)。结果将是0xDE而不是Ş

  4. <强>更新

    选项#1适用于O.P。