2013-08-19 89 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')时,查询结果是正确的,但我真的很想使用通配符(除非有更好的方式可以建议)。 –