【问题标题】:Yii2: query across two databasesYii2:跨两个数据库查询
【发布时间】:2019-07-29 19:42:15
【问题描述】:

我有两个数据库(一个在 Oracle 中,一个在 mySQL 中),我需要以某种方式加入数据。

以下查询有效:

$qry = oracleTableName::find()
  ->with('mysqlTableName')
  ->asArray()
  ->all();

并返回以下布局:

 [0]=> array(
    [id] => 1
    [name] => test
    [mysqlID] => 7
    [mysqlTableName] => array(
       [id]=>7
       [score]=>1
    )
  )

但是,如果我使用 select 语句,它会失败,(说 mysqlTableName.id 列是无效标识符):

$qry = oracleTableName::find()
  ->with('mysqlTableName')
  ->select([
       'oracleTableName.id as OracleID',
       'mysqlTableName.id as MysqlID',
       'mysqlTableName.score as Score'
   ])
  ->asArray()
  ->all();

如何从两个数据库中进行选择(或“访问”mysql 结果),以便我有一个输出,即:

[0]=>array(
  [OracleID]=>1
  [MysqlID]=>7
  [Score]=>3

谢谢

更新

这是实际的查询和输出: 注意:在本例中,“MapInvestorToOpportunity”表是 mysql,“INVESTOR”表是 Oracle

这很好用:

$performance= MapInvestorToOpportunity::find()
    ->with('investor') 
    ->andWhere(['fk_opportunityID' => $this->fk_opportunityID])
    ->limit(5)
    ->asArray()
    ->all();

并产生以下输出:

Array
(
    [0] => Array
        (
            [id] => 43797
            [uid] => 0451/0258_DD45834-99207
            [fk_opportunityID] => 3
            [status] => 1
            [fk_investorID] => 99207
            [investor] => Array
                (
                    [INVESTOR_ID] => 99207
                    [COUNTRY_ID] => US
                    [PRIMARY_INSTITUTION] => DD71233

我可以清楚地看到国家/地区 ID。但是,一旦我选择了国家 ID,它就会失败:

$performance= MapInvestorToOpportunity::find()
    ->with('investor') // or ('investor INVESTOR')
    ->andWhere(['fk_opportunityID' => $this->fk_opportunityID])
    ->select([
         'fk_opportunityID',
         'fk_investorID',
         'map_investor_to_opportunity.INVESTOR_ID',
         'COUNTRY_ID', // or 'INVESTOR.COUNTRY_ID'
     ])
    ->limit(5)
    ->asArray()
    ->all();

Column not found: 1054 Unknown column 'INVESTOR.COUNTRY_ID' in 'field list'
The SQL being executed was: SELECT `fk_opportunityID`, `fk_investorID`, `INVESTOR`.`COUNTRY_ID` FROM `map_investor_to_opportunity` WHERE `fk_opportunityID`='3' LIMIT 5

我的理解是不可能在查询中加入数据,因为它是两个不同的数据库。但是,我只是想确定一下……考虑到数组输出清楚地显示了来自 Oracle 数据库的数据,这似乎有点疯狂

非常感谢

【问题讨论】:

  • 这纯属猜测,如果没有帮助,我提前道歉。 oracle是区分大小写的,你试过ORACLETABLENAME.ID吗?
  • 您可以创建从 Oracle 到 MySQL 的数据库链接,并将其全部加入 Oracle SQL 引擎。来自此来源的示例:hs2n.wordpress.com/2012/04/03/…

标签: oracle activerecord yii2


【解决方案1】:

我认为不可能在两个完全独立的 DBMS 之间创建 JOIN。 with() 将注册预先加载规则,但不会在两个表之间创建实际连接 - 它会执行两个单独的查询以获得必要的模型。

要创建实际连接,您应该使用joinWith() 而不是with()

$qry = oracleTableName::find()
  ->joinWith('mysqlTableName')
  ->select([
       'oracleTableName.id as OracleID',
       'mysqlTableName.id as MysqlID',
       'mysqlTableName.score as Score'
   ])
  ->asArray()
  ->all();

但这很可能会失败,因为不支持跨数据库连接。

可能你能得到的最好的结果是单独查询结果并在 PHP 级别组合它们。

【讨论】:

  • 谢谢 rob006 - 我认为你是对的。感谢您的帮助。
【解决方案2】:

您应该在表名后添加一个表标识符。

$qry = oracleTableName::find()
  ->with('mysqlTableName msql')
  ->select([
       'oracleTableName.id as OracleID',
       'msql.id as MysqlID',
       'msql.score as Score'
   ])
  ->asArray()
  ->all();

原因是,with 子句接受关系名称,而不是表名称,这可能略有不同,但足够不同。如果这不起作用,请对此查询的结果发表评论,我将相应地编辑答案

$qry = oracleTableName::find()
      ->with('mysqlTableName msql')
      ->select([
           'oracleTableName.id as OracleID',
           'msql.id as MysqlID',
           'msql.score as Score'
       ])
      ->createCommand()->rawSql;

【讨论】:

  • 谢谢马丁 - 我已经更新了我的帖子。您的建议无效。
  • @DrBorrow 您是否尝试过通过map_investor_to_opportunity.COUNTRY_ID 访问它,就像您调用INVESTOR_ID 一样。它们都在同一个范围内。另外,另一方面,如果您不严格要求它是一个数组,您可以通过$performance->investor->COUNTRY_ID 访问它。请告诉我这是否有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 2012-11-17
相关资源
最近更新 更多