2013-08-19 124 views
0

我已經制作了一個小型Intranet網站來收集和存儲用於加快我們物流流程的數據。我現在正在添加搜索功能,如果發現符合該條件的記錄,將允許用戶快速選擇該數據的某些部分以預先填充具有數據的新的送貨請求(例如,用戶類型' Mar'在收件人姓名輸入文本框中,'109'在街道地址輸入文本框中,並且查詢返回兩條記錄:{「Mary Smith」,「1090 South Central St」}和{「Mark Swanson」,「109 E. 31st聖「})。查詢返回PL/SQL Developer和PHP之間的不同結果

目前,當輸入和提交搜索條件時,當且僅當輸入單個條件時(例如收件人姓名),從PHP查詢返回的數據是100%準確的。當我嘗試在PHP中使用兩種不同的搜索標準時,記錄結果與在Oracle PL/SQL Developer中運行相同查詢時的結果不匹配。如果使用三種不同的搜索標準,則在PHP中運行的查詢將返回0個記錄。在上述三種情況下,查詢在Oracle PL/SQL Developer中都沒有錯誤地執行。

以下代碼來自我的PHP搜索功能。該函數的輸入數據是字段名稱的關聯數組,並且用戶輸入了該字段的搜索條件數據。

 public function Search() 
    { 
     if($this->dbcon) 
     { 
      $query = "SELECT * FROM ship_request "; 
      $postCount = count($this->post_data); 
      $counter = 0; 

      if ($postCount > 0) 
      { 
       $query .= "WHERE "; 
      } 

      foreach ($this->post_data as $k => $v) 
      { 
       $counter++; 
       if (strlen($v) > 0) 
       { 
        if ($k == 'SR_DATE') 
        { 
         $query .= $k . " = :" . $k . " AND "; 
        } else { 
         $query .= "upper(" . $k . ") like upper(:" . $k . ") AND "; 
        } 
       } 
      } 

      if (substr($query,-4) == "AND ") 
      { 
       $query = substr($query, 0, strlen($query) - 4); 
      } 

      $stid = oci_parse($this->ifsdb, $query); 

      foreach ($this->post_data as $k => $v) 
      { 
       if (strlen($v) > 0) 
       { 
        if ($k == 'SR_DATE') 
        { 
         $this->post_data[$k] = date("d-M-y", strtotime($this->post_data[$k])); 
         $placeHolder = $this->post_data[$k]; 
        } else { 
         $placeHolder = '%' . $this->post_data[$k] . '%'; 

        } 
        oci_bind_by_name($stid, $k, $placeHolder); 
       } 
      } 
      oci_execute($stid); 
      $nrows = oci_fetch_all($stid, $recordsFound); 
      $recordsFound = json_encode($recordsFound); 
      oci_free_statement($stid); 
      echo $recordsFound; 
     } else { 
      die("Could not connect to database!"); 
     } 
    } 
} 

我已經做了$查詢的var_dump看看我的查詢實際上看起來當我輸入多個搜索標準值等。這是我所看到的一個例子:

select * from HOL_SHIP_REQUEST where upper(sr_shipper_name) like upper(:sr_shipper_name) and upper(sr_recipient_name) like upper(:sr_recipient_name) and sr_recipient_phone like upper(:sr_recipient_phone)

該查詢返回0的記錄,當我輸入「A」爲發貨人姓名,「M」爲收件人姓名,而「2」的電話號碼。

但是,此查詢在Oracle PL/SQL Developer中執行時會返回27條記錄。

select * from HOL_SHIP_REQUEST where upper(sr_shipper_name) like upper('%a%') and upper(sr_recipient_name) like upper('%m%') and sr_recipient_phone like upper('%2%')

有什麼不妥,我試圖綁定在PHP中參數的方式嗎?當使用多個like語句時,我有什麼不同嗎?

回答

3

您已經忘記了內置查詢字符串中的%通配符字符。數據庫接口庫不會分析您正在構建的查詢,也不會查找LIKE子句 - 這不是他們的工作來猜測您想要做什麼樣的匹配。例如你在幹什麼

WHERE a LIKE 'b' 
WHERE a LIKE 'b%' 
WHERE a LIKE '%b' 
WHERE a LIKE '%b%' 

這是給你提供相應的通配符,因爲你正在使用的佔位符,你必須自己做,例如

WHERE UPPER(sr_shipper_name) LIKE CONCAT('%', :sr_shipper_name, '%') 

如果你做這樣的事情:

$shipper = '%foo%'; 

WHERE ... LIKE :shipper 

你最終用等價的:

WHERE ... LIKE '\%foo\%' 

佔位符系統也不會解析您的提供的文本,並試圖找出如果你真的想要使用一個威爾卡或只是傳入一個文字%字符。這就是爲什麼你必須使用CONCAT黑客構建適當的通配構造。

+0

感謝您的意見。你是對的 - 我忘記了通配符。然而,當我試圖通過在參數之間使用'CONCAT'和'||'來解決這個函數時,我仍然有相同的結果。當使用一個搜索條件/ LIKE語句時,PHP中返回的準確結果,在PHP中使用兩個搜索條件/ LIKE語句時與搜索條件不匹配的記錄,以及使用三個或更多搜索條件/ LIKE語句時返回的零條記錄。 –

+0

你正在使用'AND'來處理你喜歡的各種子句,所以如果它們全部綁定在一起,那麼你將得到所有子句匹配的唯一記錄。你可能需要'OR',即使有一個字段匹配,你也會得到結果。 –

+0

你對「OR」部分是正確的 - 以這種方式進行搜索確實更有意義。不過,在比較PHP和Oracle PL/SQL Developer之間的查詢時,我仍然沒有得到正確的結果。有趣的是,當我使用直接比較(例如'SR_RECIPIENT_COMPANY =:sr_recipient_company')時,查詢結果是正確的,但我真的很想使用通配符(除非有更好的方式可以建議)。 –