4

我正在尝试使用 Zend Framework 2 在放置在不同数据库中的两个表之间进行连接。

第一个表称为users并存储在数据库admin中

第二个表称为层次结构,存储在数据库客户中

我在 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',
    ),
),

);

但是当我尝试使用此功能加入 UserDao 时:

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;
}

这会生成这个 SQL 语句:

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

但是当我尝试使用它时它会抛出这个异常:

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

我尝试在连接中指示数据库的名称,如下所示:

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

但它也抛出了这个异常:

SQLSTATE [42S02]:未找到基表或视图:1146 表 'admin.customer.hierarchies' 不存在

我发现这个网站解释了我如何做到这一点,但它只对 Zend Framework 1 有效,我正在使用 Zend Framework 2。

在 Zend 框架中使用不同的数据库

有人可以帮我吗?请。

谢谢!

4

5 回答 5

3

看起来这个问题是不久前被问到的,但我似乎找到了一个很好的解决方法或解决方案。如果您使用 Zend\Db\Sql\TableIdentifier 和 Zend\Db\Sq\Expression,您将能够解决您的问题。

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;
}

我不确定您的层次结构表在哪个数据库中,所以我现在使用“admin”。您可以将其替换为您拥有的任何数据库名称。看看它是否适合你,似乎对我来说很好用。

于 2013-08-05T21:33:03.887 回答
0

该框架不支持与另一个数据库的联接。您必须使用纯 SQL 来构建查询。

于 2013-04-08T17:23:45.477 回答
0

由于 Select 类转义引号的方式,出现此问题。

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

呈现为:

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

请注意围绕“database2.table2”的不一致和不正确的引用。

更新 \Zend\Db\Sql\Select 中的第 596、599、624、625 行以将“quoteIdentifier”方法替换为“quoteIdentifierInFragment”可以正确呈现查询并允许执行跨数据库连接。

我已经向 Zend 提交了一份问题报告,因为我不相信当前的行为是有意的,因此希望它会在未来的构建中得到更新。现在手动更新类已经很容易了(尽管确实有点脏)。

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

于 2013-04-24T13:38:37.300 回答
0

正如 Dan 回答的那样,但对于Zend 2.3,您应该将文件Zend\Db\Sql\Select.php中的第 742 行

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

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

第 680 行

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

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


Obs:这些只是我可以识别的行,可能不是完整的列表。

于 2013-12-02T11:31:15.487 回答
0

为什么要使用 DAO 概念?只有在表网关中,您才能拥有所需的一切。您已经在 global 或 local.php 中有适配器。您已经有用于表网关的工厂,不是吗?为什么需要将 Hierarchy 类(我认为它是另一个表网关)传递给当前类?要进行所需的连接,您唯一需要的是表标识符。

$table2 = new Zend\Db\Sql\TableIdentifier('table2', 'schema_name'); 
$select = $this->tableGateway->getSql()->select()
->join($table2, 'table1.field = table2.field', ['fields_from_table2'], 'INNER');

$sql = new Sql($this->tableGateway->getAdapter());
$selectString = $sql->buildSqlString($select);
$result = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);

查看这个问题的答案

于 2020-06-13T06:00:41.710 回答