При интеграции современных конфигураций 1С с устаревшими СУБД, такими как MS SQL Server 2000, разработчики регулярно сталкиваются с аппаратными и программными барьерами. Попытки настроить прямое подключение со современных рабочих станций под управлением 64-разрядных версий Windows часто приводят к ошибкам инициализации драйверов, отказу сетевых библиотек или системным сбоям безопасности.
В этой статье мы подробно разберем, как правильно подружить платформу 1С с базой данных MS SQL Server 2000, проанализируем причины возникновения популярных ошибок и предоставим готовые протестированные примеры кода.
Первое, что нам необходимо понять — это архитектура запускаемого процесса. Среда выполнения COM-объектов Windows (в частности, технологии ADO) напрямую зависит от разрядности родительского процесса, который их порождает.
Если на 64-разрядной операционной системе Windows вы используете 32-разрядного клиента 1С (что подтверждается наличием суффикса *32 рядом с процессом в Диспетчере задач), то COM-объект ADODB.Connection сможет обращаться исключительно к 32-битным драйверам баз данных. Наоборот, 64-разрядный клиент 1С потребует строго 64-разрядных драйверов СУБД.
Классический встроенный провайдер SQLOLEDB (системный драйвер, входящий в состав Windows по умолчанию) отлично работает "из коробки" на 32-разрядных клиентах. Однако, если перед нами стоит задача запустить обмен на 64-разрядном сервере или клиенте 1С, стандартного драйвера в системе может не оказаться, либо его работа будет нестабильной. В этом случае нам потребуется установка внешнего программного обеспечения — SQL Server Native Client.
Важное ограничение совместимости:
MSOLEDBSQL) принципиально не поддерживают соединение с MS SQL Server 2000. Попытка их использования приведет к ошибкам аутентификации или несовместимости протоколов.Рассмотрим распространенную ошибку, возникающую при попытке выполнить SQL-запрос через ADO. При написании кода инициализации подключения разработчики часто используют старый "ODBC-стиль" формирования строки подключения:
ConnectionString = "driver={SQL Server};server=192.168.1.128\server;uid=sa;pwd=pass;database=baze;";
При использовании такой строки подключения в коде 1С при попытке связать объект команды с открытым соединением возникает критическое исключение:
Произошла исключительная ситуация (ADODB.Command): Для требуемой операции необходим объект OLE DB Session, не поддерживаемый текущим поставщиком.
Выясним причину этого поведения. Использование конструкции driver={SQL Server} заставляет систему ADO использовать устаревший транслятор-обертку Microsoft OLE DB Provider for ODBC Drivers (провайдер MSDASQL). Этот мост-транслятор не обладает полной поддержкой спецификации OLE DB и не способен корректно обрабатывать сессии для объекта ADODB.Command.
Чтобы решить эту проблему, нам необходимо полностью отказаться от использования ODBC-драйверов в пользу "чистого" провайдера OLE DB. Обратите внимание, что при смене провайдера меняется и синтаксис параметров строки подключения:
driver={...} мы должны явно указать Provider=SQLOLEDB; (или Provider=SQLNCLI10; в случае использования Native Client 2008).SERVER заменяется на Data Source.DATABASE заменяется на Initial Catalog.UID и PWD заменяются на User ID и Password соответственно.Проанализируем правильный шаблон кода для надежного подключения к СУБД и получения результатов запроса:
Функция ВыполнитьЗапросКLegacySQL(ПараметрыСоединения, ТекстЗапроса) Экспорт
// Инициализируем COM-объекты ADO
СоединениеSQL = Новый COMОбъект("ADODB.Connection");
КомандаSQL = Новый COMОбъект("ADODB.Command");
НаборЗаписей = Новый COMОбъект("ADODB.Recordset");
// Устанавливаем таймауты
СоединениеSQL.ConnectionTimeout = 30;
СоединениеSQL.CommandTimeout = 600;
// Формируем правильную строку подключения OLE DB
СтрокаСоединения = "Provider=SQLOLEDB.1;" +
"Data Source=" + ПараметрыСоединения.АдресСервера + ";" +
"Initial Catalog=" + ПараметрыСоединения.ИмяБазы + ";" +
"User ID=" + ПараметрыСоединения.Пользователь + ";" +
"Password=" + ПараметрыСоединения.Пароль + ";";
Попытка
// Открываем соединение
СоединениеSQL.Open(СтрокаСоединения);
// Настраиваем команду для выполнения запроса
КомандаSQL.ActiveConnection = СоединениеSQL;
КомандаSQL.CommandText = ТекстЗапроса;
// Выполняем запрос
НаборЗаписей = КомандаSQL.Execute();
Исключение
ВызватьИсключение "Ошибка при работе с СУБД: " + ОписаниеОшибки();
КонецПопытки;
// Переносим данные в ТаблицуЗначений 1С
ТаблицаРезультат = Новый ТаблицаЗначений;
Если Не НаборЗаписей.EOF Тогда
// Создаем колонки в соответствии со структурой полей БД
Для Каждого Поле Из НаборЗаписей.Fields Цикл
// Типизируем дату, остальные поля принимаем как строку для универсальности
Если ВРег(Поле.Name) = "DATE" Тогда
ТаблицаРезультат.Колонки.Добавить(Поле.Name, Новый ОписаниеТипов("Дата"));
Иначе
ТаблицаРезультат.Колонки.Добавить(Поле.Name, Новый ОписаниеТипов("Строка"));
КонецЕсли;
КонецЦикла;
НаборЗаписей.MoveFirst();
КонецЕсли;
// Заполняем таблицу строками
Пока Не НаборЗаписей.EOF Цикл
НоваяСтрока = ТаблицаРезультат.Добавить();
Для Каждого Поле Из НаборЗаписей.Fields Цикл
НоваяСтрока[Поле.Name] = Поле.Value;
КонецЦикла;
НаборЗаписей.MoveNext();
КонецЦикла;
// Закрываем активное соединение
СоединениеSQL.Close();
Возврат ТаблицаРезультат;
КонецФункции
Если при попытке выполнить метод Open() вы получаете сообщение об ошибке сетевой библиотеки DBNETLIB, это означает, что клиентское приложение не смогло установить сетевое соединение с СУБД. Нам нужно выполнить несколько последовательных шагов диагностики.
Проблема именованных экземпляров (Named Instances)
В строке подключения часто указывают имя экземпляра сервера через обратный слэш, например: 192.168.1.128\server. В устаревшем MS SQL Server 2000 именованные экземпляры по умолчанию используют динамические TCP-порты. Для того чтобы клиентская машина поняла, к какому именно порту обращаться, она посылает UDP-запрос на порт 1434 удаленного сервера (служба SQL Server Browser/Resolution Service).
В современных корпоративных сетях этот порт практически всегда заблокирован брандмауэрами операционной системы или сетевыми экранами. Решением будет принудительное назначение фиксированного TCP-порта (обычно это стандартный порт 1433) для нашего экземпляра базы данных в утилите SQL Server Network Utility непосредственно на сервере базы данных.
После назначения статичного порта мы можем прописывать подключение в строке соединения напрямую через запятую:
Data Source=192.168.1.128,1433;
Проверка сетевых протоколов клиента
В операционной системе Windows встроена утилита для принудительного выбора используемых сетевых библиотек — cliconfg.exe. Важно помнить, что на 64-битной версии ОС Windows присутствуют две независимые версии этой утилиты:
C:\Windows\System32\cliconfg.exeC:\Windows\SysWOW64\cliconfg.exeЗапустите требуемую версию утилиты и убедитесь, что протокол TCP/IP включен и находится на первом месте по приоритету по сравнению с протоколом Named Pipes.
Если сервер СУБД настроен корректно, а подключение со стороны современной Windows все равно блокируется без видимых сетевых причин, источником проблемы являются современные политики безопасности Windows.
Поскольку MS SQL Server 2000 является очень старым программным продуктом, он обменивается данными по устаревшим протоколам безопасности TLS 1.0 / TLS 1.1 и использует старые наборы шифров (Cipher Suites), такие как 3DES. В актуальных версиях Windows эти компоненты отключены по умолчанию.
Для восстановления работоспособности обмена нам может потребоваться отредактировать реестр операционной системы на стороне клиента:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client, создайте параметр типа DWORD с именем Enabled и значением 1.Cryptography добавить поддержку шифров класса TLS_RSA_WITH_3DES_EDE_CBC_SHA.Соблюдение всех описанных шагов — от контроля разрядности до настройки политик безопасности и использования нативного OLE DB-провайдера — гарантирует стабильную, быструю и безопасную работу интеграции между вашей базой 1С и историческими базами данных MS SQL Server 2000.