Я пытаюсь создать и выполнить запрос на удаление, когда table_name и conditional_clauses передаются в качестве параметров OOP. Я использую PDO, завернув его в пользовательскую оболочку. Я использую подготовленные заявления с именными заполнителями. В каждом случае я передаю ассоциативный массив внутри функции PDO->execute()
, где array_keys - это имя используемых заполнителей, а array_value - соответствующие значения, которые будут заменены. Я сталкиваюсь с проблемами только в одном случае, когда я хочу указать условие IS NULL
с предложением WHERE .
В основном, если я хочу найти что-то вроде:
SELECT * FROM EMPLOYEES WHERE salary > 10000 AND skill IS NULL
Я могу динамически построить подготовленный оператор, который выглядит следующим образом:
$sql = SELECT * FROM employees WHERE salary > :salary AND skill IS :skill
И затем выполнить подготовленный SQL как:
$stmt->execute(["salary" => 10000,
"skill" => null])
Вот где я нахожусь сталкивается с проблемой. Я получаю фатальную ошибку здесь, только когда значение равно null . И я хочу включить проверку функциональности IS NULL в моей оболочке.
Обратите внимание -
Я хочу достичь цели без использования bindValue () или bindParam () функции.
Я отключил эмуляцию (так как MySQL может отсортировать все заполнители
правильно).
Использование ? в качестве заполнителей не вариант для меня. В противном случае мне придется
переделать всю мою кодовую базу.
Вот фрагмент кода для справки:
<?php
class DeleteQuery {
protected function where(array $whereCondition, array &$values): string{
$whereClause = ' WHERE ';
$i = 0;
$j = 0;
$hasComparators = array_key_exists("comparators", $whereCondition);
$hasConjunctions = array_key_exists("conjunctions", $whereCondition);
$comparatorCount = $hasComparators ? count($whereCondition["comparators"]) : 0;
$conjunctionCount = $hasConjunctions ? count($whereCondition["conjunctions"]) : 0;
foreach ($whereCondition["predicates"] as $predicate_key => &$predicate_value) {
$whereClause .= $predicate_key;
$whereClause .= ($hasComparators and ($i < $comparatorCount)) ?
' ' . $whereCondition["comparators"][$i++] . ' ' : ' = ';
if (is_array($predicate_value)) {
$whereClause .= "('" . implode("', '", $predicate_value) . "')";
unset($whereCondition['predicates'][$predicate_key]);
} else {
$whereClause .= ':' . $predicate_key;
}
$whereClause .= !($hasConjunctions and ($j < $conjunctionCount)) ?
'' : ' ' . $whereCondition["conjunctions"][$j++] . ' ';
}
$values = array_merge($values, $whereCondition['predicates']);
return $whereClause;
}
public function delete($tblName, $conditions) {
$sql = "DELETE FROM " . $tblName;
$values = [];
if (!empty($conditions) && is_array($conditions)) {
/* If the stmt has WHERE clause */
if (array_key_exists("where", $conditions)) {
$sql .= $this->where($conditions['where'], $values);
}
/* If the stmt has ORDER BY clause */
if (array_key_exists("order_by", $conditions)) {
$sql .= $this->order_by($conditions['order_by']);
}
/* If the stmt has LIMIT clause */
if (array_key_exists("limit", $conditions)) {
$sql .= $this->limit($conditions['limit'], $values);
}
}
echo $sql . PHP_EOL;
print_r($values);
}
}
$deleteConditions = [
"where" => array(
"predicates" => ["skill" => null],
"comparators" => ["IS"],
),
/* other conditional clauses */
];
$obj = new DeleteQuery();
$obj->delete("employees", $deleteConditions);