簡體   English   中英

從codeigniter中的where_in中刪除單引號

[英]Remove single quotes from where_in in codeigniter

我正在研究search功能。 我創建了一個搜索表單,用戶可以在其中搜索基於TypeopeFormate的應用程序。

我在連接查詢中使用了查詢來獲得所需的結果。 我已在MySQL Workbench測試了我的查詢,但它工作正常。

但是當我使用查詢構建器技術在Codeigniter中嘗試相同的查詢時,我遇到了一個問題。

這是在工作台中工作正常的查詢:

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')"

此子查詢中的單引號正在創建問題。

到目前為止我嘗試了什么:

要刪除這個單引號,我試過了

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

但所有這些解決方案都無效。 他們沒有刪除單引號。

注意:我知道$this->db->query()但不想使用它。

你的任務看起來很簡單

代替

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

你可以試試以下

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

您可以在此處的Codeigniter文檔中找到這些確切的信息(第4點和下面的部分)。

我的方法將在下面以更通用的方式進行。 我總是試圖遵循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
}

替換此代碼:

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

使用此代碼:

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

第3個參數接受布爾值,以確定函數是否應該轉義值和標識符。 設置為FALSE時,它不使用單引號作為轉義字符。

希望這可以幫助。

使用手冊查詢(不安全,非常非常使用)

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

//如果子查詢中沒有更改,則首先確認子查詢只返回一個結果

$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();

我認為您的$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;

希望它會工作:)

代替

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留給讀者練習。)

首先在查詢之后,把這段代碼:

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

這將打印查詢,您將知道問題在哪里。 同時復制該查詢並嘗試在phpmyadmin中運行它。

也可以嘗試這種類型的解決方案,因為您有單引號問題:

在子查詢中使用單引號寫入$ type_count,即'$ type_count'

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

如果你想問別的話,請告訴我。

只需在where_in語句中添加第3個參數即可。 試試這個 -

$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();

我建議你不要將子查詢直接放在條件的位置,因為你有時也可能沒有結果。 所以最好的方法是像這樣單獨執行子查詢。

$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(); 

感謝大家的建議。

我找到了解決問題的方法而不改變我的其他代碼。

感謝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用戶

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM