Day: June 14, 2007

  • Zend_Db_Adapter_Pdo_Oci关于字符集设置的解决方法

    默认没有提供在 Zend_Db_Adapter_Pdo 中设置 charset 的方法,使用下面的补丁可以解决这个问题:

    Index: Oci.php
    ==========================================
    — Oci.php (revision 267)
    +++ Oci.php (working copy)
    @@ -67,7 +67,12 @@
    $tns .= ‘/’;
    }
    $tns .= $dsn[‘dbname’];

    +
    + if (isset($dsn[‘charset’]))
    + {
    + $tns .= ‘;charset=’ . $dsn[‘charset’];
    + }
    +
    return $this->_pdoType . ‘:’ . $tns;
    }

    这样 Zend_Db::factory 方法将支持这样的设置:

    <?php

    require_once ‘Zend/Db.php’;

    $db = Zend_Db::factory(‘Pdo_Oci’, array(
    ‘host’ => ‘127.0.0.1’,
    ‘username’ => ‘webuser’,

    ‘password’ => ‘xxxxxxxx’,
    ‘dbname’ => ‘test’,
    ‘charset’ => ‘utf8’
    ));

    这个问题我已经提交到了 Zend Framework 的 Issue 中。

    http://framework.zend.com/issues/browse/ZF-1541?page=all

  • 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.