简体   繁体   English

Active Record查询中的Codeigniter括号

[英]Codeigniter parentheses in Active Record query

I have this ActiveRecord to produce a query, 我有这个ActiveRecord来生成一个查询,

$this->purchase_requisition_model
  ->where('deleted','1')
  ->likes('to',$sapfvalue,'both')
  ->likes('date',$sapfvalue,'both')
  ->likes('request_by',$sapfvalue,'both')
  ->likes('deliver_to',$sapfvalue,'both')
  ->likes('name',$sapfvalue,'both')
   ->likes('telephone',$sapfvalue,'both')
  ->likes('designation',$sapfvalue,'both')
  ->likes('budget_status',$sapfvalue,'both')
  ->find_all();

the above ActiveRecord will produce the following query, 上面的ActiveRecord将产生以下查询,

SELECT  * FROM (`purchase_requisition`)
WHERE `deleted` =  '1'
AND  `to`  LIKE '%fg%'
OR  `date`  LIKE '%fg%'
OR  `request_by`  LIKE '%fg%'
OR  `deliver_to`  LIKE '%fg%'
OR  `name`  LIKE '%fg%'
OR  `telephone`  LIKE '%fg%'
OR  `designation`  LIKE '%fg%'
OR  `budget_status`  LIKE '%fg%'

but how do I do using ActiveRecord to produce the below query? 但是如何使用ActiveRecord生成以下查询?

SELECT  * FROM (`purchase_requisition`)
WHERE `deleted` =  '1'
AND  (  `to`  LIKE '%fg%'
OR  `date`  LIKE '%fg%'
OR  `request_by`  LIKE '%fg%'
OR  `deliver_to`  LIKE '%fg%'
OR  `name`  LIKE '%fg%'
OR  `telephone`  LIKE '%fg%'
OR  `designation`  LIKE '%fg%'
OR  `budget_status`  LIKE '%fg%' )

As @M Khalid Junaid has pointed out, Codeigniter's active record library doesn't support grouped where clauses. 正如@M Khalid Junaid指出的那样,Codeigniter的活动记录库不支持分组where子句。 You can create a workaround by using "where" while preventing Codeigniter from automatically escaping the query: 您可以使用“where”创建变通方法,同时阻止Codeigniter自动转义查询:

$escaped_sapfvalue = $this->db->escape( $sapfvalue );
$this->purchase_requisition_model
->where('deleted','1')
->where("( `to` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `date` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `request_by` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `deliver_to` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `name` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `telephone` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `designation` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->where("OR `budget_status` LIKE '%{$escaped_sapfvalue}%' )", null, FALSE)
->find_all();

Notice than how I manually escaped the variable to prevent SQL injection. 请注意我是如何手动转义变量以防止SQL注入的。 Also notice how the first and last "LIKE" include the opening and closing parenthesis, respectively. 还要注意第一个和最后一个“LIKE”如何分别包括左括号和右括号。

While this works, it has a lot of repeated code. 虽然这有效,但它有很多重复的代码。 Looping through an array would be more elegant: 循环遍历数组会更优雅:

$escaped_sapfvalue = $this->db->escape( $sapfvalue );
$or_like = '';

foreach( $column_list as $column ) {
    // If it's not the first column, add 'OR'
    if ( strlen($or_like) > 0 ) {
        $or_like .= ' OR ';
    }
    // Concatenate manually escaped columns and rows
    $escaped_column = $this->db->escape( $column );
    $or_like .= "`{$escaped_column}` LIKE '%{$escaped_sapfvalue}%'";
}

// Add grouping parenthesis
$grouped_or_like = "( {$or_like} )";

// Build the query
$this->purchase_requisition_model
->where('deleted','1')
->where( $grouped_or_like, null, false )
->find_all();

EDIT: And while I haven't tested it, I've just thought this should work too: 编辑:虽然我没有测试过,但我认为这也应该有效:

$escaped_sapfvalue = $this->db->escape( $sapfvalue );
$this->purchase_requisition_model
->where('deleted','1')
->where("( `to` LIKE '%{$escaped_sapfvalue}%'", null, FALSE)
->or_like('date',$sapfvalue,'both')
->or_like('request_by',$sapfvalue,'both')
->or_like('deliver_to',$sapfvalue,'both')
->or_like('name',$sapfvalue,'both')
->or_like('telephone',$sapfvalue,'both')
->or_like('designation',$sapfvalue,'both')
->where("OR `budget_status` LIKE '%{$escaped_sapfvalue}%' )", null, FALSE)
->find_all();

Choose whatever works best for you. 选择最适合你的方法。

You can use query grouping too. 您也可以使用查询分组

Code will look like this: 代码如下所示:

$this->db->where('deleted', 1);
$this->db->group_start();
$this->db->or_like('to', $sapfvalue, 'both')
$this->db->or_like('date', $sapfvalue, 'both')
$this->db->or_like('request_by', $sapfvalue,  'both')
$this->db->or_like('deliver_to', $sapfvalue, 'both')
$this->db->or_like('name', $sapfvalue, 'both')
$this->db->or_like('telephone', $sapfvalue, 'both')
$this->db->or_like('designation', $sapfvalue, 'both')
$this->db->or_like('budget_status', $sapfvalue, 'both')
$this->db->group_end();

$q = $this->db->get('table')->result();

Using group_start and group_end assures that this part of or_like statements between then will get into brackets. 使用group_start和group_end确保之间的or_like语句的这一部分将进入括号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM