Невозможно правильно перевести символьные данные с клиента на сервер с помощью драйвера ODBC SQL Server, если кодовая страница клиента отличается от кодовой страницы сервера

Эта статья поможет вам обойти проблему, которая приводит к неправильному преобразованию данных клиента при использовании драйвера ODBC SQL Server.

Оригинальная версия продукта: SQL Server
Исходный номер базы знаний: 234748

Симптомы

При использовании MDAC 2.1 или более поздней версии драйвера SQL SERVER ODBC (версии 3.70.0623 или более поздней) или поставщика OLEDB (версии 7.01.0623 или более поздней) в некоторых случаях может возникнуть преобразование символьных данных из клиентской кодовой страницы в кодовую страницу сервера, даже если Autotranslation подключение отключено.

Причина

Autotranslation — это не единственный механизм, который может привести к преобразованию кодовой страницы. Драйвер ODBC SQL Server 7.0 и поставщик OLEDB представляют новое поведение при подключении к MSDE 1.0, SQL Server 7.0 или более поздних версий. Все инструкции SQL, отправленные в качестве языкового события, преобразуются в Юникод на клиенте перед отправкой на сервер. Конечный эффект аналогичен значению Autotranslation для всех данных, передаваемых от клиента на сервер через языковое событие, независимо от текущего Autotranslation параметра подключения. Это не приведет к возникновению каких-либо трудностей, за исключением попыток хранения непереводимых символьных данных с кодовой страницы, отличной от кодовой страницы SQL Server.

Обходной путь

Не храните данные кодовой страницы X в кодовой странице Y SQL Server (например, данные кодовой страницы 950 на сервере кодовой страницы 1252). Хотя в некоторых случаях это было возможно в предыдущих версиях SQL Server, оно всегда не поддерживалось. Для 1252 SQL Server все символы, кроме 1252 символов, недопустимы. Символьные данные, не относящиеся к Юникоду, с другой кодовой страницы будут отсортированы неправильно, а в случае с данными с двумя байтами (DBCS) SQL Server неправильно распознает границы символов. Это может привести к значительным проблемам.

Лучшим выбором для кодовой страницы SQL Server является кодовая страница клиентов, которые будут обращаться к серверу.

Сервер и клиент могут иметь разные кодовые страницы, но необходимо убедиться, что на клиенте включена автоматическая передача, чтобы во всех случаях получать правильный перевод данных на кодовую страницу сервера и с нее.

Если сервер должен хранить данные с нескольких кодовой страницы, поддерживаемое решение заключается в хранении данных в столбцах Юникода (NCHAR/NVARCHAR/NTEXT).

Если в вашей ситуации требуется хранить данные кодовой страницы X в кодовой странице Y SQL Server, это можно сделать только двумя способами:

  • Храните данные в столбцах двоичных столбцов (BINARY/VARBINARY/IMAGE).
  • Напишите приложение для использования удаленных вызовов процедур (RPC) для всех инструкций SQL, которые используют символьные данные. Данные, отправляемые через событие RPC, не подлежат преобразованию. На уровне драйвера или DSN нет никаких действий, которые можно сделать, чтобы изменить тип отправляемых событий. Отправка команды в виде языка или события RPC полностью зависит от API-интерфейсов и синтаксиса, выбранных программистом при написании приложения.

Дополнительная информация

Автоматическая передача (т. е. флажки Выполнить преобразование символьных данных в новых приложениях ODBC) преобразует символьные данные из клиентской кодовой страницы в кодовую страницу сервера перед отправкой данных на сервер, используя Юникод в качестве носителя перевода. Однако драйвер ODBC версии 3.7 SQL Server также преобразует все инструкции SQL, отправленные в качестве языкового события, в Юникод перед их размещением на проводной связи, что имеет эффект, аналогичный автоматической отправке, но не регулируется параметром Автопередача. В отличие от этого, символьные данные, передаваемые с сервера обратно клиентам, соблюдают флаг автопередажи. Если автопередача отключена, данные поступают в клиентское приложение с теми же кодами символов, что и данные на сервере. Аналогичным образом преобразование данных для событий RPC клиента на сервер можно отключить, отключив автоматическую передачу. Ниже приведен простой сценарий, демонстрирующий, как поведение влияет на события языка. Этот пример был выполнен из анализатора запросов на кодовой странице клиента 1252, подключающегося к серверу кодовой страницы 437:

-- Turn Autotranslation off here.
 USE tempdb
 GO
 CREATE TABLE t1 (c1 int, c2 char(1))
 GO

-- Enter a yen character, using the keystroke ALT-0165.
 INSERT INTO t1 VALUES (1, '¥') 
 SELECT c1, c2, ASCII (c2) FROM t1
c1 c2 
 ----------- ---- ----------- 
 1  157

(1 row(s) affected)

В приведенном выше примере приведено следующее:

  • Несмотря на то, что Autotranslation этот пакет был отключен, код символа 165 (иена на кодовой странице 1252) был преобразован в 157 (иена на кодовой странице 437). Это связано с тем, что драйвер ODBC преобразовал строку SQL в Юникод перед отправкой на сервер, поэтому сервер смог преобразовать ее в соответствующий символ для хранения на кодовой странице 437.
  • Когда клиент запустил SELECT для получения сохраненных данных, символ 157 поступил непереводимым на клиент (157 отображается как поле "" на кодовой странице клиента 1252). Это связано с тем, что преобразование, описанное в этой статье, применяется только к данным, отправленным с клиента на сервер, а не с сервера клиенту. Данные не были переведены, Autotranslation так как параметр отключен.
-- Turn Autotranslation back on before running the following batch.
 INSERT INTO t1 VALUES (2, '¥')
 SELECT c1, c2, ASCII (c2) FROM t1
c1 c2 
 ----------- ---- ----------- 
 1 ¥ 157
 2 ¥ 157

(2 row(s) affected)

В этом случае включение Autotranslation не повлияло на перевод с клиента на сервер (то есть произошел тот же правильный перевод из символьного кода 165 в код символа 157), но это повлияло на данные, полученные с сервера. При выполнении инструкции SELECT на этот раз (с Autotranslation включено), символы иены правильно отображаются на кодовой странице приложения 1252, так как механизм перевел их из символьного кода 157 обратно в код символа 165 Autotranslation .

Это поведение (преобразование языковых событий в Юникод на клиенте) будет отображаться при использовании любого SQL Server драйвера ODBC версии 3.70 или более поздней и при подключении к SQL Server 7.0 или более поздней версии. Это не произойдет при использовании более старых драйверов ODBC или при использовании драйвера 3.7 для подключения к SQL Server 6.5 или более ранней версии. Кроме того, если данные хранятся в столбцах Юникода (NCHAR/NVARCHAR/NTEXT), преобразование не будет проблемой.

Дополнительные сведения о том, как символьные данные представлены в SQL Server 2005 г., см. в статье Символьные данные представлены неправильно, если кодовая страница клиентского компьютера отличается от кодовой страницы базы данных в SQL Server 2005 г.