0
Голосовать

Подключение к другой БД

Создано:

Подскажите, что я делаю не так?

В Террасофт стоит MS SQL. стоит задача взять определенные данные с БД Firebird на другом сервере.

Пытаюсь реализовать это с помощью ADO. Создала ADOConnection co строкой подключения :

Provider=MSDASQL.1;Password=masterkey;Persist Security Info=True;User ID=SYSDBA;Extended Properties="Driver=Firebird/InterBase(r) driver; Uid=SYSDBA;Pwd=masterkey; DbName=..."

Проверка подключения производится норм.

Затем создаю ADODataset. Создаю поле P_NAME. Как строку подключения выбираю ADOConnection. Текст SQL- запроса:

SELECT P_NAME FROM PEOPLE

Создаю Окно редактирования. В невизуальных компонентах выбираю источником ADODataset. Визуальных создаю поле TextDataControl и настраиваю его на поле P_NAME.
Так же в окне раздела создаю новый DataGrid. Настраиваю его на ADODataset.

Зайдя под клиентом в гриде не отображается ничего ,а при входе в окно редактирования возникает такая вот ошибка

Ошибка выполнения метода 'wnd_BaseDBEditOnPrepare'. Object 'DataField ID' is not assigned

Комментарии

Яворский Алексей

Здравствуйте Елена,
К примеру, хоти получить колонку Name с таблицы tbl_Account (БД Firebird). При этом сама конфигурация Terrasoft на MS SQL Server 2008

Шаг 1
Создаем ADOConnection в строку соединения пишем (т.е лупу мы не нажимаем)

Driver=Firebird/InterBase(r) driver;Uid=SYSDBA;Pwd=masterkey; DbName=E:\ClientsDB\firebird\Anastasiya\TS.FDB

DbName - путь к БД
В данном случае
E:\ClientsDB\firebird\Anastasiya\TS.FDB
Uid - логин
Pwd - пароль

Шаг 2.
Далее создаю ADO Dataset
В поле соединения, устанавливаю название сервиса подключения с Шага 1
В поле текст SQL пишу:

SELECT "Name" FROM "tbl_Account"

Кавычки принципиальны.

Далее я создаем в Data Fields строковое поле Name при этом название и заголовок прописываем руками (оно не подхватывается как в случае работы с обычным DataSet)

Шаг 3. Проверяем результаты
Создем сервис Window унаследываемего от wnd_BaseGridArea. Переоткрываем сервис окна
В невизуальных dlData выбираем созданный на шаге 2 датасет
в grdData создаем DataGridView в нем определяем колонки, ставим их видимыми.

В grdData свойство ActiveView выставляем в DataGridView, получим такой вид сервиса

На OnPrepare окна открывем датасет

function wnd_BaseGridAreaOnPrepare(Window) {
        dlData.Dataset.Open();
}

запустить тестовый сервис можно по нажатию F9

XML тесовых сервисов прикрепил.

Прикрепленный файлРазмер
16-08-2011_15-53-13.jpg 6.83 кб
16-08-2011_15-57-20.jpg 26.51 кб
16-08-2011_15-59-31.jpg 10 кб
16-08-2011_16-02-27.jpg 18.53 кб
16-08-2011_16-06-40.jpg 15.91 кб
fb.rar 2.92 кб

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Большое спасибо! Все заработало!
Только строку подключения в ADOConnection немного поменяла (иначе система не находила базу):

Provider=MSDASQL.1;Password=masterkey;Persist Security Info=True;User ID=SYSDBA;Extended Properties="Driver=Firebird/InterBase(r) driver;Uid=SYSDBA;Pwd=masterkey; DbName=адрес"

Яворский Алексей

Если у Вас возникнут вопросы, обращайтесь.

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Столкнулась с такой проблемой.
Данные выводятся, но не все, т.е., если в колонке 100 записей, выводит только половину.
2 колонки из таблицы, которые связаны с другими таблицами этой же базы, выводит не как значения, а как -1 (значения в колонках точно есть)

При открытии грида с этими данными выходит в лог ошибку:

Ошибка выполнения метода 'dlAttendanceOnDatasetAfterPositionChange'. Объект TSObjectLibrary.ADODataset ({5119679C-DF62-4F33-ABD8-CD2BA96A64EA}) не поддерживает интерфейс IDBDataset ({B77D78C1-40FD-4A5A-9592-DC0A6072AA3B})

Яворский Алексей
Перепечай Елена пишет:
Данные выводятся, но не все, т.е., если в колонке 100 записей, выводит только половину.

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

По поводу второго вопроса, буду пробывать воспроизвести

Прикрепленный файлРазмер
19-08-2011_13-17-42.jpg 28.09 кб
19-08-2011_13-17-52.jpg 63.83 кб
19-08-2011_13-17-57.jpg 43.95 кб
19-08-2011_13-17-28.jpg 59.3 кб

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Увеличила количество записей в конфигурации, все заработало, спасибо!

Перепечай Елена

Возникла неожиданная, для меня, проблема. После переустановке windows пропало соединение с БД. Строка подключения осталась таже, ничего не менялось, но при попытки присоединения к Firebird выдает ошибку:

"Не выполнена проверка соединения из-за ошибки при инициализации поставщика. Неопознанная ошибка"

Яворский Алексей

В теме http://www.community.terrasoft.ru/forum/topic/6760#comment-28808 обсуждалось, что необходимо установить Firebird ODBC Driver (http://www.firebirdsql.org/en/odbc-driver/) , при переустановке ОС он удалился.

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Поставила Firebird_ODBC_2.0.0.151_Win32.exe, ошибка осталась

Яворский Алексей

На сколько я понимаю путь

Перепечай Елена пишет:
Provider=MSDASQL.1;Password=masterkey;Persist Security Info=True;User ID=SYSDBA;Extended Properties="Driver=Firebird/InterBase(r) driver;Uid=SYSDBA;Pwd=masterkey; DbName=адрес"

содержит алиас "адрес" в котором хранится путь к вашей БД firebird, проверьте, пожалуйста, прописан ли он.

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

да, конечно, путь прописан в строке подключения

Яворский Алексей

Под переустановкой ОС вы имеете в виду что, вы поставили ту же операционную систему, или установили, что то более новое? К примеру с Windows XP перешли на Windows 7, версию работы с памятью (x32, x64) системы не меняли (имеется в виду редакция ОС для работы с памятью) ?

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

перешла с ХР на 7-ку. х32 как было так и осталось.

Яворский Алексей

Елена, мое предположение что Windows 7 использует более новые методы доступа, следовательно возможно строка подключения должна выглядеть немного иначе
1.Попробуйте перегенирировать строку подключения.
2.Попробуйте пройти по ссылке http://msdn.microsoft.com/en-us/data/aa937729.aspx , и скачать более полные пакеты для полючения к бд ( http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=21995 )

И кстати, вы проверяли подключение к БД Firebird ?

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Удалось добиться успешной проверки соединения, выбрав поставщиком OLE DB Provider for Microsoft Directory Services.

Строка соединения сформировалась таким образом:

Provider=ADsDSOObject;User ID=SYSDBA;Encrypt Password=False;Data Source=firebird.fdb;Location=адрес;Mode=ReadWrite;Bind Flags=0;ADSI Flag=-2147483648;

В ADODataBase написала текст запроса:

SELECT "P_FAM" FROM "PEOPLE"

Создаю строковое поле, подключаю все это к гриду.
При запуске клиента выдает ошибку

"Ошибка открытия источника данных "db_ADOFirebird". Оригинальное сообщение об ошибке: Произошла одна или несколько ошибок во время обработки команды"

Яворский Алексей

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

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Яворский Алексей

В Windows 7 соединение можно получить следующим образом:
Среда:
Установлен Firebird-2.0.3.12981-1-Win32
Установлен Firebird_ODBC_2.0.0.151_Win32.exe

Запускаем
Для x32 %windir%\system32\odbcad32.exe
( Панель управления\Все элементы панели управления\Администрирование\Источники данных (ODBC) )

Для x64 %windir%\SysWOW64\odbcad32.exe
Замечание для Windows 7 x64 принципиально запускать именно 32х битную версию утилиты работы с ODBC

Во вкладке User DSN добавляем Data Source

Выбираем источник Firebird/InterBase(r) driver

Выбираем базу, выбираем клиент Firebird, расставляем галочки, проверяем соединение.

Получили соединение

Теперь в Terrasoft Администраторе переходим в сервис ADO подключения, в моем примере это adocon_fb
В строке соединения, нажимаем лупуи выбираем Provider

Во вкладке Connection, выбираем DSN, логин/пароль НЕ заполняем

Проверяем соединение.

Строка соединения будет выглядеть примерно так:

Provider=MSDASQL.1;Persist Security Info=False;Data Source=fbConnection

Проверяем получение данных

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Спасибо, Алексей, соединение установилось, в этом проблем нет.
Но все равно осталась предыдущая ошибка
"Произошла одна или несколько ошибок во время обработки команды"

Команда которую я прописала:

SELECT "P_FAM" FROM "PEOPLE"

До перестановки эта и другие более сложные запросы работали отлично. Никак не могу понять в чем дело

Прикрепленный файлРазмер
adodateset.jpg 29.29 кб
error.jpg 7.5 кб
Перепечай Елена

хм... перезагрузка компьютера помогла, ошибка пропала!
Большое спасибо за помощь, Алексей!

Есть еще такой вопрос. Подобные настройки соединения с БД надо провести у все пользователей, кому понадобится доступ к данным из этой базы?

Яворский Алексей

Елена, провести настройку подключение придется на всех компьютерах, но задачу можно упростить, к примеру, база данных firebird лежит на сервере, к которому есть доступ на всех пользовательских компьютерах, сами настройки ODBC хранятся в реестре HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI
т.е задача сводится к тому что бы экспортировать настройки, и запускать reg файлы на пользовательских компьютерах, перед этим разместив файлы БД firebird на доступном для всех ресурсе

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Скажите, а есть ли варианты без дополнительных настроек у пользователей? Например, использование Linked Server? Или все равно надо будет доп настройки делать?

Яворский Алексей

Елена, возможно вас устроит вариант выполнения ежедневного запроса данных с Firebird на уровне БД по средствам job в табличку SQL Server ?

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

можете описать этот вариант подробнее?

Яворский Алексей

Елена, сложность в обоих вариантах состоит в том что бы написать запрос в SQL Server который бы получал данные с Firebird. В случае с Job в SQL Server нам надо писать insert или в случае ADO Dataset мы можем подключится к существующей конфигурации SQL Server и на ней же выполнить селект который полит данные с Firebird, остановлюсь на реализации первого варианта.

Предполагается что у нас уже есть System DSN


Создаем Linked Server

Создался Linked Server, проверяем подключение

Далее, получить данные с сервера Firebird можем следующим запросом

SELECT Name FROM OPENQUERY([FBDB], 'SELECT * FROM "tbl_Account"')

Запрос которым мы создадим таблицу и запишем в нее данные с firebird

SELECT Name INTO tbl_accountfb FROM OPENQUERY([FBDB], 'SELECT * FROM "tbl_Account"')

Далее создаем job

Указываем название job и владельца

Далее создаем шаг job

Скрипт для job

begin
DELETE tbl_accountfb;
INSERT INTO tbl_accountfb
SELECT Name FROM OPENQUERY([FBDB], 'SELECT * FROM "tbl_Account"');
end

Указываем, что мы делаем при успешном и неудачном завершении шага

Далее нам следует указать, чтобы SQL Agent запускал данный job по указанным дням в условленное время

Далее Вы можете создать в конфигурации таблицу, с колонками как в tbl_accountfb, при сохранении сервиса таблицы, отказаться от сохранения ее в БД, тем самым данный сервис будет ссылкой на таблицу, которая будет обновляется через job в дни указанные по расписанию.
Работать с таблицей можно будет, как с обычным сервисом Terrasoft

Прикрепленный файлРазмер
30-08-2011_0-37-06.jpg 42.17 кб
30-08-2011_0-38-46.jpg 60.43 кб
30-08-2011_0-40-06.jpg 35.99 кб
30-08-2011_0-41-57.jpg 36.14 кб
30-08-2011_0-44-01.jpg 8.54 кб
30-08-2011_0-53-44.jpg 29.42 кб
30-08-2011_0-54-09.jpg 26.01 кб
30-08-2011_1-03-22.jpg 40.72 кб
30-08-2011_1-03-40.jpg 39.41 кб
30-08-2011_1-05-05.jpg 28 кб
30-08-2011_1-05-17.jpg 28.41 кб
30-08-2011_1-06-08.jpg 42.44 кб

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Такой вопрос. В БД Firebird в день добавляется в среднем около 100 нужных мне записей. Со временем, постоянная перекачка данных не будет ли подтормаживать сеть?

Яворский Алексей

Елена, данный job запускается в определенное время в определенные дни один раз, т.е он не работает как процесс который постоянно записывает данные в таблицу, следовательно логично запускать его скажем ночью в определенные дни, когда никто не работает с системой. В скрипте, который запускается, удаляются все записи с таблицы tbl_accountfb, а потом добавляются по новому с Firebird, если вы не импортируете миллионы записей, то процесс совершенно не критичен и будет проходить за секунды.

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

А если данные должны обновляться каждый день днем, в рабочее время, не вызовет ли это каких либо сбоев?

Яворский Алексей

Предлагаю вам установить на таблицу, в которую вы будете импортировать данные с Firebird доступ только на чтение, что бы на уровне БД никто с пользователей не держал таблицу на запись в SQL Server, во время работы job.

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Скажите, можно ли изменить job таким образом, чтобы таблица не удалялась полностью и потом перезаписывалась, а данные просто добавлялись в нее ( таблица обновлялась)?

Яворский Алексей

Елена попробуйте дописать логику скрипта который отрабатывает во время шага job, доработка будет состоять в добавлении проверки на существующие записи

Пример :

INSERT INTO tbl_to
SELECT * FROM tbl_from
WHERE NOT EXISTS
(SELECT * FROM tbl_to WHERE tbl_to.name = tbl_from.name)

При этом происходит только добавление записей, существующие записи не обновляются

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

INSERT INTO tbl_to
SELECT * FROM OPENQUERY ([FBDB],'SELECT * FROM tbl_from')
WHERE NOT EXISTS
(SELECT * FROM tbl_to WHERE tbl_to.name = ???)

Как обратиться к таблице из которой берем инфу если она в linked server? снова писать OPENQUERY?

Яворский Алексей

Попробуйте поставить алиас,и проверить работу, самого SELECT'a

SELECT * FROM OPENQUERY ([FBDB],'SELECT * FROM tbl_from') a
WHERE NOT EXISTS
(SELECT * FROM tbl_to WHERE tbl_to.name = a.Name)

вернет ли он только новые записи ?

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

Попробовала так:

SELECT* FROM openquery ([FBDB],'Select R_ID From Record') a
WHERE NOT EXISTS
(SELECT * FROM a WHERE a.R_ID <17242)

Invalid object name 'a'.

Если просто:

SELECT* FROM openquery ([FBDB],'Select R_ID From Record') a
WHERE a.R_ID >=17242

Все отлично, а в подзапросе не указано что такое "а"

Яворский Алексей

Елена, запросом

SELECT* FROM openquery ([FBDB],'Select R_ID From Record') a
WHERE a.R_ID >=17242

вы определяете что openquery ([FBDB],'Select R_ID From Record') это алиас a, и потом уже фильтруете, SQL подставяет вместо a = openquery ([FBDB],'Select R_ID From Record') и вы получаете фильтр openquery ([FBDB],'Select R_ID From Record').R_ID >=17242

Запрос

SELECT * FROM a WHERE a.R_ID <17242

ищет таблицу а, ее не находит, и выдает ошибку Invalid object name 'a', так как во FROM запрос еще не видит таблицы определенной выше

Попробуйте запустить запрос подобный http://www.community.terrasoft.ru/forum/topic/6843#comment-31260

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки

Перепечай Елена

SELECT* FROM openquery ([FBDB],'Select R_ID From Record') a
WHERE NOT EXISTS
(SELECT * FROM tbl_AttendenceFoto WHERE AttendenceFoto.R_ID =a.R_ID)

Работает!!!!
Большое спасибо!!!!