zf2 make a join between two different databases

故事扮演 提交于 2019-12-07 07:31:09

问题


I am trying to make a join between two tables placed in different databases with Zend Framework 2.

The first table is called users and is stored in the database admin

The second table is called hierarchy and is stored in the database customer

I load the databases adapters in global.php

return array(
'admin' => array(
    'driver' => 'Pdo',
    'dsn' => 'mysql:dbname=admin;host=localhost',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),
),
'customer' => array(
    'driver' => 'Pdo',
    'dsn' => 'mysql:dbname=customer;host=localhost',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),
),
'service_manager' => array(
    'factories' => array(
        'Zend\Db\Adapter\Adapter'
        => 'Zend\Db\Adapter\AdapterServiceFactory',
    ),
),

);

But when I try to make a join in UserDao with this function:

public function getSelect(Hierarchy $hierarchy) {
    $select = $this->tableGateway->getSql()->select();
    $select->where(array('level' => $hierarchy()->getId()));
    $select->join(array('h' => 'hierarchies'), 'h.id = users.idHierarchy', array('hierarchyId' => 'id', 'level' => 'level'));
    return $select;
}

This generate this SQL sentence:

SELECT "users".*, "h"."id" AS "hierarchyId", "h"."level" AS "level" FROM "users" INNER JOIN "hierarchies" AS "h" ON "h"."id" = "users"."idHierarchy" WHERE "level" = '1'

But it throws this exception when I try to use it:

Zend\Db\Adapter\Exception\InvalidQueryException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'admin.hierarchies' doesn't exist

I try to indicate the name of the database int the join like this:

$select->join(array('h' => 'customer.hierarchies'), 'h.id = users.idHierarchy', array('hierarchyId' => 'id', 'level' => 'level'));

But it throws this exception too:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'admin.customer.hierarchies' doesn't exist

I found this web where explained how I can do it, but it's only valid for Zend Framework 1 and I'm working with Zend Framework 2.

Using Different Databases with Zend Framework

Could somebody help me? Please.

Thanks!


回答1:


Looks like this question was asked a while back, but I seem to have found a good workaround or solution. If you utilize the Zend\Db\Sql\TableIdentifier and Zend\Db\Sq\Expression, you will be able to get around your issue.

public function getSelect(Hierarchy $hierarchy) {
    $select = $this->tableGateway->getSql()->select();
    $select->where(array('level' => $hierarchy()->getId()));
    $select->join(
         array('h' => new TableIdentifier('hierarchies', 'admin')), 
         new Expression('h.id = ?', 'users.idHierarchy', Expression::TYPE_IDENTIFIER), 
         array('hierarchyId' => 'id', 'level' => 'level')
    );
    return $select;
}

I wasn't sure which database your hierarchies table is in so I used 'admin' for now. YOu can replace it with which ever database name you have. See if it works for you, seems to work nicely for me.




回答2:


The framework does not support a join with another database. You have to use plain SQL for building the query.




回答3:


The issue is occurring because of the way the Select class escapes quotes.

$select->join("database2.table2", "database2.table2.id = table.id")

Is rendered as:

SELECT 'table'.* 'database2.table2'.* FROM 'table' INNER JOIN 'database2.table2' ON 'database2'.'table2'.'id' = 'table'.'id'

Note the inconsistant and incorrect quoting around "database2.table2".

Updating lines 596, 599, 624, 625 in \Zend\Db\Sql\Select to replace the "quoteIdentifier" method with "quoteIdentifierInFragment" renders the query correctly and allows a cross database join to be performed.

I've submitted an issue report to Zend as I don't believe the current behaviour is intended so hopefully it will be updated in a future build. For now it's easy enough (though admittedly a little dirty) to update the class manually.

https://github.com/zendframework/zf2/issues/4307




回答4:


As Dan has answered, but for Zend 2.3 you should change line 742 in file Zend\Db\Sql\Select.php from

$joinName = $platform->quoteIdentifier($joinName);

to

$joinName = $platform->quoteIdentifierInFragment($joinName);

and line 680 from

$name = $platform->quoteIdentifier($name);

to

$name = $platform->quoteIdentifierInFragment($name);


Obs: These are only the lines that I could identify, and may not be a complete list.



来源:https://stackoverflow.com/questions/15830774/zf2-make-a-join-between-two-different-databases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!