SQL转CodeIgniter Active Record结果不符,求修正及替代方案
将SQL查询转换为CodeIgniter Active Record的正确方式
嘿,我知道你为啥查询结果不符合预期了!问题出在查询条件的逻辑优先级上!
你写的原生SQL里,特意用括号把user1 = 144 OR user2 = 144包裹起来,确保这部分条件作为一个整体,和后面的status = 2、action != 1做AND运算。但你当前的Active Record写法会生成这样的SQL:
SELECT * FROM `relation` WHERE `user1` = 144 OR `user2` = 144 AND `status` = 2 AND `action` != 1
由于SQL中AND的优先级比OR高,这个语句实际的逻辑是:user1=144 或者 (user2=144且status=2且action!=1),和你想要的逻辑完全不符,所以结果自然不对。
正确的CodeIgniter Active Record实现
你需要用CodeIgniter的分组WHERE条件(通过闭包实现)来模拟原生SQL里的括号逻辑,代码如下:
$ID = 144; $this->db->where(function($query) use ($ID) { $query->where('user1', $ID); $query->or_where('user2', $ID); }); $this->db->where('status', 2); $this->db->where('action !=', 1); // 获取查询结果 $result = $this->db->get('relation')->result();
这段代码会生成和你原生SQL完全一致的查询语句,确保user1和user2的条件先作为一个整体判断,再和其他条件做AND运算,逻辑就对了。
非Active Record的实现方案
如果觉得分组WHERE的写法有点绕,也可以直接执行原生SQL,这样更直观,还能避免逻辑优先级的坑:
$ID = 144; $sql = "SELECT * FROM `relation` WHERE (`user1` = ? OR `user2` = ?) AND `status` = 2 AND `action` != 1"; $result = $this->db->query($sql, array($ID, $ID))->result();
这里用占位符?绑定参数,和Active Record一样能有效避免SQL注入,安全又省心。
内容的提问来源于stack exchange,提问作者drcyber
相关产品推荐
相关产品推荐

