I feel like this search query is not working as I imagined it would. I want to be certain that the only items selected are those with ksisoldby identical (though case-insensitive, thus ILIKE) to $user. And the the other fields specified with the ANDs and ORs are possible ways this selection could be narrowed down.
"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";
Have I done this correctly, and it is my data that is not set up correctly, or are these AND and/or OR statements overriding the WHERE clause? Thanks for the help.
The keyword here is operator precedence.
ANDbinds beforeOR.All items in the
WHEREclause are evaluated to one boolean result. If youthen you have to wrap the
OR‘ed criteria into parenthesis or they will offer alternative ways to qualify.On the other hand, you can remove the parenthesis around the
AND‘ed pairs like I demonstrate.I added (syntactically irrelevant) white space and line breaks to make it clearer.
BTW – as this came up in the comments – if you don’t want all columns from the table, listing the ones you want (like you have it) is the optimal way.
I would also consider to use prepared statements (or server-side functions with parameters) instead of building one big query strings to prevent SQL injection. Your framework probably offers some way to do this. Or you can do it manually.
While you keep building query strings, use
quote_literal()to sanitize user input.