查询返回意外结果


query returns unexpected results

我觉得这个搜索查询并没有像我想象的那样工作。我想确定的是,只选择ksisoldby$user相同(尽管不区分大小写,因此ILIKE)的项目。用ANDs和ORs指定的其他字段是缩小此选择范围的可能方式。

"SELECT 
id,
status,
customer_id,
shipping_address_id,
order_number,
reference,
ship_via_id,
order_date :: date,
due_date :: date,
created,
sales_tax,
freight,
taxable,
nontaxable,
job_name,
order_description,
ship_to_name,
ship_to_address1,
ship_to_address2,
ship_to_city,
ship_to_state,
ship_to_zipcode,
name,
address1,
address2,
city,
state,
zipcode,
act_ship_date,
ksisoldby
FROM sales_orders 
WHERE ksisoldby ILIKE '".$user."'
AND (order_description ilike 
'%".implode("%' AND order_description like '%", $search)."%')
OR (order_number ilike 
'%".implode("%' AND order_number like '%", $search)."%')
OR (name ilike 
'%".implode("%' AND name like '%", $search)."%')
OR (reference ilike 
'%".implode("%' AND name like '%", $search)."%')
ORDER BY order_number DESC";

我是否正确地执行了此操作,并且是我的数据设置不正确,还是这些AND和/或OR语句覆盖了WHERE子句?谢谢你的帮助。

这里的关键字是运算符优先级。CCD_ 9先于CCD_ 10结合。

WHERE ksisoldby ILIKE '".$user."'
AND (
     order_description ilike '%".implode("%'
     AND order_description like '%", $search)."%')
  OR order_number ilike '%".implode("%'
     AND order_number like '%", $search)."%'
  OR name ilike '%".implode("%'
     AND name like '%", $search)."%'
  OR reference ilike '%".implode("%'
     AND name like '%", $search)."%'
    )

WHERE子句中的所有项都计算为一个布尔结果。如果你

希望确定唯一选择的项目是那些ksisoldby与$user相同[…]的项目

则必须将OR’ed标准封装在括号中,否则它们将提供其他方式来进行资格验证。

另一方面,您可以像我演示的那样删除AND’ed对周围的括号。

我添加了(语法无关的)空白和换行符,使其更清晰。


顺便说一句,正如评论中提到的那样,如果你不想要表中的所有列,那么列出你想要的列(就像你有它一样)是最佳的方式。


我还考虑使用准备好的语句(或带有参数的服务器端函数),而不是构建一个大的查询字符串来防止SQL注入。您的框架可能提供了一些实现这一点的方法。或者你可以手动操作。

在构建查询字符串的同时,使用quote_literal()来净化用户输入。