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

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

В Террасофт стоит 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

Нравится

37 комментариев

Здравствуйте Елена,
К примеру, хоти получить колонку 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 тесовых сервисов прикрепил.

Большое спасибо! Все заработало!
Только строку подключения в 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=адрес"

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

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

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

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

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

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

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

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

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

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

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

Поставила 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, проверьте, пожалуйста, прописан ли он.

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

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

перешла с ХР на 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=219… )

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

Удалось добиться успешной проверки соединения, выбрав поставщиком 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". Оригинальное сообщение об ошибке: Произошла одна или несколько ошибок во время обработки команды"

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

В 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

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

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

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

SELECT "P_FAM" FROM "PEOPLE"

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

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

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

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

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

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

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

Елена, сложность в обоих вариантах состоит в том что бы написать запрос в 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

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

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

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

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

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

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

Пример :

insert into tbl_to 
select * from tbl_from 
where not exists 
(select * from tbl_to where tbl_to.name = tbl_from.name)

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

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)

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

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

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

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

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

Сделала все по инструкции, однако не проходит проверка соединения при создании драйвера (Не удалось открыть базу). База расположена на диске D, адрес на латинице.
В чем может быть проблема? Что посоветуете для ее решения?

Здравствуйте.

Уточните пожалуйста, какую именно инструкцию выполнили?
Прикрепите файлы с изображением на которых будет видны Ваши настройки.

Показать все комментарии