Скобки Codeigniter в динамическом запросе Active Record - PullRequest
18 голосов
/ 02 июля 2011

Я создаю запрос, подобный следующему, используя ActiveRecord

SELECT * FROM (`foods`) WHERE `type` = 'fruits' AND 
       `tags` LIKE '%green%' OR `tags` LIKE '%blue%' OR `tags` LIKE '%red%'

Число tags и значения неизвестны. Массивы создаются динамически. Ниже я добавил возможный массив.

$tags = array (                 
        '0'     => 'green'.
        '1'     => 'blue',
        '2'     => 'red'
);  

Имея массив тегов, я использую следующий цикл для создания запроса, который я разместил сверху.

$this->db->where('type', $type); //var type is retrieved from input value

foreach($tags as $tag):         
     $this->db->or_like('tags', $tag);
endforeach; 

Проблема: мне нужно добавить круглые скобки вокруг предложений LIKE, как показано ниже:

SELECT * FROM (`foods`) WHERE `type` = 'fruits' AND 
      (`tags` LIKE '%green%' OR `tags` LIKE '%blue%' OR `tags` LIKE '%red%')

Я знаю, как этого добиться, если содержимое в круглых скобках было статичным, но цикл foreach отбрасывает меня ..

Ответы [ 7 ]

35 голосов
/ 02 июля 2011

Из вики CI:

Функция кодового обозначения ActiveRecord позволяет создавать запросы SQL относительно просто и независимо от базы данных, однако есть нет конкретной поддержки для включения скобка в запросе SQL.

Например, когда вы хотите, чтобы оператор where выходил схожим образом со следующим:

WHERE (field1 = value || field2 = value) AND (field3 = value2 || field4 = value2) 

Эту проблему можно обойти, передав строку в функцию CI-> db-> where (), в этом случае вы захотите специально экранировать свои значения.

См. Следующий пример:

$value=$this->db->escape($value);
$value2=$this->db->escape($value2);
$this->db->from('sometable');
$this->db->where("($field = $value || $field2 = $value)");
$this->db->where("($field3 = $value2 || $field4 = $value2)");
$this->db->get(); 

Подобный обходной путь может быть использован для предложений LIKE:

$this->db->where("($field LIKE '%$value%' || $field2 LIKE '%$value%')");
$this->db->where("($field3 LIKE '%$value2%' || $field4 LIKE '%$value2%')"); 
17 голосов
/ 06 сентября 2014

В CI 3.0-dev вы можете добавлять группы в запрос:

$this->db->select('id, title')
->group_start()
->or_like([ 'title' => $s, 'id' => $s ])
->group_end()                
->where([ 'b_del' => 0 ]);

Производит:

SELECT `id`, `title`, `venda1`
FROM `itens`
WHERE   
(
`title` LIKE '%a%' ESCAPE '!'
OR  `id` LIKE '%a%' ESCAPE '!'
 )
AND `b_del` =0 
4 голосов
/ 07 мая 2017

Одна из лучших функций для сохранения запроса при применении нескольких предложений where или_where.

$this->db->group_start();
$this->db->where();
$this->db->or_where();
$this->db->group_end();

Счастливое кодирование. :)

0 голосов
/ 04 июня 2014
$likes = array (                 
    '0'     => 'green'.
    '1'     => 'blue',
    '2'     => 'red'
);  
$where_like = "("; 
$or_counter = 1;
foreach($likes as $like_key => $like_val):
    $or_content = ($or_counter > 1) ?'OR': '';
    $newlikeval = $this->db->escape_like_str($like_val);
    $where_like .= $or_content." `$like_key` LIKE  '%$newlikeval%' ";
    $or_counter++;
endforeach;
$where_like .= ")";
$this->db->where($where_like);
0 голосов
/ 11 сентября 2013

Просто добавляю мое успешное решение:

$this->db->where("(table.field = $variable OR table.field IS NULL)");
0 голосов
/ 04 июня 2013

Исходя из решения Silencer, я написал крошечную функцию, которая помогает создавать подобные условия

function make_like_conditions (array $fields, $query) {
    $likes = array();
    foreach ($fields as $field) {
        $likes[] = "$field LIKE '%$query%'";
    }
    return '('.implode(' || ', $likes).')';
}

Вы бы использовали это так:

$search_fields = array(
    'field_1',
    'field_2',
    'field_3',
);
$query = "banana"
$like_conditions = make_like_conditions($search_fields, $query);
$this->db->from('sometable')
    ->where('field_0', 'foo')
    ->where($like_conditions)
    ->get()
0 голосов
/ 02 июля 2011

Вы не можете добавить скобки в ActiveRecord, но, возможно, ГДЕ IN - это то, что вы ищете?

$names = array('Frank', 'Todd', 'James');
$this->db->where_in('username', $names);
// Produces: WHERE username IN ('Frank', 'Todd', 'James')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...