Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php zend framework 2使用oracle适配器连接子选择_Php_Sql_Oracle_Zend Framework2 - Fatal编程技术网

Php zend framework 2使用oracle适配器连接子选择

Php zend framework 2使用oracle适配器连接子选择,php,sql,oracle,zend-framework2,Php,Sql,Oracle,Zend Framework2,我在互联网上搜索过,大部分答案适用于ZF1。 我想使用select对象将一个子select查询连接到另一个select查询中。对于我来说,在多个这样的连接结束时获得整个选择对象是至关重要的 代码如下所示: $subSelect = new Select(); $subSelect->from(array('TABLE' => 'SOME_TABLE')); $subSelect->columns(array('ID')); $select = new Select(); $se

我在互联网上搜索过,大部分答案适用于ZF1。
我想使用select对象将一个子select查询连接到另一个select查询中。对于我来说,在多个这样的连接结束时获得整个选择对象是至关重要的

代码如下所示:

$subSelect = new Select();
$subSelect->from(array('TABLE' => 'SOME_TABLE'));
$subSelect->columns(array('ID'));
$select = new Select();
$select->from(array('SEC_TABLE' => 'SOME_ANOTHER_TABLE'));
$select->join(
    array('SUB' => $subSelect),
    'SUB.ID = SEC_TABLE.ID',
    array(),
    $select::JOIN_LEFT
);
在ZF1中使用class
Zend_Db_Expr
是可能的,在ZF2中有什么好方法可以做到这一点吗?

答案如下

在ZF2中,可以使用其
Select::combine()
方法组合两个Select对象实例

$select->combine($subSelect);
答案是这样的

在ZF2中,可以使用其
Select::combine()
方法组合两个Select对象实例

$select->combine($subSelect);

我尝试使用
Select::combine()
,但它是用于
UNION
INTERSECT
等内容的功能,这些关键字放在Select语句之间。我需要纯
JOIN
,问题是ZF2中的Oracle适配器覆盖了
processJoins
方法的标准方法。 这是来自
Zend/Db/Sql/Select

protected function processJoins(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
    {
        if (!$this->joins) {
            return null;
        }

        // process joins
        $joinSpecArgArray = array();
        foreach ($this->joins as $j => $join) {
            $joinSpecArgArray[$j] = array();
            $joinName = null;
            $joinAs = null;

            // type
            $joinSpecArgArray[$j][] = strtoupper($join['type']);

            // table name
            if (is_array($join['name'])) {
                $joinName = current($join['name']);
                $joinAs = $platform->quoteIdentifier(key($join['name']));
            } else {
                $joinName = $join['name'];
            }
            if ($joinName instanceof ExpressionInterface) {
                $joinName = $joinName->getExpression();
            } elseif ($joinName instanceof TableIdentifier) {
                $joinName = $joinName->getTableAndSchema();
                $joinName = ($joinName[1] ? $platform->quoteIdentifier($joinName[1]) . $platform->getIdentifierSeparator() : '') . $platform->quoteIdentifier($joinName[0]);
            } else {
                if ($joinName instanceof Select) {
                    $joinName = '(' . $this->processSubSelect($joinName, $platform, $driver, $parameterContainer) . ')';
                } else {
                    $joinName = $platform->quoteIdentifier($joinName);
                }
            }
            $joinSpecArgArray[$j][] = (isset($joinAs)) ? $joinName . ' AS ' . $joinAs : $joinName;

            // on expression
            // note: for Expression objects, pass them to processExpression with a prefix specific to each join (used for named parameters)
            $joinSpecArgArray[$j][] = ($join['on'] instanceof ExpressionInterface)
                ? $this->processExpression($join['on'], $platform, $driver, $this->processInfo['paramPrefix'] . 'join' . ($j+1) . 'part')
                : $platform->quoteIdentifierInFragment($join['on'], array('=', 'AND', 'OR', '(', ')', 'BETWEEN', '<', '>')); // on
            if ($joinSpecArgArray[$j][2] instanceof StatementContainerInterface) {
                if ($parameterContainer) {
                    $parameterContainer->merge($joinSpecArgArray[$j][2]->getParameterContainer());
                }
                $joinSpecArgArray[$j][2] = $joinSpecArgArray[$j][2]->getSql();
            }
        }

        return array($joinSpecArgArray);
    }
由于标准的
Select
类允许您加入另一个
Select
(行:
if($joinName instanceof Select){
),Oracle扩展版本不允许这样做。
这只是Zend中的一个bug吗?
有什么办法吗?

它没有以任何方式连接到Oracle规范,为什么会这样呢?

我尝试使用
Select::combine()
但它是用于诸如
UNION
INTERSECT
减号
-在select语句之间放置关键字的功能。我需要纯
JOIN
,问题是ZF2中的Oracle适配器覆盖了
processJoins
方法的标准方法。 这是来自
Zend/Db/Sql/Select

protected function processJoins(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
    {
        if (!$this->joins) {
            return null;
        }

        // process joins
        $joinSpecArgArray = array();
        foreach ($this->joins as $j => $join) {
            $joinSpecArgArray[$j] = array();
            $joinName = null;
            $joinAs = null;

            // type
            $joinSpecArgArray[$j][] = strtoupper($join['type']);

            // table name
            if (is_array($join['name'])) {
                $joinName = current($join['name']);
                $joinAs = $platform->quoteIdentifier(key($join['name']));
            } else {
                $joinName = $join['name'];
            }
            if ($joinName instanceof ExpressionInterface) {
                $joinName = $joinName->getExpression();
            } elseif ($joinName instanceof TableIdentifier) {
                $joinName = $joinName->getTableAndSchema();
                $joinName = ($joinName[1] ? $platform->quoteIdentifier($joinName[1]) . $platform->getIdentifierSeparator() : '') . $platform->quoteIdentifier($joinName[0]);
            } else {
                if ($joinName instanceof Select) {
                    $joinName = '(' . $this->processSubSelect($joinName, $platform, $driver, $parameterContainer) . ')';
                } else {
                    $joinName = $platform->quoteIdentifier($joinName);
                }
            }
            $joinSpecArgArray[$j][] = (isset($joinAs)) ? $joinName . ' AS ' . $joinAs : $joinName;

            // on expression
            // note: for Expression objects, pass them to processExpression with a prefix specific to each join (used for named parameters)
            $joinSpecArgArray[$j][] = ($join['on'] instanceof ExpressionInterface)
                ? $this->processExpression($join['on'], $platform, $driver, $this->processInfo['paramPrefix'] . 'join' . ($j+1) . 'part')
                : $platform->quoteIdentifierInFragment($join['on'], array('=', 'AND', 'OR', '(', ')', 'BETWEEN', '<', '>')); // on
            if ($joinSpecArgArray[$j][2] instanceof StatementContainerInterface) {
                if ($parameterContainer) {
                    $parameterContainer->merge($joinSpecArgArray[$j][2]->getParameterContainer());
                }
                $joinSpecArgArray[$j][2] = $joinSpecArgArray[$j][2]->getSql();
            }
        }

        return array($joinSpecArgArray);
    }
由于标准的
Select
类允许您加入另一个
Select
(行:
if($joinName instanceof Select){
),Oracle扩展版本不允许这样做。
这只是Zend中的一个bug吗?
有什么办法吗?

它与Oracle规范没有任何联系,为什么会这样呢?

我不确定它是否能像预期的那样工作,因为combine生成UNION,我需要参数连接。我已经尝试了几个小时了,我也会尝试这个方法。老实说,我以前没有使用Oracle。顺便说一句,你是以
$select->jo的身份尝试的吗在($subSelect,…)中
。因为它也可以将
选择
实例作为第一个参数。它可以在标准适配器中,Oracle适配器会覆盖它,所以它不能将
选择
作为参数。我不确定它是否能按预期工作,因为combine生成UNION,我需要使用参数连接。我已经尝试了几个小时不同的方法,我也会试试这个。老实说,我以前没有用过Oracle。顺便说一句,你是以
$select->join($subSelect,…)
的方式尝试的。因为它也可以将
select
实例作为第一个参数。在标准适配器中,Oracle适配器会覆盖它,所以它不能将
select
作为参数。