Как подключиться к другой базе 1С 7.7 на SQL Server 2012 с помощью внешней компоненты 1С++

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке и администрировании систем на платформе 1С:Предприятие 7.7 часто возникает необходимость интеграции нескольких баз данных или прямого обращения к таблицам СУБД. В качестве основного инструмента для решения таких задач используется внешняя компонента 1С++, которая предоставляет мощные возможности работы с базами данных через интерфейс ODBC.

Однако при попытке настроить подключение к другой базе данных, особенно расположенной на современной СУБД, такой как MS SQL Server 2012, разработчики регулярно сталкиваются с неочевидными ошибками. Типичный пример — сообщение об ошибке Введенный пароль неверен при вызове метода ПрисоединитьИБ. В этой статье мы подробно разберем, почему возникает эта ошибка, как устроена авторизация в системе 1С 7.7 и как правильно настроить стабильное соединение.

Выясняем причину: два уровня авторизации

Проанализируем ситуацию, описанную в теме. Разработчик успешно настроил системный DSN, проверил соединение с SQL-сервером через утилиты администрирования, создал объект ODBCDatabase и успешно установил низкоуровневое соединение. Однако при попытке инициализировать метаданные другой базы данных с помощью конструкции БазаПодкл.ПрисоединитьИБ(Каталог1С) платформа выдает ошибку неверного пароля.

Главная причина этой проблемы кроется в непонимании архитектуры безопасности платформы 1С 7.7. Важно четко разделять два совершенно разных уровня авторизации:

  1. Авторизация на уровне СУБД (SQL Server) — используется для доступа к таблицам базы данных. Здесь применяется учетная запись SQL (например, стандартный системный администратор СУБД sa или выделенный пользователь с правами владельца базы данных db_owner). Параметры этого подключения хранятся в зашифрованном файле 1cv7.dba в каталоге базы данных.
  2. Авторизация на уровне платформы 1С:Предприятие 7.7 — используется для проверки прав конкретного пользователя внутри самой бизнес-логики программы. Список пользователей и их пароли хранятся в каталоге базы данных в папке usrdef (файл users.usr). На уровне SQL-сервера эти пароли никак не дублируются и не проверяются СУБД.

Когда мы вызываем метод ПрисоединитьИБ без указания дополнительных параметров, компонента 1С++ пытается выполнить авторизацию в целевой базе данных под именем и паролем текущего активного пользователя текущей сессии 1С. Если в целевой базе список пользователей отличается, или у данного пользователя установлен другой пароль, то платформа закономерно возвращает системную ошибку: Введенный пароль неверен.

Разбираем синтаксис метода ПрисоединитьИБ()

Чтобы решить проблему с авторизацией, нам необходимо явно передать учетные данные пользователя целевой базы 1С. Рассмотрим подробнее синтаксис метода ПрисоединитьИБ класса ODBCDatabase:

ПрисоединитьИБ(КаталогИБ, [ИмяПользователя], [Пароль], [СтрокаСоединения])

Разберем назначение каждого параметра:

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


КаталогЦелевойБазы = "D:\Bases1C\TradeBase\";
ИмяПользователя1С = "ИнтеграцияODBC";
ПарольПользователя1С = "P@ssw0rd1C";

БазаПодкл = СоздатьОбъект("ODBCDatabase");
Если БазаПодкл.ПрисоединитьИБ(КаталогЦелевойБазы, ИмяПользователя1С, ПарольПользователя1С) = 0 Тогда
    Предупреждение("Не удалось подключиться к базе данных!");
    Сообщить("Описание ошибки: " + БазаПодкл.ПолучитьОписаниеОшибки());
Иначе
    Сообщить("Успешное подключение к метаданным смежной информационной базы!");
КонецЕсли;

Особенности работы с MS SQL Server 2012

Платформа 1С 7.7 разрабатывалась задолго до выхода современных версий СУБД, и штатно поддерживает работу только с MS SQL Server 2000. При работе со SQL Server 2012 стандартные механизмы могут давать сбои. Чтобы обеспечить стабильное функционирование, необходимо учитывать три важных аспекта:

  1. Модификация BkEnd.dll. Оригинальная библиотека платформы выдаст ошибку при попытке работы с СУБД версии выше 2000. Для обхода этого ограничения разработчики используют пропатченные версии библиотек (так называемый "секретный релиз" или библиотеки-прокси BkEnd.dll и BkEndUtls.dll из проекта Solution7).
  2. Режим совместимости баз данных. На самом SQL-сервере для подключаемой базы рекомендуется выставить уровень совместимости (Compatibility Level) в значение SQL Server 2000 (80) или SQL Server 2005 (90). Это минимизирует вероятность ошибок при выполнении платформенных запросов.
  3. Права пользователя SQL. Учетная запись SQL, под которой выполняется подключение к СУБД, должна обладать ролью владельца базы данных (db_owner), а также системными правами VIEW SERVER STATE для корректного мониторинга транзакций.

Обход проблем с устаревшим ODBC-драйвером

По умолчанию 1С:Предприятие 7.7 и компонента 1С++ при подключении к SQL-базе генерируют строку соединения со стандартным системным драйвером {SQL Server} (библиотека sqlsrv32.dll). В современных операционных системах этот устаревший драйвер работает некорректно со SQL Server 2012 и выше, что может приводить к аварийному завершению работы программы или ошибкам транзакций.

Решением является принудительное переопределение драйвера на более современный, например SQL Server Native Client 11.0 (SQLNCLI11). Для этого мы должны передать сформированную вручную строку подключения в четвертый параметр метода ПрисоединитьИБ. Это также избавит компоненту от необходимости считывать зашифрованный файл 1cv7.dba, доступ к которому может блокироваться операционной системой из-за настроек прав или UAC.

Рассмотрим пример подключения с явным указанием современного драйвера Native Client:


КаталогЦелевойБазы = "D:\Bases1C\TradeBase\";
ИмяПользователя1С = "Администратор";
ПарольПользователя1С = "SuperPassword";

// Формируем надежную строку подключения в обход настроек файла 1cv7.dba
СерверSQL = "SQL-SERVER-2012\MAIN";
ИмяБазыSQL = "trade_prod";
ПользовательSQL = "sa";
ПарольSQL = "StrongSQLPass123";

СтрокаПодключения = "Driver={SQL Server Native Client 11.0};Server=" + СерверSQL + 
                    ";Database=" + ИмяБазыSQL + 
                    ";Uid=" + ПользовательSQL + 
                    ";Pwd=" + ПарольSQL + ";";

БазаПодкл = СоздатьОбъект("ODBCDatabase");
ФлПодключения = БазаПодкл.ПрисоединитьИБ(КаталогЦелевойБазы, ИмяПользователя1С, ПарольПользователя1С, СтрокаПодключения);

Если ФлПодключения = 0 Тогда
    Сообщить("Ошибка подключения: " + БазаПодкл.ПолучитьОписаниеОшибки(), "!");
Иначе
    Сообщить("Успешно подключились через SQL Server Native Client 11.0!");
КонецЕсли;

Альтернативный вариант: прямое подключение без метаданных 1С

Иногда перед разработчиком стоит задача не полной интеграции с другой базой 1С (с получением типизированных объектов, справочников и документов), а просто быстрого чтения или записи данных в таблицы SQL-сервера. Если нам не требуется разыменовывать внутренние идентификаторы 1С через типизацию метаданных (например, использовать конструкции вида $Справочник.Номенклатура), мы можем полностью отказаться от метода ПрисоединитьИБ.

В этом случае мы можем использовать прямое бесшаблонное (DSN-less) подключение через объект ODBCDatabase. Этот метод работает быстрее, стабильнее и не требует наличия заведенных пользователей 1С во второй базе данных.

Разберем, как реализовать прямое подключение и выполнить SQL-запрос к таблице справочника напрямую:


// Создаем объект базы данных
БД = СоздатьОбъект("ODBCDatabase");

// Формируем строку подключения напрямую к SQL Server 2012
СтрокаПодключения = "Driver={SQL Server Native Client 11.0};Server=SQLSRV-NODE1;Database=accounting_db;Uid=sa;Pwd=MyS3cretPa$$;";

Если БД.Соединение(СтрокаПодключения) = 0 Тогда
    Сообщить("Не удалось установить соединение с SQL-сервером!", "!");
    Сообщить(БД.ПолучитьОписаниеОшибки());
    Возврат;
КонецЕсли;

// Создаем объект для выполнения запросов
Запрос = СоздатьОбъект("ODBCRecordSet");
Запрос.УстБД(БД);

// Пишем прямой SQL-запрос. 
// Имена таблиц (например, SC145 для справочника) смотрим в файле 1cv7.dd
ТекстЗапроса = "
|SELECT TOP 100
|    ID as [КодЭлемента],
|    DESCR as [Наименование],
|    CODE as [Код1С]
|FROM
|    SC145 (NOLOCK)
|WHERE
|    ISFOLDER = 2 -- выбираем только элементы, не группы
|";

ТЗ_Результат = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);

Если ПустоеЗначение(ТЗ_Результат) = 0 Тогда
    // Выведем результат в окно выбора для визуального анализа
    ТЗ_Результат.ВыбратьСтроку();
КонецЕсли;

Использование прямого подключения гарантирует, что никакие проблемы совместимости платформы 1С 7.7 со SQL Server 2012 не помешают вашей работе, поскольку взаимодействие происходит на чистом уровне драйвера ODBC и СУБД.

← На главную