При разработке и администрировании систем на платформе 1С:Предприятие 7.7 часто возникает необходимость интеграции нескольких баз данных или прямого обращения к таблицам СУБД. В качестве основного инструмента для решения таких задач используется внешняя компонента 1С++, которая предоставляет мощные возможности работы с базами данных через интерфейс ODBC.
Однако при попытке настроить подключение к другой базе данных, особенно расположенной на современной СУБД, такой как MS SQL Server 2012, разработчики регулярно сталкиваются с неочевидными ошибками. Типичный пример — сообщение об ошибке Введенный пароль неверен при вызове метода ПрисоединитьИБ. В этой статье мы подробно разберем, почему возникает эта ошибка, как устроена авторизация в системе 1С 7.7 и как правильно настроить стабильное соединение.
Проанализируем ситуацию, описанную в теме. Разработчик успешно настроил системный DSN, проверил соединение с SQL-сервером через утилиты администрирования, создал объект ODBCDatabase и успешно установил низкоуровневое соединение. Однако при попытке инициализировать метаданные другой базы данных с помощью конструкции БазаПодкл.ПрисоединитьИБ(Каталог1С) платформа выдает ошибку неверного пароля.
Главная причина этой проблемы кроется в непонимании архитектуры безопасности платформы 1С 7.7. Важно четко разделять два совершенно разных уровня авторизации:
sa или выделенный пользователь с правами владельца базы данных db_owner). Параметры этого подключения хранятся в зашифрованном файле 1cv7.dba в каталоге базы данных.usrdef (файл users.usr). На уровне SQL-сервера эти пароли никак не дублируются и не проверяются СУБД.Когда мы вызываем метод ПрисоединитьИБ без указания дополнительных параметров, компонента 1С++ пытается выполнить авторизацию в целевой базе данных под именем и паролем текущего активного пользователя текущей сессии 1С. Если в целевой базе список пользователей отличается, или у данного пользователя установлен другой пароль, то платформа закономерно возвращает системную ошибку: Введенный пароль неверен.
Чтобы решить проблему с авторизацией, нам необходимо явно передать учетные данные пользователя целевой базы 1С. Рассмотрим подробнее синтаксис метода ПрисоединитьИБ класса ODBCDatabase:
ПрисоединитьИБ(КаталогИБ, [ИмяПользователя], [Пароль], [СтрокаСоединения])
Разберем назначение каждого параметра:
1cv7.dba целевой базы.Посмотрим на пример правильного вызова метода для инициализации подключения к другой базе:
КаталогЦелевойБазы = "D:\Bases1C\TradeBase\";
ИмяПользователя1С = "ИнтеграцияODBC";
ПарольПользователя1С = "P@ssw0rd1C";
БазаПодкл = СоздатьОбъект("ODBCDatabase");
Если БазаПодкл.ПрисоединитьИБ(КаталогЦелевойБазы, ИмяПользователя1С, ПарольПользователя1С) = 0 Тогда
Предупреждение("Не удалось подключиться к базе данных!");
Сообщить("Описание ошибки: " + БазаПодкл.ПолучитьОписаниеОшибки());
Иначе
Сообщить("Успешное подключение к метаданным смежной информационной базы!");
КонецЕсли;
Платформа 1С 7.7 разрабатывалась задолго до выхода современных версий СУБД, и штатно поддерживает работу только с MS SQL Server 2000. При работе со SQL Server 2012 стандартные механизмы могут давать сбои. Чтобы обеспечить стабильное функционирование, необходимо учитывать три важных аспекта:
BkEnd.dll и BkEndUtls.dll из проекта Solution7).SQL Server 2000 (80) или SQL Server 2005 (90). Это минимизирует вероятность ошибок при выполнении платформенных запросов.db_owner), а также системными правами VIEW SERVER STATE для корректного мониторинга транзакций.По умолчанию 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С (с получением типизированных объектов, справочников и документов), а просто быстрого чтения или записи данных в таблицы 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 и СУБД.