我在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
答案 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 (十六进制)的值。这就是你的角色以这种方式翻译的原因。
您可以尝试一些事项:
使用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。
强制每列的整理:
SELECT [ACCOUNTNUM], [NAME] COLLATE Turkish_100_CI_AS
FROM OPENQUERY(CARGO, 'SELECT taxno AS ACCOUNTNUM, title AS NAME FROM view_company');
将字符串值(只是具有字符映射问题的值)转换为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
而不是Ş
。
<强>更新强>
选项#1适用于O.P。