3.1.3 ORACLE 11g WHERE条件失效

浏览:1771 发布日期:2013/11/08
3.1.3 - 致命 - 未处理
如                $subSystemId = '0001';
                $userModulePrivilligesModel = M ( "VFrwkYonghmkqx" );
                $userModulePrivilliges =
                    $userModulePrivilligesModel
                    ->where(array('YHID' => '0002','ZXTID'=>$subSystemId))
                    ->field( "zxtid,zxtmc,mkzid,mkzmc,mkid,mkmc,mkbsurl,mkcsurl" )
                    ->order ( 'mkzxh, mkxh asc' )
                    ->select ();
生成的SQL为:SELECT * FROM (SELECT thinkphp.*, rownum AS numrow FROM (SELECT   zxtid,zxtmc,mkzid,mkzmc,mkid,mkmc,mkbsurl,mkcsurl FROM v_frwk_yonghmkqx ORDER BY mkzxh, mkxh asc) thinkphp ) 即where(array('YHID' => '0002','ZXTID'=>$subSystemId))条件失效。

解决办法如下:
1、我用的是Oracle数据库,11g
2、在DBOracle.class.php中,有函数getFields,需要将取值时所使用的键名改为大写,如下:        /**
         * 取得数据表的字段信息
         * access public
         */
         public function getFields($tableName) {
            $result = $this->query("select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk "
                      ."from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col "
              ."where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='".strtoupper($tableName)
              ."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)");
            $info   =   array();
            if($result) {
                foreach ($result as $key => $val) {
                    // 将取值时所使用的键名改为大写形式
                    $info[strtolower($val['COLUMN_NAME'])] = array(
                        'name'    => strtolower($val['COLUMN_NAME']),
                        'type'    => strtolower($val['DATA_TYPE']),
                        'notnull' => $val['NOTNULL'],
                        'default' => $val['DATA_DEFAULT'],
                        'primary' => $val['PK'],
                        'autoinc' => $val['PK'],
                    );
                }
            }
            return $info;
        }
3、在上面的方法中,将$info中的键名转换为小写了,也就是说返回值$info中包含的所有字段信息的键名(也就是字段名)都是小写形式的。
4、在Model.class.php中,有方法_parseOptions,在此方法中,对于where条件有验证如下(注意TODO部分):            if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) {
                // 对数组查询条件进行字段类型检查
                foreach ($options['where'] as $key=>$val){
                    $key            =   trim($key);
                    // TODO 若where中体现的字段名与$fields中所包含的字段
                    // TODO 相符(大小写也要一致),则解析where条件;
                    // TODO 否则这个where条件极有可能被去除。
                    if(in_array($key,$fields,true)){
                        if(is_scalar($val)) {
                            $this->_parseType($options['where'],$key);
                        }
                    }elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){
                        unset($options['where'][$key]);
                    }
                }
            }
5、解决办法:
5.1 按照第2步修改框架代码
5.2 从结果集中取值时必须使用字段名的大写形式
5.3 所有where条件所体现的字段必须是小写形式。
6、例子(我问题的例子的解决办法):
6.1 按照第2步修改框架代码
6.2 在我的例子中并未涉及到取值,但第2步修改体现的就是取值问题
6.3        $subSystemId = '0001';
                    $userModulePrivilligesModel = M ( "VFrwkYonghmkqx" );
                    $userModulePrivilliges =
                        $userModulePrivilligesModel
                        // 注意这里修改为小写的了。
                        ->where(array('yhid' => '0002','zxtid'=>$subSystemId))
                        ->field( "zxtid,zxtmc,mkzid,mkzmc,mkid,mkmc,mkbsurl,mkcsurl" )
                        ->order ( 'mkzxh, mkxh asc' )
                        ->select ();
评论()
后面还有条评论,点击查看>>