4

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!

4

3 回答 3

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

不会按预期工作。它将被翻译为:

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

它返回所有行,因为“columnName”包含一个“a”。'columnName' 是一个字符串,而不是实际的列名。

您的第二次尝试是正确的,除非您在该术语中有额外的引号。使用参数时,不需要任何引号。解决方案是:

$term = "%".$_POST['searchTerm']."%";
$suquery=$dbCon->prepare("select * from Table where columnName LIKE ?");
$suquery->bind_param('s', $term);
$suquery->execute();
于 2009-10-02T01:49:55.827 回答
2

编辑:原始答案基于错误的假设(假设 PDO 而不是 mysqli)。相应地改变了答案。

看起来您不允许对列名使用参数替换。从mysqli::prepare文档:

注意:标记仅在 SQL 语句中的某些地方是合法的。例如,它们可以在 INSERT 语句的 VALUES() 列表中使用(以指定行的列值),或者在与 WHERE 子句中的列进行比较以指定比较值时。但是,它们不允许用于标识符(例如表或列名),在选择列表中命名要由 SELECT 语句返回的列,或者...

您可能希望通过硬编码查询中的列/字段名称并仅通过参数替换比较值来验证这一点...

于 2009-10-01T14:19:56.380 回答
0

只是为了澄清任何偶然发现这一点的人。这个问题相当简单,但奇怪的是,追踪它是一只熊。Henrik 部分正确。在解析要在我的 LIKE 语句中使用的变量 $term 时,我正在执行以下操作:

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

Henrik 指出我不应该需要用单引号括住我的变量。如果一个人只是简单地准备和执行查询,这是正确的:

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

这工作得很好。但是,我实际上使用 $term 作为绑定参数,这意味着我确实需要单引号,因为语句本身要求搜索词看起来像这样:'%term%'。它需要单引号。如果您尝试将单引号放在绑定参数的问号占位符周围,您将收到语法错误,并且如果您没有将单引号放在您用作绑定参数的变量中,结果将始终为找到 0 行。因此,简而言之,对于遇到此问题的任何其他人......如果您直接发送查询,则不需要单引号,因为您可以将它们直接放入 select 语句中。如果您使用绑定参数,则必须将单引号作为变量的一部分,以便查询正常工作。

于 2009-10-14T23:27:07.647 回答