【问题标题】:Building Multiple LIKE Operator Prepared Statement at run-time在运行时构建多个 LIKE 运算符准备语句
【发布时间】:2019-02-08 16:47:15
【问题描述】:

表格tbl列
col1 | col | col3

我想在运行时绑定参数的预处理语句使用 SQL

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);

【问题讨论】:

  • 准备 SQL 只是一个字符串。您可以构建它并将值保存在数组中以供以后用于绑定。
  • 不需要括号,因为您只使用AND 子句。使用implode() 这完全是微不足道的,但由于您没有展示您尝试过的内容,因此无法帮助您解决具体问题
  • 如果你要在运行时绑定参数,它应该看起来像col3 LIKE CONCAT('%', ?, '%')。
  • @MonkeyZeus 添加代码

标签: php mysql mysqli prepared-statement


【解决方案1】:

考虑使用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);

SQL and Param Build Demo


或者,考虑 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 表达式要慢。

【讨论】:

    猜你喜欢
    • 2017-03-04
    • 2014-11-14
    • 1970-01-01
    • 2012-08-09
    • 2015-10-22
    • 1970-01-01
    • 2014-09-02
    相关资源
    最近更新 更多