Перекрестное соединение базы данных прогресса через OpenEdge ODBC и PHP
В настоящее время на моем веб-сервере установлено 2 подключения ODBC. Один, который подключается к нашей корпоративной базе данных QAD, а другой - к нашей пользовательской базе данных, используемой для расширения нашей базы данных. В этом специфическом примере у меня есть записи сотрудников в базе данных QAD, а затем номер сотрудника в другой таблице в пользовательской базе данных.
Можно ли как-нибудь настроить перекрестное соединение между двумя соединениями odbc в php, чтобы мне не приходилось циклически просматривать результаты первого запроса и отправлять несколько запросов на основе возвращенных результатов, чтобы связать мои записи в массив php?
Лучшее, что я смог придумать, - это создать предложение IN из моего первого запроса из нашей пользовательской базы данных, отправить второй запрос в базу данных QAD, а затем выполнить слияние массива в php. Однако это очень медленный процесс по сравнению с обычным соединением SQL.
3 ответа
Не уверен, что вы уже нашли решение, но есть статья о том, как это сделать.
Краткое руководство по настройке подключения ODBC для нескольких баз данных
У меня было похожее требование - я хотел создать соединение между таблицей в основной базе данных QAD и пользовательской таблицей в нашей пользовательской базе данных. Я проверил это, и он работает хорошо, хотя мои настройки немного отличаются. Мне нужно было подключиться к QAD из Microsoft SSRS для создания отчетов по данным QAD - мне нужно было создать несколько отчетов, которые не мог обработать стандартный конструктор отчетов QAD.
Я проверил это на Progress 10.1c (этот метод поддерживается только в 10.1b+).
Итак, шаги, которые я предпринял, были:
- Создайте файл конфигурации oesql.properties согласно статье, относящейся к основной и пользовательской базам данных.
- Создайте системный DSN ODBC на клиентском компьютере (в моем случае на компьютере с Windows Server 2008 R2, на котором запущен SQL Server 2008 R2 с SSRS) с дополнительными ссылками на базы данных в соответствии со статьей.
- Создайте связанный сервер в SQL Server через ODBC DSN
- Создайте представление, которое использует синтаксис OpenQuery для извлечения данных из QAD (в моем случае это было создано в базе данных ReportServer) через связанный сервер.
- Создайте стандартный запрос T-SQL, используя представление в пункте 3 в качестве источника данных. В конечном итоге это был источник данных для моего отчета по SSRS.
Я считаю, что важно, чтобы битовые версии ОС / базы данных и драйверы ODBC совпадали, но еще не подтвердили это.
Хотя мое требование отличается от вашего, в конечном счете, это конфигурация сервера QAD и настройка ODBC. Пока ваш PHP-клиент может выполнять аналогичную функцию с точки зрения команды OpenQuery, тогда вы можете получить эту работу. У меня нет опыта работы с PHP, поэтому я не могу вам помочь.
Это кажется немного запутанным, но на самом деле работает очень хорошо, и во многих случаях фактически превосходит запросы данных, используя просмотры QAD!
Надеюсь это поможет.
Редактировать: Вот пример команды OpenQuery - вы можете видеть, что объединения таблиц работают обычным образом, но просто требуют и дополнительной части в ссылке на таблицу.
CREATE VIEW [dbo].[vQADData] AS SELECT * FROM OPENQUERY(LinkedServerName,
'
SELECT custTable.item_date AS DESP_DATE, so_mstr.so_site AS SITE, so_mstr.so_po AS PO_NO, so_mstr.so_inv_nbr AS INV_NO,
ad_mstr.ad_name AS ADNAME, ad_mstr.ad_city AS ADCITY, ad_mstr.ad_state AS ADSTATE
FROM customdbname.pub.customtable custTable
INNER JOIN pub.so_mstr ON so_mstr.so_nbr = custTable.so_nbr
INNER JOIN pub.ad_mstr ON ad_mstr.ad_addr = so_mstr.so_ship
INNER JOIN pub.sod_det ON sod_det.sod_nbr = custTable.so_nbr
WHERE so_mstr.so_site = ''SiteName'' AND so_mstr.so_shipvia = ''SHIPPER'' AND custTable.item_date IS NULL
')
Затем просто получите доступ к представлению, используя обычный синтаксис SQL.
SELECT * FROM vQADData
Спасибо Тирану за предложенное решение. Для тех людей, которые пытаются ссылаться на несколько таблиц через SQL-сервер, как это делал Тиран, у меня есть дополнительный вклад.
Я пытаюсь получить данные из нескольких источников (Progress), с одинаковой структурой таблиц одновременно и вставить их в наше хранилище данных (SQL Server). Поэтому я просто пытаюсь объединить несколько одинаковых структурированных таблиц в разных базах данных. Решение Тирана подтолкнуло меня к тому же пути, но связывание баз данных Progress было обременительным процессом, который потребовал от меня найти администратора баз данных Progress с 2-3 днями свободного времени (его цитата), чтобы собрать все вместе. Когда я общался с людьми из Progress напрямую, они также указывали, что, если бы я создал представление с объединением на стороне Progress, оно будет последовательно извлекать данные из каждого источника в представлении, а не одновременно. Тем не менее, это привело меня к другому открытию, которое, похоже, решит наши задачи и полностью пропустит работу по связыванию таблиц на стороне прогресса.
Вот пример с тремя источниками, одинаковыми таблицами (это должно работать и для разных источников, объединяющих разные таблицы). Все имена здесь приведены только для ясности в примерах.
Source 1 - Table_A
Source 2 - Table_A
Source 3 - Table_A
- Создайте соединение ODBC с источником 1 с именем source1.
- Создайте соединение ODBC с источником 2 с именем source2.
- Создайте соединение ODBC с источником 3 с именем source3. (Обратите внимание, что вы обычно хотите установить для параметра подключения значение Чтение незафиксированным).
В SQL Server создайте связанные серверные соединения с каждым источником.
ls_source1
ls_source2
ls_source3
В вашей базе данных SQL Server, в которой вам нужно сослаться на базы данных Progress, создайте представление, объединяющее три разных связанных серверных соединения, используя объединение. Для каждой ссылки на сервер необходимо использовать openquery. В этом примере, использующем select * из каждого источника связанных серверов, предполагается, что все столбцы названы и структурированы одинаково из каждого источника.
CREATE VIEW table_name_v as
SELECT *
FROM
(SELECT *
FROM OPENQUERY(ls_source1,
'select *
from source1.dbo.Table_A
')
union
SELECT *
FROM OPENQUERY(ls_source2,
'select *
from source2.dbo.Table_A
'
union
SELECT *
FROM OPENQUERY(ls_source3,
'select *
from source3.dbo.Table_A
'
)
) x
Создав представление, вы можете одновременно запрашивать все три таблицы в разных источниках Progress. Никаких дополнительных настроек на стороне прогресса не требуется.
Есть важное предупреждение, над которым я сейчас работаю. Если вы работаете на 64-битной машине, использующей 64-битный SQL Server, вам нужно использовать 64-битный драйвер для подключения к базе данных Progress с опцией связанного сервера. Мои потребности требуют, чтобы у меня были и 32-битные, и 64-битные драйверы на одной и той же машине, и у меня возникли проблемы с этим, потому что, очевидно, они не очень хорошо играют вместе на одной машине. Мне удалось установить как 64-битные, так и 32-битные драйверы на одну и ту же машину (на веб-сайте Progress был сбой, который должен был отправить мне ссылку на этот драйвер, но я смог найти там кого-нибудь, чтобы он направил меня в нужное место). чтобы получить 64-битный драйвер odbc. Обычному человеку не нужны оба драйвера, и он может просто использовать 64-битный. В качестве альтернативы, если я не могу установить оба драйвера на одной машине, я обнаружил, что и подтвердил, что компания Connx предоставляет драйвер, который обеспечивает 64-битный /32-битный мост, который решает эту проблему для меня. В идеале, однако, никакого стороннего программного обеспечения не потребуется.
К сожалению, возникла новая проблема, так как я установил и использовал связанные серверы, которые больше не работают должным образом. Два шага вперед, один шаг назад....
Просто подумал, что поделюсь своими выводами, так как я уверен, что есть другие, которые ищут
Короткий ответ: вы не можете JOIN
таблицы между двумя связями.
Сценарии: (все они в одном соединении)
- По умолчанию в большинстве баз данных можно объединять таблицы в разных схемах, добавляя префикс имени схемы перед таблицей, например:
(...) FROM defaultDB.TableA INNER JOIN extensionDB.TableA ON ({Condition}) (...)
В зависимости от вашей базы данных (я не знаю глубоко о Progress DB), вы не сможете присоединиться к таблицам, принадлежащим схемам на разных серверах.
Объединять таблицы в разных базах данных (например, Progress x MySQL) еще сложнее. Я слышал о Oracle Gateway, проприетарном решении, которое (не совсем уверенно) могло бы реализовать этот последний сценарий.
В итоге:
Если ваша ситуация не соответствует первому сценарию (который указывает на наиболее очевидный подход), я думаю, что самое короткое решение - это профилирование вашего кода и оптимизация возможных узких мест производительности. Адаптация вашего кода для параллельной обработки может быть более смелым улучшением.