Подтвердить что ты не робот

Удалить одинарные кавычки из where_in в codeigniter

Я работаю над функциональностью search. Я создал форму поиска, в которой пользователь может искать приложение на основе Type, ope и Formate.

Я использовал подзапрос в моем запросе join, чтобы получить желаемый результат. Я тестировал свой запрос в MySQL Workbench и работал нормально.

Но когда я попробовал тот же запрос в Codeigniter, используя технику построения запросов, я столкнулся с проблемой.

Вот запрос, который отлично работает в workbench:

SELECT (*)
FROM `App`
LEFT JOIN `App_type` 
ON `App_type`.`app_id` = `App`.`id`
LEFT JOIN `App_formate` 
ON `App_formate`.`app_id` = `App`.`id`
WHERE `App`.`id` IN(select app_id FROM App_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3)
AND `App_formate`.`formate_id` IN('1', '3')
AND `jobs`.`ope_min` <= '3'
AND `jobs`.`ope_max` >= '3'
GROUP BY `jobs`.`id`;

Это запрос соединения, который я использую:

$subquery = "select app_id FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count";

$search_app_query = $this->db
    ->select('*')
    ->from('App')
    ->join('App_type', 'App_type.app_id = App.id', 'left outer')
    ->join('App_formate', 'App_formate.app_id = App.id', 'left outer')      
    ->where_in('App.id',$subquery)  //<-- Here is the problem
    ->where_in('App_formate.formate_id',$data['selected_formates'])
    ->where('App.ope_min <=',$data['ope_value'])
    ->where('App.ope_max >=',$data['ope_value'])    
    ->group_by("App.id", "desc")
    ->get();

Пока я отлаживаю эту проблему, он показывает

 I have found the problem is in this part of the query:
 "WHERE `App`.`id` IN('select app_id 
 FROM App_type 
 WHERE type_id in (3,2,6) 
 group by app_id HAVING COUNT(*) = 3')"

что одиночная кавычка в этом подзапросе создает проблему.

То, что я пробовал до сих пор:

Чтобы удалить эту одиночную кавычку, я пробовал

  • REPLACE($subquery, '''', '')
  • ->where_in('App.id',trim($subquery,"'"))
  • $subquery_improved = substr($subquery, 1, -1);

Но все это решение не работает. Они не удаляют одиночную кавычку.

Примечание. Я знаю $this->db->query(), но не хочу этого использовать.

4b9b3361

Ответ 1

Ваша задача выглядит довольно простой

вместо

->where_in('App.id',$subquery)  //<-- Here is the problem

вы можете попробовать следующее

->where("App.id IN (".$subquery.")",NULL, false)

Вы можете найти эту точную информацию в документации Codeigniter here (пункт 4 и раздел ниже).

Ответ 2

Мой подход будет чем-то вроде ниже, более общим образом. Я всегда стараюсь следовать шаблону MVC, нарушая функциональность в небольших функциях. Хотя вы не разделили весь свой код, я все равно предлагаю его.

Вы должны изменить мои пользовательские имена для функций, массивов и т.д., чтобы он соответствовал вашему коду. Надеюсь, что это поможет.

Функция модели

public function getApp_ids($selected_type, $type_count) {
   $subquery = "select app_id FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count";
   $result = $subquery->get();
   if($result->num_rows() > 0) //the check here is relevant to your data
       return $result->result_array();
   return false;
}

Функция модели

public function searchApp($appIds, $data) {
  //$appIds and $data are parameters to this function. 
    $search_app_query = $this->db
       ->select('*')
       ->from('App')
       ->join('App_type', 'App_type.app_id = App.id', 'left outer')
       ->join('App_formate', 'App_formate.app_id = App.id', 'left outer')      
       ->where_in('App.id',$appIds)  //pass the array of your IDs
       ->where_in('App_formate.formate_id',$data['selected_formates'])
       ->where('App.ope_min <=',$data['ope_value'])
       ->where('App.ope_max >=',$data['ope_value'])    
       ->group_by("App.id", "desc")
       ->get();

    if($search_app_query->num_rows() > 0) //again, the check is yours
         return $search_app_query->result_array();
    return false;
}

В вашем контроллере что-то вроде этого

public function YOUR_FUNCTION($selected_type, $type_count) {
   //call this function from model to grab the app_id you want. Don't forget to pass the parameters you sql needs.
   $appIdsResult = $this->YOUR_MODEL->getApp_ids($selected_type, $type_count);

   //Manipulate your result in another array, so you can get rid off the indexes and do some checks if you want
   $appIds = array();
   foreach ($appIdsResult as $appId) {
       array_push($appIds, $appId['app_id']); //Check the index app_id, it is the result from your DB.
    }

    //Call searchApp from your model and pass the found $appIds and your $data ofcourse
    $result = $this->YOUR_MODEL->searchApp($appIds, $data);
    //In $result will be your answer
}

Ответ 3

замените этот код:

->where_in('App.id',$subquery)  //<-- Here is the problem

с помощью этого кода:

->where_in("App.id", $subquery, FALSE)

3-й параметр принимает Boolean, чтобы определить, должна ли функция избегать значения и идентификатора или нет. Если установлено значение FALSE, он не использует одиночную кавычку как escape char.

Надеюсь, что это поможет.

Ответ 4

ИСПОЛЬЗУЙТЕ РУКОВОДСТВО QUERY (небезопасно, используйте очень очень хорошо)

$sql = "SELECT ....[Your Query].....":
$query = $this->db->query($sql);
if ($query->num_rows() > 0){
    // Found
}else{
    // Not Found
}

Ответ 5

//сначала подтвердить, что подзапрос возвращает только один результат, если не изменить подзапрос

$subquery = "select GROUP_CONCAT(CONCAT(\"'\",app_id,\"'\")) FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count";

$search_app_query = $this->db
->select('*')
->from('App')
->join('App_type', 'App_type.app_id = App.id', 'left outer')
->join('App_formate', 'App_formate.app_id = App.id', 'left outer')      
->where_in('App.id',$subquery,false)  //<-- pass 3rd parameter as false for removing single quotes
->where_in('App_formate.formate_id',$data['selected_formates'])
->where('App.ope_min <=',$data['ope_value'])
->where('App.ope_max >=',$data['ope_value'])    
->group_by("App.id", "desc")
->get();

Ответ 6

Я думаю, что ваш $subquery рассматривался как строка параметров, а не как запрос.
Общий синтаксис метода активной записи

->where_in('field_name', array() || 'string values');

Вы $subquery должны быть такими

$subquery = $this->db
        ->select('app_id')
        ->from('App_type')
        ->where_in('type_id',array(3,2,6))
        ->group_by('app_id')
        ->having(' COUNT(*) = 3')
        ->get()
        ->row()
        ->app_id;

Надеюсь, что это сработает:)

Ответ 7

Вместо

SELECT (*)

использование

SELECT *

Вместо

WHERE `App`.`id` IN(
    select app_id FROM App_type
        WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3)

использование

JOIN (
    select app_id FROM App_type
        WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3
     ) AS x  ON x.app_id = App.id

(Перевод в CodeIgniter оставлен как упражнение для читателя.)

Ответ 8

Прежде всего после запроса, поместите этот код:

echo $this- > db- > last_query(); exit;

Это напечатает запрос, и у вас будет идея, где проблема. Также скопируйте этот запрос и попробуйте запустить его в phpmyadmin.

Также попробуйте этот тип решения, поскольку у вас есть проблемы с одной цитатой:

В подзапросе введите $type_count, используя одинарные кавычки i.e '$ type_count'

->where("App.ope_min <='",$data['ope_value']."'")
->where("App.ope_max >='",$data['ope_value']."'")    
->group_by("App.id", "desc")
->get();

Сообщите мне, если вы хотите спросить что-то еще.

Ответ 9

Просто добавьте третий параметр в оператор where_in. Попробуйте это -

$subquery = "select app_id FROM app_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3";
    $search_app_query = $this->db
    ->select('*')
    ->from('app')
    ->join('app_type', 'app_type.app_id = app.id', 'left outer')
    ->join('app_formate', 'app_formate.app_id = app.id', 'left outer')      
    ->where_in('app.id',$subquery, FALSE)  
    ->where_in('app_formate.formate_id',array(1,3))
    ->where('app.ope_min <=',3)
    ->where('app.ope_max >=',3)    
    ->group_by("app.id", "desc")
    ->get()->result();

Ответ 10

Я бы посоветовал вам не ставить sub-запрос прямо в том месте, где вы находитесь, потому что иногда вы также можете иметь нулевой результат. Таким образом, лучший способ - выполнить свой подзапрос отдельно, как это.

$subdata = $this->db->select("app_id ")->from("App_type ")->where_in("type_id",$selected_type)->group_by(""app_id)->having("COUNT(*) = $type_count")->get()->result_array();

$search_app_query = $this->db
    ->select('*')
    ->from('App')
    ->join('App_type', 'App_type.app_id = App.id', 'left outer')
    ->join('App_formate', 'App_formate.app_id = App.id', 'left outer');
if(!empty($subdata)) {     
    $this->db->where_in('App.id',$subdata);
}
    $this->db->where_in('App_formate.formate_id',$data['selected_formates'])
    ->where('App.ope_min <=',$data['ope_value'])
    ->where('App.ope_max >=',$data['ope_value'])    
    ->group_by("App.id", "desc")
    ->get(); 

Ответ 11

Спасибо всем вам за ваши предложения.

У меня есть способ решить мою проблему без изменения моего другого кода.

Благодаря пользователю sintakonte-SO его комментарий был ключом к решению этой проблемы.

Решение - это просто изменение одного кода строки, который я раньше хотел.

$search_app_query = $this->db
    ->select('*')
    ->from('App')
    ->join('App_type', 'App_type.app_id = App.id', 'left outer')
    ->join('App_formate', 'App_formate.app_id = App.id', 'left outer') 

    // This is what he suggested me to change and it works. 
    ->where('App.id IN('.$subquery.')')     

    ->where_in('App_formate.formate_id',$data['selected_formates'])
    ->where('App.ope_min <=',$data['ope_value'])
    ->where('App.ope_max >=',$data['ope_value'])    
    ->group_by("App.id", "desc")
    ->get();

Позднее спасибо пользователю sintakonte-SO.