Php zend framework 2使用oracle适配器连接子选择
我在互联网上搜索过,大部分答案适用于ZF1。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
我想使用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中使用classZend_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
作为参数。