查询在PL / SQL Developer和PHP之间返回不同的结果

时间:2013-08-19 19:02:22

标签: php oracle plsql

我已经建立了一个小型内联网网站来收集和存储数据,以加快我们的物流流程。我现在正在添加搜索功能,如果发现符合该条件的记录,将允许用户快速选择该数据的一部分以预先填充带有数据的新运送请求(例如,用户输入' Mar'在收件人姓名输入文本框中,'109'在街道地址输入文本框中,查询返回两条记录:{“Mary Smith”,“1090 South Central St”}和{“Mark Swanson”,“109 E. 31st圣。“})。

目前,当输入并提交搜索条件时,当且仅当输入单个条件(例如收件人名称)时,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!");
        }
    }
}

我在$ query上做了一个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)

当我为托运人名称输入“a”时,该查询返回0条记录,“收件人名称”输入“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语句时,我有什么不同吗?

1 个答案:

答案 0 :(得分: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\%'

占位符系统也不会解析您提供的文本,并试图弄清楚您是否真的尝试使用wilcard或只是传入文字%字符。这就是为什么你必须使用CONCAT hack来构建一个合适的通配符构造。