Подключение к внешним источникам данных из 1С (ODBC)

 
ВИД (внешние источники данных) в 1С – это объекты конфигурации, позволяющие использовать информацию из внешних ODBC-источников (баз данных), не основанных на 1С:Предприятии, внутри прикладного решения так же, как будто бы она хранится в самой информационной базе.

В качестве ODBC-драйвера был выбран пакет FreeODBC, т.к. он бесплатный и его везде используют.

В процессе гугления использовались источники:

Внешние источники данных на Linux-серверах 1С

Настройка доступа к базе 1С на MSSQL из под Linux

Настройка доступа к Microsoft SQL Server через ODBC. Ubuntu 12.04

Пример интеграции базы 1С и внешней СУБД (хорошая статья)

Подробное описание работы с ВИД (да и вообще хороший блог о работе с 1С)

Программное добавление, изменение, удаление (примеры)

Запись во внешний источник данных из 1С 8.3 (используя хранимые процедуры MS SQL Server)

Запись во внешние источники данных в «1С:Предприятие 8» (используя хранимые процедуры MS SQL Server)


Установка

Достаточно установить пакет tdsodbc (разрядность должна совпадать с сервером 1С!):
# apt install tdsodbc:i386 (дополнительно установятся: libodbc1 odbcinst odbcinst1debian2)

В файл odbcinst.ini добавить (если не добавилось автоматически) секцию для FreeTDS:

# nano /etc/odbcinst.ini
[FreeTDS]
Description = FreeTDS
Driver = <путь_к_либам>/libtdsodbc.so
Setup = <путь_к_либам>/libtdsS.so
FileUsage = 1
UsageCount = 1

, где <путь_к_либам_tdsodbc>:

  • Для 32-битного пакета: /usr/lib/i386-linux-gnu/odbc
  • Для 64-битного пакета: /usr/lib/x86_64-linux-gnu/odbc

Если этого не сделать, или поставить пакет не той же разрядности, что сервер 1С, то будет ошибка:
[unixODBC][Driver Manager]Can't open lib 'FreeTDS' : file not found

А вот такая ошибка будет, если неверно указали путь к либам:
/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so file not found

При нажатии на кнопку “…” конфигурация выдаст последний вскрик в виде окошка с ошибкой и благополучно покрашится. Что это за НЛО непонятно, но на нашем серваке оно поселилось, видать, надолго:

"Ошибка аутентификации клиента 1cv8 средствми операционной системы: Аутентификационный контекст клиента отсутствует в рабочем процессе"

 

Как я понял, поключаться и работать с ВИД можно двумя способами:
1) Подключаться программно.
Пример:
(Спасибо caponid за инфу о поле СУБД):
Соед = Новый ПараметрыСоединенияВнешнегоИсточникаДанных;
Соед.СтрокаСоединения = "Строка_соединения";
Соед.АутентификацияОС = Ложь;
Соед.ИмяПользователя = Пользователь;
Соед.Пароль = Пароль;
Соед.СУБД = "MSSQLServer"; //Явно указываем, потому что тот тип, что указали в строке соединения, игнорируется;
Источник = ВнешниеИсточникиДанных["НазваниеИсточника"];
Источник.УстановитьПараметрыСоединенияСеанса(Соед);
Источник.УстановитьСоединение();

Но тут у меня не получилось запихнуть проинициализированный объект ВИД в запрос:
Запрос.Текст =
"ВЫБРАТЬ
| Источник.Поле
|ИЗ
| &ВИД КАК Источник
|";
Запрос.Параметры.Вставить("ВИД", ВИД);

2) Использовать механизм подключения в режиме Предприятия. Параметры подключения хранятся тут:
РегистрСведений.НастройкиПодключенияКВнешнемуИсточникуДанных
или
Все функции -> Стандартные -> Управление внешними источниками данных

Строка подключения выглядит так:
"Driver={FreeTDS}; Server=SERVER,1433; Database=BASE; User Id=USER; Password=PASS;"
Пользователя и пароль я запихивал в отдельные поля.

Если в режиме предприятия будут отсутствовать параметры подключения к внешнему источнику данных, то будет ошибка:
"[unixODBC][Driver Manager]Data source name not found, and no default driver specified"

Названия Таблиц и полей в конфигураторе могут быть какими угодно, а вот к полям “Имя в источнике данных” нужно присмотреться внимательнее. Если в именах полей БД MS SQL есть, к примеру, символ “_”, то будет вот такая ошибочка:
"[FreeTDS][SQL Server]Incorrect syntax near 't_ticket_id'"

Спасибо master1c8.ru, выручил!

“Если значение, находящееся в свойстве Имя в источнике данных заключено в одинарные кавычки, то в SQL-запрос к базе данных это значение попадает без преобразований, вне зависимости от состава символов.”

Т.е. названия таблиц и полей MS SQL в поле “Имя в источнике данных” нужно указать в одинарных кавычках.

 

 

 

 

Дату нужно форматировать перед добавлением, например, так:

Формат(ТекущаяДата(), "ДФ='yyyy-MM-dd HH:mm:ss'")

Иначе будет:

"[FreeTDS][SQL Server]Conversion failed when converting date and/or time from character string."

Для добавления новых записей поле идентификатора с автоинкременом нужно установить в “Только чтение”, иначе будет:

"[FreeTDS][SQL Server]Cannot insert explicit value for identity column in table 't_logs' when IDENTITY_INSERT is set to OFF."

При добавлении таблицы с помощью помощника, поля с внешними ключами (foreign_key) будут по-умолчанию устанавливаться в тип объекта, а не Число. Мне это небыло нужно, поэтому вручную менял тип.

Нужно быть внимательным с поиском записи с помощью функции НайтиПоПолю(). Значение должно совпадать с типом поля в таблице. Например, строку перегонять в число:

НайтиПоПолю("поле", Число(ЗначениеДляПоискаСтрока));

По поводу поиска вхождений записей в список значений в запросе:
table.id В(&СписокЗаявки) – не прокатит (СписокЗаявки – это СписокЗначений со значениями – строками, а id – число)
table.id В("+СтрокаЗаявки+") – прокатит (СтрокаЗаявки – строка со значениями через запятую)
Сейчас пишу и не понимаю почему не попробовал значения списка СписокЗаявки привести к численному типу, но проверять уже лень.

Чтобы не выводить таблицы в командный интерфейс раздела (подсистемы) в свойствах таблицы нужно убрать галку “Использовать стандартные команды“.


Что не получилось

Не получилось сделать поля выбора (а-ля combobox) с выпадающим списком значений из ВИД. Ставишь реквизиту формы тип таблицы ВИД, переносишь его на форму. Все ок, элемент (контрол) создается, но не отображается. Заморачиваться не стал, вводил вручную id-шники записи, этого было достаточно.

Выполнить хранимую процедуру. До этого хранимыми процедурами в БД не пользовался, хотя хорошая вещь.
Но как ни крутил я этот функционал в конфигураторе, ничего не вышло (а тут и тут работало).
Какие были ошибки…:
1) <Выражение в источнике данных>
2) <Ошибка>

1) FuncName
2) [FreeTDS][SQL Server]Invalid column name 'FuncName'.

1) dbo.FuncName
2) [FreeTDS][SQL Server]Cannot find either column "dbo" or the user-defined function or aggregate "dbo.FuncName", or the name is ambiguous.

1) SELECT <FuncName>
2) [FreeTDS][SQL Server]Incorrect syntax near the keyword 'SELECT'.

1) EXECUTE <FuncName>
2) [FreeTDS][SQL Server]Incorrect syntax near the keyword 'EXECUTE'.

1) * from dbo.FuncName()
2) Обращение к процедуре объекта как к функции (FuncName)

Так же не решился вопрос с кириллицей. А точнее, при создании записей из 1С в MS SQL текст на русском языке превращался в кракозябры, например:

" 0:@KB85 70O2:8 87 1!, ID=[3037]"

Параметры сортировки базы: Cyrillic_General_CI_AS.
Что пытался сделать:
1) настроить FreeTDS, всунув в его конфиг параметр charset в секцию [global]:
# nano /etc/freetds/freetds.conf
client charset = UTF8
2) добавить параметр charset в строку подключения:
"Driver={FreeTDS}; Server=SERVER,1433; Database=BASE; charset=UTF8;"

Не получилось. Еще есть вариант 3:
3) сменить API ODBC
Но придется делать все заново. Поэтому, ограничился записью текста на инглише.


Нужно больше прав!!!

При нехватке прав при выполнении запроса к таблицам ВИД будет ошибка:
Ошибка при вызове метода контекста (Выполнить): Недостаточно прав для работы с таблицей "ВнешнийИсточникДанных.БДTickets.Таблица.<TableName>"
Нужно добавить права:
На ВИД: Использование
На таблицы в запросе: Чтение

 

Для выполнения функции <ТаблицаВИД>.НайтиПоПолю() нужно добавить права (иначе “Нарушение прав доступа!”):

На ВИД: Использование
На таблицы в запросе: Чтение, Изменение

Для функции <ТаблицаВИД>.СоздатьОбъект() соответсвенно: Использование, Чтение и Добавление.

Кстати, стандартная роль “Запуск внешнего соединения” не понадобилась, для меня осталось загадкой ее назначение (разобраться не пытался).

0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *