Перекрестное соединение базы данных прогресса через 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+).

Итак, шаги, которые я предпринял, были:

  1. Создайте файл конфигурации oesql.properties согласно статье, относящейся к основной и пользовательской базам данных.
  2. Создайте системный DSN ODBC на клиентском компьютере (в моем случае на компьютере с Windows Server 2008 R2, на котором запущен SQL Server 2008 R2 с SSRS) с дополнительными ссылками на базы данных в соответствии со статьей.
  3. Создайте связанный сервер в SQL Server через ODBC DSN
  4. Создайте представление, которое использует синтаксис OpenQuery для извлечения данных из QAD (в моем случае это было создано в базе данных ReportServer) через связанный сервер.
  5. Создайте стандартный запрос 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, проприетарном решении, которое (не совсем уверенно) могло бы реализовать этот последний сценарий.

В итоге:

Если ваша ситуация не соответствует первому сценарию (который указывает на наиболее очевидный подход), я думаю, что самое короткое решение - это профилирование вашего кода и оптимизация возможных узких мест производительности. Адаптация вашего кода для параллельной обработки может быть более смелым улучшением.

Другие вопросы по тегам