Настройка MSDTS для работы с IBProvider.

Привет.

Сегодня на email поддержки пришло письмо, из которого пришлось прервать противоестественную увлекательную работу с IBProvider-ом из .NET кода. Письмо просило помощи в решении проблем с MSDTS. Суть проблемы, собственно говоря, проста — ничего не работает. Поскольку про это «не работает» уже было давно известно и уже были некоторые соображения по-этому поводу, я решил замучать эту тему «по-взрослому».

Немного по-подробнее о проблеме.
При попытке экспортировать данные из таблицы БД Firebird/Interbase через «Мастер импорта и экспорта SQL Server» свеже-установленного MSSQL 2008, после настройки источника (LCPI.IBProvider.3, разрешаем автоматические транзакции) и приемника (SQL Server Native Client 10.0), получается приблизительно такая картина:


Не распознанный тип колонки.

Здесь «TEST_COLUMNS» — это тестовая таблица, структуру которой можно посмотреть в c:\Program Files (x86)\LCPI_IBProvider\TestCode\ActiveX\IBP\test_database\sql\test_columns.sql. Как видим, в столбце «тип» для «COL_BLOB_TEXT» указан идентификатор 130 (это OLEDB тип DBTYPE_WSTR) вместо имени. В подсказке же говорится, что исходный столбец имеет тип «BLOB SUB_TYPE TEXT».

У MSSQL есть интересный каталог «c:\Program Files\Microsoft SQL Server\100\DTS\MappingFiles», в котором хранятся XML-файлы с правилами преобразования типов между разными источниками.

После ряда экспериментов, с участием Firebird 2.5 и базой данных третьего диалекта, были созданы два файла IBProviderToMSSql10.xml и IBProviderToSSIS10.xml. Копируем эти файлы в «MappingFiles». Перезапускаем визард. Настраиваем источник и приемник. Выбираем «копирование данных из одной или нескольких таблиц или представлений». Выбираем нашу тестовую таблицу «TEST_COLUMNS» и смотрим на сопоставление столбцов (кнопка «изменить» в диалоге выбора таблиц):


Корректно распознанные типы колонок.

Ага, зер гуд. Закрываем это окно и проходим все остальные окна визарда вплоть до запуска.


Последняя страница визарда перед запуском копирования данных.

Нажимаем на кнопку «Готово» и видим:
Ошибка выборки данных из таблицы источника.

Ну, вообщем, тоже известная проблема. MSDTS получает данные через IOpenRowset::OpenRowset и передает туда заковыченное имя таблицы. А провайдер такое не любит. Хотя раньше любил, но эту «функциональность» пришлось зарезать. Но это так, к слову.

Закрываем окно с ошибкой. Отматываем визард назад до выбора способа копирования. Говорим, что будем указывать запрос.

Выбор режима получения данных из источника.

В этом случае MSDTS будет получать данные через команду (ICommand::Execute).

Указываем запрос.

Выбор режима получения данных из источника.

Нажимаем далее. Здесь я отредактировал «пункт назначения» — заменил «[dbo].[Запрос]» на «[dbo].[TEST_COLUMNS]»

Просмотр источника данных и получателя.

Можно нажать на «Изменить», чтобы еще раз посмотреть на сопоставление столбцов.

Так, теперь проматываем визард вперед до упора запуска. Запускаем копирование данных.

Копирование данных таблицы TEST_COLUMNS.

В моей адской таблице нет записей, она предназначена исключительно для тестирования работы с различными практически всеми видами простых колонок (исключая массивы).

Проделывание тех же самых операций для таблицы EMPLOYEE из стандартной базы данных, выдает на финише такую картинку:

Копирование данных таблицы EMPLOYEE.

Предупреждения (по всей видимости) вылазят из-за кодовой страницы NONE, которая используется для текстовых колонок employee.fdb. Такие данные передаются провайдером в виде мультибайтных строк (DBTYPE_STR), для которых подразумевается какая-нибудь кодовая страница. Об этом «копирователь» данных нас и предупреждает.

Отчет копирования таблицы EMPLOYEE.

Теперь можно чем нибудь подключиться к той базе данных MSSQL, куда мы копировали данные, и визуально посмотреть что там и как.

Просмотр скопированных данных EMPLOYEE в базе данных MSSQL.

Я еще до кучи эксперементировал с копированием RDB$PROCEDURES, «dbtype_rules=1″ и включением эмуляции типов. Все работает корректно. То есть правила, описанные в XML-ных файлах, охватывают все возможные типы колонок. Ну, кроме массивов, разумеется.

Обратное копирование из MSSQL в Interbase/Firebird.
Было бы странно (хотя не, не было бы) если бы я не попробовал скопировать данные обратно. Все хорошо, за исключением двух вещей.

1. Firebird не поддерживает BINARY и VARBINARY. Без них как-то проблематично описывать колонки с бинарным данными. В правилах нельзя написать что-то типа «CHAR(%SOURCE_STRING_LENGTH%) CHARACTER SET OCTETS». Потому что — смотри п.2.

2. Тупорылость Ограниченные возможности XML-ных файлов с правилами. Кстати, вот они, эти правила — DataTypeMapping.xsd. Могли бы и побольше возможностей дать. Вплоть до использования нормальных текстовых шаблонов для описания типов.

Так что вот. Что касается провайдера, то я найду время чтобы опционально вернуть зарезанную функциональность с IOpenRowset::OpenRowset. А вот насчет BINARY/VARBINARY — это обращайтесь к машинистам серверо-писателям. Тем более что эти типы вроде как введены в стандарт SQL 2008.

3 комментария

Kovalenko  on Февраль 5th, 2012

Вообщем, «пацан сказал, пацан сделал» 🙂

У меня была мысль создать пошаговую инструкцию в отдельной записи. Но потом решил ограничиться комментарием в к этой. Инструкцию создадим после полного осмысления сделанного 🙂

1. На сайт выложен новый триал (сборка 13110). Скачать и инсталлировать.

2. В каталоге «c:\Program Files (x86)\LCPI_IBProvider\Integrations» находятся файлы с правилами отображения типов (для копирования из Interbase/Firebird в MS SQL 2008): IBProviderToMSSql10.xml, IBProviderToSSIS10.xml. Их нужно скопировать в «{Folder with installation of Microsoft SQL Server 2008}\100\DTS\MappingFiles»

Поддержку для 2005 сервера я решил пока не делать.

Про обратное копирование из MSSQL 2008 я уже писал — там проблемы с описанием правил. Эти же проблемы относятся и к копированию между FB и IB.

3. В провайдер добавлено новое свойство инициализации «open_rowset__sql«. При работе с MS DTS (или SSIS) это свойство нужно выставить в true. Для того чтобы не копаться в километровом списке свойств (на странице «Все»), на дополнительную вкладку добавлен checkbox «SQL через OpenRowset». Ставим галочку и обретаем счастье.

Включаем расширенный функционал IOpenRowset::OpenRowset.

4. Общие сведения по поводу перекачки данных
— Не забываем разрешать «автоматические транзакции». Включается на первой вкладке настроек.

— Про «open_rowset__sql=true» я уже сказал выше.

— Если текстовые данные хранятся в колонках с кодовой страницей NONE, то надо указать «ctype_none=< имя кодовой страницы данных>«. В противном случае могут быть всякие проблемы.

— По умолчанию, провайдер работает в UNICODE режиме — не надо его отключать.

— Если вы выгружаете данные из FB ниже v2.5 или из Interbase — укажите кодовую страницу подключения.

— Можно еще указать «dbtime_rules=1″, чтобы перенести данные TIME без потери микросекунд.


На этом, пожалуй, пока можно и остановиться.

Kovalenko  on Февраль 15th, 2012

На сайт выложен дистрибутив с новым триалом (сборка 13122) и новыми правилами для переноса данных из Interbase/Firebird в базы данных MSSQL 2005 (IBProviderToMSSql9.xml, IBProviderToSSIS9.xml). Там почти все тоже самое что и для MSSQL 2008, только другие правила для типов TIME/DATE/TIMESTAMP.

В процессе тестирования наступил на древние грабли Firebird’а. Четвертый год уже висит бага и портит карму.

Dmitry Kovalenko  on Апрель 25th, 2015

Да, кстати — текущие MSI-установщики IBProvider-a могут (и делают это по умолчанию) копировать файлы с правилами в каталоги MappingFiles.

Оставить комментарий