При интеграции «1С:Предприятия» с внешними базами данных часто используются прямые SQL-запросы через механизмы Microsoft ADO (ActiveX Data Objects). Однако разработчики регулярно сталкиваются со следующей проблемой: соединение устанавливается успешно, запрос выполняется без ошибок, но при попытке прочитать строковые данные из таблиц СУБД Oracle вместо привычной кириллицы выводятся знаки вопроса (?). Для изучения типовых сценариев настройки прямых запросов можно использовать руководство по подключению и получению данных из SQL в 1С.
В этой статье мы подробно разберем, почему возникает эта проблема, как функционируют кодировки в клиенте Oracle и какие конкретные шаги необходимо предпринять для восстановления корректного отображения русских символов в 1С.
Появление знаков вопроса вместо букв — это классический симптом рассинхронизации кодировок между сервером базы данных Oracle, установленным клиентом Oracle (Oracle Client) на машине с 1С и самим приложением «1С:Предприятие».
Когда вы выполняете запрос из 1С через COM-объект ADODB.Connection, цепочка передачи данных выглядит следующим образом:
AL32UTF8 или CL8MSWIN1251).ASCII (которая не поддерживает русские символы). В результате все символы за пределами стандартной латиницы превращаются в нечитаемые знаки вопроса.Для управления поведением клиента Oracle используется ключевой параметр — NLS_LANG. Именно он сообщает драйверу, в каком языковом стандарте и в какой кодовой странице нужно возвращать текстовые данные.
Рассмотрим по шагам все возможные способы решения этой проблемы в зависимости от используемой архитектуры и прав доступа.
Наиболее надежный и проверенный способ решить проблему с кодировкой — жестко задать системную переменную среды NLS_LANG на компьютере, где выполняется код 1С (это может быть либо локальный компьютер пользователя, либо сервер приложений 1С).
Формат значения переменной NLS_LANG выглядит так:
[Язык]_[Территория].[Кодировка]
Для русскоязычных пользователей Windows наиболее стабильным и подходящим значением является:
AMERICAN_AMERICA.CL8MSWIN1251 или RUSSIAN_RUSSIA.CL8MSWIN1251
Разберем процесс настройки по шагам:
sysdm.cpl в строке «Выполнить» (Win + R).NLS_LANG.AMERICAN_AMERICA.CL8MSWIN1251.КРИТИЧЕСКИ ВАЖНО: Если код подключения к Oracle выполняется на стороне сервера 1С (например, в фоновом задании или в серверном модуле), изменения в системных переменных среды не вступят в силу автоматически! Служба сервера 1С («1С:Предприятие 8.3 Сервер») кэширует переменные окружения при своем запуске. Вам необходимо полностью перезапустить службу srv1cv83 (ragent) через оснастку services.msc, иначе 1С продолжит считывать старое окружение, и знаки вопроса не исчезнут.
Если вы не хотите создавать глобальную системную переменную окружения, можно настроить параметр локально для конкретного установленного клиента Oracle через системный реестр Windows.
Здесь важно учитывать разрядность операционной системы, разрядность платформы 1С и разрядность установленного клиента Oracle. Разберем два сценария:
Откройте редактор реестра regedit и перейдите по следующему пути:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_[Имя_Вашего_Окружения_Oracle]
Найдите параметр с именем NLS_LANG и установите его значение в AMERICAN_AMERICA.CL8MSWIN1251.
Если у вас используется 32-битный сервер 1С (или вы запускаете толстого/тонкого клиента в 32-битной версии), то 32-битный драйвер Oracle обращается к другой ветке реестра:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_[Имя_Вашего_Окружения_Oracle]
Точно так же измените значение строкового параметра NLS_LANG на AMERICAN_AMERICA.CL8MSWIN1251.
Примечание: Системная переменная среды (Решение 1) всегда имеет более высокий приоритет, чем настройки реестра (Решение 2). Если задана системная переменная, Oracle проигнорирует настройки реестра.
В исходном коде для связи с СУБД использовался ODBC-драйвер: Driver={Oracle in OraDb12g_home1}. Этот подход имеет ряд ограничений в современных информационных системах на базе 1С. Более надежным, современным и производительным решением является использование нативного OLE DB провайдера от Oracle — OraOLEDB.Oracle.
Преимущества перехода на OLE DB:
tnsnames.ora (технология TNS-less).Проанализируем пример кода с использованием OLE DB провайдера, который решает проблему с кодировкой и упрощает администрирование:
Соединение = Новый COMОбъект("ADODB.Connection");
// Формируем строку подключения по технологии TNS-less без использования tnsnames.ora
СтрокаПодключения = "Provider=OraOLEDB.Oracle;" +
"Data Source=(DESCRIPTION=" +
"(ADDRESS=(PROTOCOL=TCP)(HOST=" + ИмяСервера + ")(PORT=" + Порт + "))" +
"(CONNECT_DATA=(SERVICE_NAME=" + ИмяСлужбы + ")));" +
"User Id=" + Логин + ";" +
"Password=" + Пароль + ";";
Соединение.ConnectionString = СтрокаПодключения;
Соединение.Open();
ТекстЗапроса = "
|SELECT
| zpu_name AS ""Name""
|FROM PARUS.ZPU_TYPES";
rsRES = Новый COMОбъект("ADODB.Recordset");
rsRES.Open(ТекстЗапроса, Соединение);
Пока rsRES.EOF() = 0 Цикл
Имя = СокрЛП(rsRES.Fields("Name").Value);
Сообщить(Имя);
rsRES.MoveNext();
КонецЦикла;
rsRES.Close();
Соединение.Close();
В последние годы многие компании переводят серверную инфраструктуру 1С на операционную систему Linux. Если сервер 1С работает под Linux и обращается к внешней базе данных Oracle, настройки реестра Windows окажутся абсолютно нерелевантными.
В Linux-среде необходимо передать переменную окружения NLS_LANG непосредственно процессу службы сервера 1С. Сделать это можно следующими способами:
/etc/default/srv1cv83), добавьте в конец файла строку:
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
srv1cv83.service). Добавьте директиву Environment в секцию [Service]:
[Service]
Environment="NLS_LANG=AMERICAN_AMERICA.AL32UTF8"
Важное отличие кодировок для Linux: Обратите внимание, что для Linux-окружения в качестве кодовой страницы клиента рекомендуется указывать современный стандарт AL32UTF8 (UTF-8) вместо устаревшего Windows-1251 (CL8MSWIN1251). Платформа 1С на Linux нативно работает с кодировкой UTF-8, что полностью исключает искажение символов.
Бывают ситуации, когда у разработчика 1С нет административных прав на сервере приложений 1С или СУБД Oracle для изменения системных переменных окружения или реестра Windows. В этом случае проблему со знаками вопроса можно обойти программным путем на уровне сессии базы данных или самого SQL-запроса.
Сразу после открытия ADO-соединения можно принудительно выполнить команды инициализации языковых параметров для конкретной открытой сессии подключения:
Соединение.Open();
// Управляем языком возвращаемых сообщений об ошибках и датами
Соединение.Execute("ALTER SESSION SET NLS_LANGUAGE = 'AMERICAN'");
Соединение.Execute("ALTER SESSION SET NLS_TERRITORY = 'AMERICA'");
Важное ограничение: Команды ALTER SESSION позволяют переопределить формат вывода дат, чисел и язык системных ошибок, но саму кодовую страницу (например, CL8MSWIN1251) изменить в уже открытой сессии СУБД не позволит, так как она жестко инициализируется клиентским драйвером на этапе рукопожатия (handshake) при подключении.
Если кодовая страница базы данных известна (например, данные в таблицах хранятся в формате UTF-8), мы можем заставить саму СУБД Oracle на своей стороне на лету перекодировать текст в нужный нам формат перед тем, как отдать его в ADO-рекордсет 1С. Для этого используется встроенная функция Oracle SQL — CONVERT.
Изменим запрос автора из примера следующим образом:
ТекстЗапроса = "
|SELECT
| CONVERT(zpu_name, 'CL8MSWIN1251', 'AL32UTF8') AS ""Name""
|FROM PARUS.ZPU_TYPES";
Параметры функции CONVERT(string, dest_char_set, [source_char_set]) означают:
zpu_name — преобразуемое поле таблицы.'CL8MSWIN1251' — кодировка назначения, которую гарантированно воспримет драйвер ADO на стороне 1С.'AL32UTF8' — текущая кодировка, в которой данные хранятся на сервере СУБД Oracle (опционально, если она отличается от базовой).Этот способ позволяет гарантированно получить читаемый русский текст без внесения каких-либо настроек в реестр или системные переменные операционной системы Windows / Linux.
Мы проанализировали причины искажения кириллицы при интеграции 1С и Oracle. Для предотвращения появления знаков вопроса придерживайтесь следующих правил:
NLS_LANG со значением AMERICAN_AMERICA.CL8MSWIN1251 и последующий обязательный перезапуск службы 1С.OraOLEDB.Oracle.NLS_LANG=AMERICAN_AMERICA.AL32UTF8 через конфигурационные файлы systemd служб 1С.CONVERT для трансформации кодировок прямо в тексте запроса.