简体   繁体   English

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

[英]Query returns different results between PL/SQL Developer and PHP

I have made a small intranet website to collect and store data to be used to expedite our logistics processes. 我已经建立了一个小型的Intranet网站,以收集和存储用于加快物流流程的数据。 I'm now in the process of adding search functionality which, if records are found that match that criteria, will allow the user to quickly select parts of that data to pre-populate a new shipping request with data (eg, the user types 'Mar' in the Recipient Name input textbox and '109' in the Street Address input textbox and the query returns two records: {"Mary Smith", "1090 South Central St"} and {"Mark Swanson", "109 E. 31st St."}). 我现在正在添加搜索功能,如果找到了符合该条件的记录,该功能将允许用户快速选择该数据的一部分,以使用数据预填充新的运送请求(例如,用户键入“ “收件人姓名”输入文本框中的“ Mar”和“街道地址”输入文本框中的“ 109”,查询返回两个记录:{“ Mary Smith”,“ 1090 South Central St”}和{“ Mark Swanson”,“ 109 E. 31st”圣”})。

At the moment, when search criteria is entered and submitted, the data returned from the query in PHP is 100% accurate if and only if a single criteria is entered (such as Recipient Name). 目前,输入并提交搜索条件后,如果且仅当输入单个条件(例如收件人名称)时,PHP查询中返回的数据才100%准确。 When I attempt to use two different search criterias in PHP, the record results do not match the results when running the same query in Oracle PL/SQL Developer. 当我尝试在PHP中使用两个不同的搜索条件时,在Oracle PL / SQL Developer中运行相同查询时,记录结果与结果不匹配。 If three different search criterias are used, the query ran in PHP will return 0 records. 如果使用三种不同的搜索条件,则在PHP中运行的查询将返回0条记录。 In all three of the aforementioned scenarios, the query is executed without error in Oracle PL/SQL Developer. 在上述所有三种情况下,在Oracle PL / SQL Developer中执行查询都不会出错。

The following code is from my PHP search function. 以下代码来自我的PHP搜索功能。 The input data to this function is an associate array of field names and the user inputted search criteria data for that field. 该功能的输入数据是字段名称和用户输入的该字段的搜索条件数据的关联数组。

     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!");
        }
    }
}

I've done a var_dump on $query to see what my query actually looks like when I enter multiple search criteria values. 我在$ query上完成了var_dump,以查看输入多个搜索条件值时查询的实际外观。 This is an example of what I see: 这是我所看到的一个示例:

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)

That query returns 0 records when I enter "a" for Shipper Name, "m" for Recipient Name, and "2" for Phone Number. 当我为托运人名称输入“ a”,为收件人名称输入“ m”以及为电话号码输入“ 2”时,该查询返回0条记录。

This query, when executed in Oracle PL/SQL Developer, however, returns 27 records. 但是,该查询在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%')

Is there something wrong with the way that I'm trying to bind the parameters in PHP? 我尝试在PHP中绑定参数的方式有问题吗? Is there something different I have to do when using multiple like statements? 使用多个like语句时,我必须做些其他事情吗?

You've forgotten the % wildcard chars in your built query string. 您忘记了内置查询字符串中的%通配符。 The DB interface libraries do NOT parse the query you're building, and do NOT look for LIKE clauses - it's not their job to guess what kind of match you're trying to do. DB接口库不会解析正在构建的查询,也不会查找LIKE子句-猜测您要进行哪种匹配并不是他们的工作。 eg are you doing 例如你在做什么

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

It's up to you to provide the appropriate wildcards, and since you're using placeholders, you'll have to do it yourself, eg 您需要提供适当的通配符,并且由于使用的是占位符,因此必须自己完成操作,例如

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

If you were to do it something like this: 如果要执行以下操作:

$shipper = '%foo%';

WHERE  ... LIKE :shipper

you'd end up with the equivalent of: 您最终将得到以下结果:

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

The placeholder system also doesn't parse your provided text and try to figure out if you're really trying to use a wilcard or just passing in a literal % char. 占位符系统也不会解析您提供的文本,而是试图弄清楚您是真的要使用通配符还是仅传入文字% char。 That's why you have to use the CONCAT hack to build a proper wildcarded construct. 这就是为什么您必须使用CONCAT hack构建适当的通配符构造的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM