我有一个多字段的php搜索表单。将通配符添加到其中一个搜索字段时,会导致其他字段检索数据库中的所有数据。如果没有通配符,国家/地区仅查找国家/地区,城市名称仅查找城市:
$sql = " SELECT * FROM `epic_schools_tbl` WHERE ";
if (!empty($_POST['submit'])) {
if (isset($_POST['country'])) {
$country = $_POST['country'];
$sql .= " `country` = :country ";
}
if (isset($_POST['cityname'])) {
$cityname = $_POST['cityname'];
$sql .= " OR `city` = :cityname ";
}
$stmt = $pdo->prepare($sql);
$stmt->execute(array($country,$cityname));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<p>" . $row['country'] . "</p><p>" . $row['city'] . "</p>" . PHP_EOL;
}
}
添加外卡(学校名称)时:
$sql = " SELECT * FROM `epic_schools_tbl` WHERE ";
if (!empty($_POST['submit'])) {
if (isset($_POST['country'])) {
$country = $_POST['country'];
$sql .= " `country` = :country ";
}
if (isset($_POST['schoolname'])) {
$schoolname = $_POST['schoolname'];
$sql .= " OR `school_name` LIKE :schoolname ";
}
if (isset($_POST['cityname'])) {
$cityname = $_POST['cityname'];
$sql .= " OR `city` = :cityname ";
}
$stmt = $pdo->prepare($sql);
$stmt->execute(array($country,"%$schoolname%",$cityname));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<p>" . $row['country'] . "</p><p>" . $row['school_name'] . "</p><p>" . $row['city'] . "</p>" . PHP_EOL;
}
}
它会导致国家和 cityname 来检索数据库中的所有数据。是否可以编写SELECT语句以接受带有通配符的一个输入,而其他输入的形式不是?
答案 0 :(得分:0)
该问题的部分解决方案包括在select语句中放入IF函数。另外,如果留空,则用AND替换OR有助于消除city field或schoolname字段返回整个数据库。
$sql = "select * from epic_schools_tbl where country = if(length(:countryname)=0, country, :countryname2) and city = if(length(:cityname)=0, city, :cityname2) and (school_name like concat('%', if(length(:schoolname)=0, school_name, :schoolname2) , '%') or alternate_names like concat('%', if(length(:alternatenames)=0, alternate_names, :alternatenames2) , '%') and aka_names like concat('%', if(length(:akanames)=0, aka_names, :akanames2) , '%'))";
$stmt = $pdo->prepare($sql);
$countryname = $_POST['country'];
$cityname = $_POST['cityname'];
$schoolname = $_POST['schoolname'];
$alternatenames = $_POST['schoolname'];
$akanames = $_POST['schoolname'];
//Bind the variables to the prepared statement. Maybe each bind variable must have unique name.
$stmt->bindParam(':countryname', $countryname);
$stmt->bindParam(':countryname2', $countryname);
$stmt->bindParam(':cityname', $cityname);
$stmt->bindParam(':cityname2', $cityname);
$stmt->bindParam(':schoolname', $schoolname);
$stmt->bindParam(':schoolname2', $schoolname);
$stmt->bindParam(':alternatenames', $alternatenames);
$stmt->bindParam(':alternatenames2', $alternatenames);
$stmt->bindParam(':akanames', $akanames);
$stmt->bindParam(':akanames2', $akanames);
//Nothing to pass in. Everything is already bound.
$stmt->execute();