简体   繁体   中英

Mysqli parameter binding issue

I need an extra set of eyes on this one. Any help will be greatly appreciated. This is a very simple search query, but for whatever reason I cannot find the bug. Well, I know where the bug is. I just can't get past it. Anyway.....

I am taking a search value from a POST variable, setting that variable and then setting a column variable as follows...

$term = "'%".$_POST['searchTerm']."%'";
$field = "columnName";

When I echo these they come up perfectly. So if I type "a" in the form I would be echoing '%a%' and columnName.

I then prepare the query and bind the parameters as follows...

$suquery=$dbCon->prepare("select * from Table where ? LIKE ?");
$suquery->bind_param('ss', $field, $term);
$suquery->execute();

The result always returns 0 rows. What I am finding as I play with this is that neither bound parameter is working correctly even though it echoes as it should. For instance, when I change the query so that the column is hard coded and only bind the search term....

$suquery=$dbCon->prepare("select * from Table where columnName LIKE ?");
$suquery->bind_param('s', $term);
$suquery->execute();

I still get zero returned rows. This tells me that even though $field echoes as '%a%' something is still off. I really am at a loss on that one. Likewise, when I hard wire the search term and bind the column....

$suquery=$dbCon->prepare("select * from Table where ? LIKE '%a%'");
$suquery->bind_param('s', $field);
$suquery->execute();

I get far too many rows returned. It is actually pulling rows from the table where the value in any column contains the letter "a". So, neither column or term is binding correctly. Mayday!

$suquery=$dbCon->prepare("select * from Table where ? LIKE ?");

Will not work as expected. It will get translated as:

SELECT * from table WHERE 'columnName' LIKE '%a%'

which returns all rows because 'columnName' contains an 'a'. 'columnName' is a string, not an actual column name.

Your second attempt is correct, except you have an extra quotes in the term. When using parameters, you don't need any quotes. The solution is:

$term = "%".$_POST['searchTerm']."%";
$suquery=$dbCon->prepare("select * from Table where columnName LIKE ?");
$suquery->bind_param('s', $term);
$suquery->execute();

EDIT: Original Answer was based on false assumption (assumed PDO instead of mysqli). Changed answer accordingly.

It looks like you are not allowed to use parameter substitution for column names. From the mysqli::prepare documentation:

Note: The markers are legal only in certain places in SQL statements. For example, they are allowed in the VALUES() list of an INSERT statement (to specify column values for a row), or in a comparison with a column in a WHERE clause to specify a comparison value. However, they are not allowed for identifiers (such as table or column names), in the select list that names the columns to be returned by a SELECT statement, or ...

You might want to verify this by hardcoding the column/field name in the query and just replacing the comparison value via parameter...

Just to clarify for anyone stumbling across this. The issue was fairly simple but it was odd enough that tracking it down was a bear. Henrik was partially correct. When parsing the variable $term to use in my LIKE statement I was doing the following:

$term = "'%".$_POST['searchterm']."%'";

Henrik pointed out that I should not need the single quotes bracketing my variable. This is true if one is simply preparing and executing the query as:

$query=$connection->prepare("select * from DATABASE where $field like '$term'");
$query->execute();

That works just fine. However, I was actually using $term as a bound parameter, which meant that I did indeed require the single quotes as the statement itself require the search term to look like this: '%term%'. It requires the single quotes. You will get a syntax error if you try to put the single quotes around the question mark place holder for the bound parameter, and if you do not put the single quotes inside the variable that you are using as the bound parameter the result will always be 0 rows found. So, in short, for anyone else encountering this.... if you are sending the query directly no need for single quotes as you can put them directly into the select statement. If you are using bound parameters you must have the single quotes as part of the variable in order for the query to work properly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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