在 运行 时间构建多个 LIKE 运算符准备语句
Building Multiple LIKE Operator Prepared Statement at run-time
Table tbl 列
col1 | 列 | col3
SQL 我想使用 with prepared statement 并在运行时绑定参数
select col1, col2, col3
from tbl
where col1=10
and col2 between 0 and 10 and col3 like '%QUERY%';
问题是对 col3 的过滤取决于用户输入。如果只使用 2 个术语,那么它应该是
select col1, col2, col3
from tbl
where col1=10
and col2 between 0 and 10 and (col3 like '%QUERY%' AND col3 like '%QUERY2%');
如果找到 3 个输入,那么它应该是
select col1, col2, col3
from tbl
where col1=10
and col2 between 0 and 10 and (col3 like '%QUERY%' AND col3 like '%QUERY2%' AND col3 like '%QUERY3%');
我只想使用 Prepared Statement 而不是直接查询。我知道同样可以通过清理输入和 运行 直接查询来实现,但我仍然只喜欢准备好的语句。
如何实现?
在我的代码下面:(打开SQL注入
$terms=explode(",",$_POST['txtD']);
$sql='';
for($i=0;$i<count($terms);$i++) {
$terms[$i] = trim($terms[$i]);
if ($i!=$count-1)
$sql = $sql."`Places` LIKE '%$terms[$i]%' AND ";
else
$sql = $sql."`Places` LIKE '%$terms[$i]%'";
}
$stmt = mysqli_prepare($con,"select col1, col2, col3 from tbl where col1=? and col2 between ? and ? and ".$sql);
mysqli_stmt_bind_param($stmt,"iii", $param1, $param2, $param3);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
考虑使用 implode
构建准备好的 SQL 语句的 LIKE
表达式部分。然后构建一个参数参数为 运行 和 call_user_func_array()
.
$terms = explode(",", str_replace(",", " ,", $_POST['txtD']));
// PREPARED STATEMENT BUILD
$likes = [];
foreach($terms as $t) {
$likes[] = "col3 LIKE CONCAT('%', ?, '%')";
}
$expr = implode(" or ", $likes);
$sql = "select col1, col2, col3 from tbl ".
"where col1=? and col2 between ? and ? and (". $expr .")";
// PARAM ARG BUILD
$type = 'iii' . str_repeat("s", count($terms));
$sql_params = array_merge(array($stmt, $type, $param1, $param2, $param3), $terms);
// PREPARE AND EXECUTE QUERY
$stmt = mysqli_prepare($con, $sql);
call_user_func_array('mysqli_stmt_bind_param', sql_params);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
或者,考虑 MySQL 的 REGEXP
正则表达式,使用管道表示 OR
逻辑:
// REPACE COMMAS BY PIPE
$terms = str_replace(",", "|", str_replace(",", " ,", $_POST['txtD']));
$sql = "select col1, col2, col3 from tbl " .
"where col1=? and col2 between ? and ? and col3 regexp ?";
// PREPARE AND EXECUTE QUERY
$stmt = mysqli_prepare($con);
mysqli_stmt_bind_param($stmt, "iii", $param1, $param2, $param3, $terms);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
如前所述请注意 here REGEXP
的执行速度比等效的 LIKE
表达式要慢。
Table tbl 列
col1 | 列 | col3
SQL 我想使用 with prepared statement 并在运行时绑定参数
select col1, col2, col3
from tbl
where col1=10
and col2 between 0 and 10 and col3 like '%QUERY%';
问题是对 col3 的过滤取决于用户输入。如果只使用 2 个术语,那么它应该是
select col1, col2, col3
from tbl
where col1=10
and col2 between 0 and 10 and (col3 like '%QUERY%' AND col3 like '%QUERY2%');
如果找到 3 个输入,那么它应该是
select col1, col2, col3
from tbl
where col1=10
and col2 between 0 and 10 and (col3 like '%QUERY%' AND col3 like '%QUERY2%' AND col3 like '%QUERY3%');
我只想使用 Prepared Statement 而不是直接查询。我知道同样可以通过清理输入和 运行 直接查询来实现,但我仍然只喜欢准备好的语句。
如何实现?
在我的代码下面:(打开SQL注入
$terms=explode(",",$_POST['txtD']);
$sql='';
for($i=0;$i<count($terms);$i++) {
$terms[$i] = trim($terms[$i]);
if ($i!=$count-1)
$sql = $sql."`Places` LIKE '%$terms[$i]%' AND ";
else
$sql = $sql."`Places` LIKE '%$terms[$i]%'";
}
$stmt = mysqli_prepare($con,"select col1, col2, col3 from tbl where col1=? and col2 between ? and ? and ".$sql);
mysqli_stmt_bind_param($stmt,"iii", $param1, $param2, $param3);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
考虑使用 implode
构建准备好的 SQL 语句的 LIKE
表达式部分。然后构建一个参数参数为 运行 和 call_user_func_array()
.
$terms = explode(",", str_replace(",", " ,", $_POST['txtD']));
// PREPARED STATEMENT BUILD
$likes = [];
foreach($terms as $t) {
$likes[] = "col3 LIKE CONCAT('%', ?, '%')";
}
$expr = implode(" or ", $likes);
$sql = "select col1, col2, col3 from tbl ".
"where col1=? and col2 between ? and ? and (". $expr .")";
// PARAM ARG BUILD
$type = 'iii' . str_repeat("s", count($terms));
$sql_params = array_merge(array($stmt, $type, $param1, $param2, $param3), $terms);
// PREPARE AND EXECUTE QUERY
$stmt = mysqli_prepare($con, $sql);
call_user_func_array('mysqli_stmt_bind_param', sql_params);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
或者,考虑 MySQL 的 REGEXP
正则表达式,使用管道表示 OR
逻辑:
// REPACE COMMAS BY PIPE
$terms = str_replace(",", "|", str_replace(",", " ,", $_POST['txtD']));
$sql = "select col1, col2, col3 from tbl " .
"where col1=? and col2 between ? and ? and col3 regexp ?";
// PREPARE AND EXECUTE QUERY
$stmt = mysqli_prepare($con);
mysqli_stmt_bind_param($stmt, "iii", $param1, $param2, $param3, $terms);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
如前所述请注意 here REGEXP
的执行速度比等效的 LIKE
表达式要慢。