谁能告诉我为什么这个SQL命令不起作用? 我有一个具有多个输入的表格,即(id)=>帐号,然后是名字,姓氏和电子邮件。我想让用户无论如何都可以搜索。
如果我仅以(id)的方式保留代码的“ with AND”方式,那么它将仅显示ID行,但如果我尝试显示,则不会显示其余搜索输入第一个,最后一个或电子邮件,但是如果我将其更改为“ OR”,则所有其他输入框将可以显示单个结果,但是如果我仅输入id“帐号”,则将显示表中的每个客户..为什么? 我缺少什么,所以我的代码可以搜索所有输入? 谢谢
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$firstname = "%$firstname%";
$lastname = "%$lastname%";
$email = "%$email%";
$id = $_POST['id'];
$stmt = $conn->prepare("
SELECT * FROM `Demo_Guests`
WHERE
firstname LIKE :firstname
AND lastname LIKE :lastname
AND email LIKE :email AND id = :id
");
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->bindValue(':firstname', $firstname,PDO::PARAM_STR);
$stmt->bindValue(':lastname', $lastname,PDO::PARAM_STR);
$stmt->bindValue(':email', $email,PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach($result as $row){
echo "<tr><td>
<a href=\"main_table.php?id={$row->id}\"> " . $row->id . "</a><br></td>";
echo "<td>" . $row->firstname . "</td>";
echo "<td>" . $row->lastname . "</td>";
echo "<td>" . $row->email . "</td>";
echo "<td>" . $row->reg_date . "</td></tr>";
}
答案 0 :(得分:2)
在上面的评论中,我补充说:
使用OR语句时,需要确保您没有firstname LIKE '%%'
,因为这将匹配所有内容。您将需要构建查询以仅使用表单提供的非空值。
这意味着您将必须从搜索表单的NON-EMPTY输入中构建查询,并省略与表中所有内容匹配的术语。
最好先遍历发布数据并提出非空值,然后放入数组中:
$searchFields = [];
foreach (['id', 'firstname', 'lastname', 'email'] as $searchField) {
if (!empty($_POST[$searchField])) {
$searchFields[$searchField] = $_POST[$searchField];
}
}
这将为您提供用户实际填写的所有字段的列表。您将需要该列表两次-一次构建查询,一次进行绑定。
if (count($searchFields) > 0) {
$queryStr = "SELECT * FROM `Demo_Guests` WHERE 0";
foreach (array_keys($searchFields) as $fieldName) {
$queryStr .= " OR " . $fieldName . " LIKE :" . $fieldName;
}
// ... the rest of the code goes here
} else {
return "you gotta give me something to work with!";
}
两个注意事项:1)我没有将id设置为特殊情况,因此您需要在代码中执行此操作。 2)WHERE 0
是一个懒人快捷方式,您以后不必执行任何额外的逻辑来决定是否需要在第一项中添加OR
。它变成WHERE 0 OR firstname LIKE '%Alice%'
,在功能上与WHERE firstname LIKE '%Alice%'
相同。
构建查询字符串后,可以按照上面的方法进行准备,然后使用与构造查询相同的数组执行绑定。
$stmt = $conn->prepare($queryStr);
foreach($searchFields as $fieldName => $fieldValue) {
$stmt->bindValue(':'.$fieldName, "%$fieldValue%", PDO::PARAM_STR);
}
$stmt->execute();
如上所述,我没有创建用于区别id字段的代码,但是您应该能够处理该代码。如果您有许多不同类型的字段,则可能需要更改$ searchFields的结构以包括类型信息。如果id
是唯一的例外,则在每个循环中仅使用if语句可能是最简单的。
添加:
此搜索将返回数据库中与任何输入条件匹配的所有记录。因此,如果用户搜索firstName LIKE '%Ali%' OR lastName LIKE '%Smi%'
,您可能会回来查看Alice Smith,Alicia Smith,Fred Smith和Alice Jones。
但是,如果仅希望该搜索返回Alice Smith和Alicia Smith,而不使用OR
,则使用AND
。搜索将产生较少的结果,因此对名称错误的输入等的容忍度也要稍差一些。
对代码的唯一其他修改是,懒人快捷方式也必须更改:
if (count($searchFields) > 0) {
$queryStr = "SELECT * FROM `Demo_Guests` WHERE 1";
foreach (array_keys($searchFields) as $fieldName) {
$queryStr .= " AND " . $fieldName . " LIKE :" . $fieldName;
}
// ... the rest of the code goes here
} else {
return "you gotta give me something to work with!";
}
WHERE 1 AND first_name LIKE '%Ali%'
在功能上与WHERE first_name LIKE '%Ali%'
相同。
请注意,在这种情况下,如果用户指定ID,则将要完全忽略其他搜索字段。否则,如果他们指定的ID和名称不匹配,则根本不会获得任何结果。