【问题标题】:Cross Join Progress Database via OpenEdge ODBC and PHP通过 OpenEdge ODBC 和 PHP 交叉加入进度数据库
【发布时间】:2012-10-12 16:01:17
【问题描述】:

我目前在我的网络服务器上设置了 2 个 ODBC 连接。一个连接到我们的企业 QAD 数据库,另一个连接到用于扩展我们的数据库的自定义数据库。在这个特定的示例中,我在 QAD 数据库中保存了我的员工记录,然后在自定义数据库的另一个表中保存了员工编号。

有什么方法可以让我在 php 中的两个 odbc 连接之间建立交叉连接,这样我就不必遍历第一个查询的结果并根据返回的结果发送多个查询来绑定我的一起记录在一个php数组中?

我能想到的最好的方法是从我们的自定义数据库中的第一个查询构建一个 IN 子句,将第二个查询发送到 QAD 数据库,然后在 php.ini 中进行数组合并。但是,与普通的 SQL 连接相比,这是一个极其缓慢的过程。

【问题讨论】:

  • OpenEdge,嗯?我有一个有趣的解决方案,但它仅适用于 JDBC(在 OpenEdge 10+ 上)和 Ruby。可能使您的方案不可行,但如果不是,请告诉我。

标签: php odbc progress-4gl openedge


【解决方案1】:

不确定您是否已经找到解决方案,但有一篇关于如何做到这一点的进度文章。

Quick Guide To Setting Up MultiDatabase ODBC Connectivity

我有一个类似的要求 - 我想在主 QAD 数据库中的一个表和我们自定义数据库中的一个自定义表之间创建一个连接。我已经对此进行了测试,尽管我的设置略有不同,但它运行良好。我需要从 Microsoft SSRS 连接到 QAD 以针对 QAD 数据创建报告 - 我需要创建一些标准 QAD 报告设计器无法处理的报告。

我已在 Progress 10.1c 上对此进行了测试(此方法仅在 10.1b+ 中支持)。

所以我采取的步骤是:

  1. 根据与主数据库和自定义数据库相关的文章创建 oesql.properties 配置文件。
  2. 在客户端机器上创建 ODBC 系统 DSN(在我的例子中是一台运行带有 SSRS 的 SQL Server 2008 R2 的 Windows Server 2008 R2 机器),并根据文章附加数据库引用。
  3. 通过 ODBC DSN 在 SQL Server 中创建链接服务器
  4. 创建一个视图,该视图使用 OpenQuery 语法通过链接服务器从 QAD 中提取数据(在我的例子中,这是在 ReportServer 数据库中创建的)。
  5. 使用第 3 点中的视图作为数据源创建标准 T-SQL 查询。这最终是我的 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

【讨论】:

  • 不是我希望的简单答案,但我认为这是我将要找到的答案。
【解决方案2】:

感谢 Tiran 提出的解决方案。对于那些像 Tiran 一样尝试通过 SQL 服务器引用多个表的人,我有额外的意见。

我正在尝试同时从多个来源(进度)、相同的表结构中提取数据并将其插入我们的数据仓库(SQL Server)。所以我只是想在不同的数据库中合并多个相同的结构化表。 Tiran 的解决方案让我走上了同样的道路,但是 Progress 数据库的链接是一个繁琐的过程,需要我找到一个有 2-3 天空闲时间的 Progress DBA(他的报价)来把它放在一起。当我直接与 Progress 的人交谈时,他们还指出,如果我在 Progress 端创建一个带有 union 的视图,它将按顺序从视图中的每个源中提取数据,而不是同时提取。然而,这让我发现了另一个发现,它看起来可以解决我们的需求,并且完全跳过了处理进度方面的链接表。

这是一个包含三个源、相同表的示例(这也适用于跨源连接的不同表)。此处提供的所有名称只是为了在示例中清晰。

Source 1 - Table_A
Source 2 - Table_A
Source 3 - Table_A
  • 创建到名为 source1 的源 1 的 ODBC 连接。
  • 创建到名为 source2 的源 2 的 ODBC 连接。
  • 创建到名为 source3 的源 3 的 ODBC 连接。 (注意,您通常希望确保将连接设置设置为未提交读取)。

在 SQL Server 中,创建到每个源的链接服务器连接。

ls_source1
ls_source2
ls_source3

在您需要引用 Progress 数据库的 SQL Server 数据库中,创建一个使用联合将三个不同的链接服务器连接连接在一起的视图。每个链接服务器引用都需要使用 openquery。这个使用 select * from each linked server source 的示例假定每个源中的所有列的名称和结构都相同。

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 位 SQL Server 的 64 位计算机上,则需要使用 64 位驱动程序通过链接服务器选项连接到 Progress 数据库。我的需求要求我在同一台机器上同时拥有 32 位和 64 位驱动程序,并且遇到了问题,因为显然它们在同一台机器上不能很好地协同工作。我已经能够在同一台机器上同时安装 64 位和 32 位驱动程序(Progress 网站出现故障,本应向我发送该驱动程序的链接,但我能够让那里的人将我引导到正确的地方检索 64 位 odbc 驱动程序。一般人不应该需要两个驱动程序,可以只使用 64 位。作为替代解决方法,如果我不能让两个驱动程序在同一台机器上共存,我发现并确认 Connx 公司提供了一个驱动程序,该驱动程序提供了一个 64 位/32 位桥接器,可以为我解决这个问题。但理想情况下,不需要第三方软件。

不幸的是,现在出现了一个新问题,因为我设置和使用的链接服务器不再正常运行。前进两步,后退一步……

只是想我会分享我的发现,因为我确信还有其他人在寻找。

【讨论】:

  • 这是很好的信息。我很好奇这样做是否真的有很大的性能提升,而不是仅仅连接到从应用程序到 3 个数据源的进度并加入应用程序本身,但无论如何都很高兴知道。
【解决方案3】:

简答:您不能在两个连接之间使用JOIN 表。

场景:(所有场景都在一个连接中)

  • 默认情况下,在大多数数据库中,您可以通过在表前添加架构名称前缀来连接不同架构中的表,如下所示:

(...) FROM defaultDB.TableA INNER JOIN extensionDB.TableA ON ({Condition}) (...)

  • 根据您的数据库(我对 Progress DB 了解不深),您可能无法加入属于不同服务器中模式的表。

  • 连接不同数据库中的表(例如:Progress x MySQL)甚至更加复杂。我听说过Oracle Gateway,这是一种专有解决方案,(不太确定)可以实现最后一种情况。

总结:

如果您的情况不符合第一种情况(这指向最明显的方法),我想最短的解决方案是分析您的代码并优化可能的性能瓶颈。为parallel processing 调整您的代码可能是一个更大胆的改进。

【讨论】:

  • 不幸的是,我认为我需要为我的不同数据库设置不同的代理,而且我的理解是它们需要在不同的端口上运行,这迫使我使用两个单独的 ODBC。如果有其他证据,尽管我非常有兴趣将两个 odbc 组合成一个来实现这一点。
猜你喜欢
  • 2013-10-23
  • 2015-09-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2021-01-22
  • 1970-01-01
相关资源
最近更新 更多