SQL Server - конвертируйте varchar в другое сопоставление (кодовую страницу) для исправления кодировки символов - PullRequest
19 голосов
/ 11 ноября 2011

Я запрашиваю базу данных SQL Server, которая использует параметры сортировки SQL_Latin1_General_CP850_BIN2.В одной из строк таблицы есть varchar со значением, включающим символ +/- (десятичный код 177 в кодовой странице Windows-1252).

Когда я запрашиваю таблицу непосредственно в 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

Что я делаю не так?

Ответы [ 4 ]

12 голосов
/ 16 февраля 2015

Преобразование набора символов выполняется неявно на уровне соединения с базой данных. Вы можете принудительно отключить автоматическое преобразование в строке подключения ODBC или ADODB с помощью параметра «Auto Translate = False». Это НЕ рекомендуется. Смотри: https://msdn.microsoft.com/en-us/library/ms130822.aspx

В SQL Server 2005 была несовместимость кодовых страниц, когда база данных и клиентская кодовая страница не совпадали. https://support.microsoft.com/kb/KbView/904803

SQL-Management Console 2008 и выше является приложением UNICODE. Все введенные или запрошенные значения интерпретируются как таковые на уровне приложения. Разговор с сопоставлением столбцов выполняется неявно. Вы можете проверить это с помощью:

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

Это вернет 0xB100, который является символом Unicode U + 00B1 (как введено в окне консоли управления). Вы не можете отключить «Автоматический перевод» для Management Studio.

Если вы укажете другую сортировку в выборе, вы в конечном итоге окажетесь в двойном преобразовании (с возможной потерей данных), пока «Автоматический перевод» все еще активен. Оригинальный символ сначала преобразуется в новое сопоставление во время выбора, который, в свою очередь, получает «Автоматический перевод» на «правильную» кодовую страницу приложения. Вот почему ваши различные тесты COLLATION показывают одинаковый результат.

Вы можете проверить, что указание параметров сортировки влияет на выбор, если вы приведете результат как 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, это все равно может быть правильным выводом. Вопрос в том, правильно ли отображаются записи в ваших приложениях.

4 голосов
/ 11 февраля 2016

Должен использоваться конвертировать, а не сотворять:

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

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

1 голос
/ 30 апреля 2015

попробуй:

SELECT CAST( CAST([field] AS VARBINARY) AS varchar) 
1 голос
/ 11 ноября 2011

Нам может понадобиться больше информации. Вот что я сделал для воспроизведения на SQL Server 2008:

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

Результаты показывают оригинальный персонаж. Объявление параметров сортировки в запросе должно возвращать надлежащий символ с точки зрения SQL Server, однако может случиться так, что уровень представления затем преобразуется во что-то еще отличное от UTF-8.

...