我正在寻找一种在 CodeIgniter 中使用 Active Record 来构建查询的方法。
我当前的代码是这样的:
$this->db-> like('responsible', $user->id);
$this->db->or_like('accountable', $user->id);
$this->db->or_like('consulted', $user->id);
$this->db->or_like('informed', $user->id);
// Get the tasks, but only with the correct start or end date
$tasks = $this->db->get_where('level_' . $this->config->item('answer_level'), array('date_end' => $offset, 'ccode' => $user->country));
// Check if tasks exist
if($tasks->num_rows() > 0){
// Tasks have been found that should have been finished!
echo $tasks->num_rows() . " tasks found for " . $user->first_name . " that should have been finished!\n";
$last_month_tasks = $tasks->result();
}
unset($tasks);
生成以下 SQL:
SELECT *
FROM (`level_3`)
WHERE `date_start` = -5
AND `ccode` = 'GB'
AND `responsible` LIKE '%5%'
OR `accountable` LIKE '%5%'
OR `consulted` LIKE '%5%'
OR `informed` LIKE '%5%'
但是我需要它来生成这个 SQL:
SELECT *
FROM (`level_3`)
WHERE `date_start` = -5
AND `ccode` = 'GB'
AND (
`responsible` LIKE '%5%'
OR `accountable` LIKE '%5%'
OR `consulted` LIKE '%5%'
OR `informed` LIKE '%5%'
)
CodeIgniter 的 ActiveRecord 不支持查询和子句的嵌套。 你必须像这样手动完成:
$this->db->select('*');
$this->db->from('level_' . $this->config->item('answer_level'));
$this->db->where(array('date_end' => $offset, 'ccode' => $user->country));
$this->db->where("(responsible LIKE '%5%' OR accountable LIKE '%5%' OR consulted LIKE '%5%' OR informed LIKE '%5%')");
$tasks = $this->db->get();
CodeIgniter 绝对支持查询和子句的嵌套。 在这种情况下,解决方案是使用
group_start()
和 group_end()
将 LIKE 条件集封装在括号中。
我确实想警告,如果用户 ID 是整数,则很少适合使用 LIKE 条件,因为这会使查询容易受到较大用户 ID 的过度匹配子字符串的影响。换句话说,
12
将匹配12
、112
、121
、122
、123
等。您的编码意图给了我代码气味问题。
or_like()
能够接收关联数组,其中键是要搜索的列,值是要搜索的值。
select('*')
不需要显式写出,省略则隐含。
from()
子句和where()
条件可以合并到get_where()
调用中,这是对get()
的扩展,这是实际执行查询所必需的。
模型方法不应该做任何回显——它们最多应该返回数据。 计算结果和验证数据可以在另一层完成。 只需将有效负载返回给调用方法即可。
return $this->db
->group_start()
->or_like([
'responsible' => $user->id,
'accountable' => $user->id,
'consulted' => $user->id,
'informed' => $user->id,
])
->group_end()
->get_where(
'level_' . $this->config->item('answer_level'),
[
'date_end' => $offset,
'ccode' => $user->country,
]
)
->result();