Zend_Db_Select 在 join 系列方法上的注意

大概很多人都跟我一样,在没有遇到问题的时候不去仔细阅读手册,问题如下:

当对一个使用 join 方法的 select 使用 COUNT(*) 统计时,join 总是默认添加字段在 FROM 前。

代码如下:

$select->from($this->addStatement(‘CBBS_USER’), new Zend_Db_Expr(‘COUNT(*)’))
->join($this->addStatement(‘CBBS_POWER’), ‘CBBS_USER.USER_ID = CBBS_POWER.USER_ID’)
->join($this->addStatement(‘CBBS_ROLE’), ‘CBBS_POWER.ROLE_ID = CBBS_ROLE.ROLE_ID’)
->where(‘CBBS_USER.DEL_FLAG = 0’);

这个产生的 SQL 语句:

SELECT COUNT(*), “CBBS_POWER”.*, “CBBS_ROLE”.* FROM “ACEMACHINE”.”CBBS_USER” INNER JOIN “ACEMACHINE”.”CBBS_POWER” ON CBBS_USER.USER_ID = CBBS_POWER.USER_ID INNER JOIN “ACEMACHINE”.”CBBS_ROLE” ON CBBS_POWER.ROLE_ID = CBBS_ROLE.ROLE_ID WHERE (CBBS_USER.DEL_FLAG = 0)

实际上只需要:

$select->from($this->addStatement(‘CBBS_USER’), new Zend_Db_Expr(‘COUNT(*)’))
->join($this->addStatement(‘CBBS_POWER’), ‘CBBS_USER.USER_ID = CBBS_POWER.USER_ID’, array())
->join($this->addStatement(‘CBBS_ROLE’), ‘CBBS_POWER.ROLE_ID = CBBS_ROLE.ROLE_ID’, array())
->where(‘CBBS_USER.DEL_FLAG = 0’);

就可以产生正确的 SQL 语句:

SELECT COUNT(*) FROM “ACEMACHINE”.”CBBS_USER” INNER JOIN “ACEMACHINE”.”CBBS_POWER” ON CBBS_USER.USER_ID = CBBS_POWER.USER_ID INNER JOIN “ACEMACHINE”.”CBBS_ROLE” ON CBBS_POWER.ROLE_ID = CBBS_ROLE.ROLE_ID WHERE (CBBS_USER.DEL_FLAG = 0)

其实 Zend Framework 手册上清楚的写着:

If you give an empty array as the columns argument, no columns from the respective table are included in the result set. See a code example under the section on the join() method.

Zend_Db_Adapter_Pdo_Oci 的 Bug

这个 Bug 在 Zend Framework 的 RC1、RC2 中都存在。2007-06-13日的SVN已经更新了这个Bug。ZF 对 Oracle 的支持又上升到一个层次。

我的 patch文件

Index: Oci.php
===============================
— Oci.php (revision 5221)
+++ Oci.php (working copy)
@@ -261,7 +261,7 @@
if ($primaryKey) {
$sequenceName .= “_$primaryKey”;
}
– $sequenceName .= ‘_seq’;
+ $sequenceName .= ‘_SEQ’;
return $this->lastSequenceId($sequenceName);
}
return $this->_connection->lastInsertId($tableName);

As Golang beyond PHP