Построение нескольких операторов LIKE, подготовленных оператором во время выполнения - PullRequest
0 голосов
/ 08 февраля 2019

Таблица Табличка Колонки
Кол1 | цв | 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%');

Я хочу использовать только подготовленное утверждение, а не прямой запрос.Я знаю, что того же самого можно достичь путем очистки входных данных и выполнения прямого запроса, но я предпочитаю только подготовленные операторы.

Как этого добиться?

Ниже кода, который я имею :( с открытым 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);

1 Ответ

0 голосов
/ 08 февраля 2019

Попробуйте построить часть выражения LIKE подготовленного оператора SQL, используя implode.Затем создайте аргументы параметров для запуска с 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 и демонстрация построения параметров


В качестве альтернативы,рассмотрим REGEXP MySQL для выражения регулярного выражения, использующего каналы для обозначения логики 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);

Обратите внимание, что здесь REGEXP медленнее, чем эквивалент LIKE выражение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...