|
本帖最后由 CM帮主 于 2012-3-19 14:06 编辑
对于在使用AR过程中所遇到的一个瓶颈!
个人比较喜欢它使用CI,而在开发过程中经常会使用到里面的AR来生成查询!
但是最让我苦恼的是,在使用过程中,在生成部分语句的时候总是难以实现!
就比如:(注:这里字段前的表名是特意加上的,为了下面说明问题!)
SQL复制代码 SELECT * FROM USER WHERE (USER.name='CM帮主' AND USER.note='CM帮主描述') OR (USER.name='CMivan' AND USER.note='CMivan描述');
复制代码
因此我尝试了这样写:
$this->db->from('user');
$this->db->where('user.name','CM帮主');
$this->db->where('user.note','CM帮主描述');
$this->db->or_where('user.name','CMivan描述');
$this->db->where('user.note','CMivan描述');
结果返回的查询语句是这样的:
SQL复制代码
SELECT * FROM (`user`) WHERE `user`.`name` = 'CM帮主' AND `user`.`note` = 'CM帮主描述' OR `user`.`name` = 'CMivan' AND `user`.`note` = 'CMivan描述';
复制代码
唉!完全不是我要的东西!在接下来的一段时间,在网上没有找到生成我需要的这种写法!怎么办呢!?~?
好!突然想起AR的一个自带的一个写法,如下
$this->db->from("user");
$this->db->where("(user.name='CM帮主' and user.note='CM帮主描述') or (user.name='CMivan' and user.note='CMivan描述')");
结果返回的查询语句是这样的:
SQL复制代码
SELECT * FROM (`user`) WHERE (USER.name='CM帮主' AND USER.note='CM帮主描述') OR (USER.name='CMivan' AND USER.note='CMivan描述');
复制代码
来到这里,我是相当的开心啊!这正是我所需要的哈,没想到AR已经想到了会出现这种特殊情况,为我们自由发挥留下了一扇门啊!
这真的可以说是相当开心!,觉得这样AR有 $this->db->where('{sql}') 这种写法 就可以帮我解决很大一部分的查询难题了!
好!又过了一段时间,因为开发需要,我要对表加上前缀!
因此我修改了配置文件如下:
$db['default']['dbprefix'] = 'exp_';
新问题就来了,原来的语句查询的结果变成了这样:
SQL复制代码
SELECT * FROM (`exp_user`) WHERE (USER.name='CM帮主' AND USER.note='CM帮主描述') OR (USER.name='CMivan' AND USER.note='CMivan描述');
复制代码
来到这里,突然就汗了,相当苦闷啊!它竟然没对where里的语句进行解析!没有对表加上相应的前缀!!!!!!
网上有找到这个问题的解决方法!
那就是对where查询里的表,先使用 $this->db->dbprefix('user'); 返回!
$this->db->from("user");
$user = $this->db->dbprefix('user');
$this->db->where("(".$user.".name='CM帮主' and ".$user.".note='CM帮主描述') or (".$user.".name='CMivan' and ".$user.".note='CMivan描述')");
嗯!问题再次被解决了!
-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>-<>
虽然问题是解决了,但是在应用的时候总觉得不顺心!
总觉得这样写的话,很累赘!
一气之下!决定修改AR内核!
找到文件: /system/database/DB_active_rec.php ,在代码底部加上:
PHP复制代码 //用于支持带括号的检索条件
function where_on ($values = NULL)
{
return $this->_where_on ($values);
}
function or_where_on ($values = NULL)
{
return $this->_where_on ($values,'OR ');
}
function _where_on ($values = NULL, $type = 'AND ')
{
if ($values === NULL)
{
return;
}
if ( ! is_array($values))
{
$values = array($values);
}
$where_on = NULL;
foreach ($values as $value)
{
$this->ar_whereOR = NULL;
if (is_array($value))
{
$this->ar_whereOR = $this->_where_on_set ($value);
}
if (!empty($this->ar_whereOR))
{
if ( empty($where_on) )
{
$where_on = $this->ar_whereOR;
}
else
{
$where_on.= ' OR ' . $this->ar_whereOR;
}
}
}
if( !empty( $where_on ) )
{
$prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;
$where_on = $prefix . '(' . $where_on . ')';
$this->ar_where[] = $where_on;
if ($this->ar_caching === TRUE)
{
$this->ar_cache_where[] = $where_on;
$this->ar_cache_exists[] = 'where';
}
return $this;
}
}
function _where_on_set ($key, $value = '', $escape = TRUE)
{
$key = $this->_object_to_array ($key);
if ( ! is_array($key))
{
$key = array($key => $value);
}
$whereON = NULL;
$wherePRE = FALSE;
foreach ($key as $k => $v)
{
if (is_null($v) && ! $this->_has_operator ($k))
{
$k .= ' IS NULL';
}
if ( ! is_null($v))
{
if ($escape === TRUE)
{
$k = $this->_protect_identifiers ($k, FALSE, $escape);
$v = ' '.$this->escape($v);
}
if ( ! $this->_has_operator ($k))
{
$k .= ' =';
}
}
else
{
$k = $this->_protect_identifiers ($k, FALSE, $escape);
}
$thisor = $k . $v;
if ( !empty($thisor) )
{
if ( empty($whereON) )
{
$whereON = $thisor;
}
else
{
$whereON.= ' AND ' . $thisor;
$wherePRE = TRUE;
}
}
}
if ( $whereON != NULL)
{
if ( $wherePRE )
{
return '(' . $whereON . ')';
}
else
{
return $whereON;
}
}
}
复制代码
OK!可以开始使用这个来查询了!
$this->db->from('user');
$whereON[] = array('user.name'=>'CM帮主','user.note'=>'CM帮主描述');
$whereON[] = array('user.name'=>'CMivan','user.note'=>'CMivan描述');
$this->db->where_on($whereON);
结果终于是我所需要的了:
SQL复制代码
SELECT * FROM (`exp_user`) WHERE ((`exp_user`.`name` = 'CM帮主' AND `exp_user`.`note` = 'CM帮主描述') OR (`exp_user`.`name` = 'CMivan' AND `exp_user`.`note` = 'CMivan描述'));
复制代码
这里有:
$this->db->where_on() 、 $this->db->or_where_on() 和
$this->db->where() 、 $this->db->or_where()
的原理是一样的,都是为了和前面语句保持AND 或者 OR 的链接关系!就不哆嗦了!
最后! 我写这个出来主要是希望能给遇到相似情况的朋友一些帮助!同时希望大家给点意见,让这个
$this->db->where_on() 的写法可以进一步优化!
|
评分
-
查看全部评分
|