Как исправить ошибку в SQL запросе, связанной с конструкцией WHEN THEN?

Здравствуйте! Уже несколько дней я пытаюсь разобраться с проблемой: код работает корректно с другими данными, но в этом случае возникает ошибка... Вот текст ошибки: <br/> <pre><code class="sql">Ошибка MySQL
    You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END), `is_updated` = (CASE `id` END), `is_order` = (CASE `id` END), `is_exist`' at line 1
    UPDATE `table` set `count` = (CASE `id` END), `is_updated` = (CASE `id` END), `is_order` = (CASE `id` END), `is_exist` = (CASE `id` END), `price` = (CASE `id` END) WHERE `id` IN () AND `deleted` = 'N'</code></pre> <br/> Код для вставки выглядит следующим образом: <br/> <pre><code class="php">// Все переменные проверял, строки формируются корректно и количество совпадает
// Пробовал разные форматы для цифр в кавычках, это не решает проблему!
$sqlPartRusklimatProductName .= ($sqlPartRusklimatProductName == '') ? "'{$itemName['id']}'" : ',' . "'{$itemName['id']}'";
$caseIsExist .= " WHEN '{$itemName['id']}' THEN 'Y'";
$caseIsOrder .= " WHEN '{$itemName['id']}' THEN 'N'";
$caseCount .= " WHEN '{$itemName['id']}' THEN '$count'";
$caseUpdated .= " WHEN '{$itemName['id']}' THEN 'Y'";
$casePrice .= " WHEN '{$itemName['id']}' THEN '$price'";

$updateProductRusklimat = "UPDATE `table` set `count` = (CASE `id` $caseCount END), `is_updated` = (CASE `id` $caseUpdated END), `is_order` = (CASE `id` $caseIsOrder END), `is_exist` = (CASE `id` $caseIsExist END), `price` = (CASE `id` $casePrice END) WHERE `id` IN ($sqlPartRusklimatProductName) AND `deleted` = 'N'";
db()->query($updateProductRusklimat);</code></pre> <br/> Что особенно странно, так это то, что в других частях кода все работает исправно. Не могу понять, в чем может быть проблема...
  • 28 октября 2024 г. 9:52
Ответы на вопрос 3
Ошибка в вашем SQL запросе связана с тем, что конструкции `CASE` не формируются корректно. Давайте рассмотрим ваш код и выделим ключевые моменты, которые могут вызывать проблемы.

Ваша конструкция `CASE` выглядит так:
```sql
.. = (CASE `id` $caseCount END)
```
Однако в случае, если не будет условий (если, например, `$caseCount` будет пустым), вы получите ошибку синтаксиса, потому что конструкция `CASE` не будет завершена верно.

### Возможные причины проблемы:
1. **Пустая конструкция `CASE`**: Если ни одно из значений `id` не подходит, или если переменные `$caseCount`, `$caseUpdated`, `$caseIsOrder`, `$caseIsExist`, и `$casePrice` остались пустыми, результатом будет некорректный синтаксис SQL. В таком случае вы получите что-то вроде:
   ```sql
   (CASE `id` END)
   ```
   без условий.

2. **Неправильное формирование списка `id`**: Если `$sqlPartRusklimatProductName` оказывается пустым (например, если нет элементов для обновления), это также приведет к ошибке.

### Рекомендации по исправлению:
1. **Проверка на пустоту**: Перед выполнением запроса убедитесь, что все необходимые переменные не пустые. Если переменные пустые, вам следует пропустить выполнение запроса или обработать это соответствующим образом.

2. **Добавление условия для `CASE`**: Добавьте проверку, чтобы `CASE` имел хотя бы одно условие. Например:
   ```php
   if (!empty($caseCount)) {
       $caseCount = "CASE `id` $caseCount END";
   } else {
       $caseCount = "NULL"; // или какое-то другое значение по умолчанию
   }
   ```

3. **Проверка на наличие `id`**: Убедитесь, что `id` для обновления действительно есть. Если `$sqlPartRusklimatProductName` будет пустым, инициируйте обработку ошибки, чтобы запрос не выполнялся.

### Пример исправленного кода:
```php
if ($sqlPartRusklimatProductName != '') {
    $caseCount = !empty($caseCount) ? "CASE `id` $caseCount END" : "NULL";
    $caseUpdated = !empty($caseUpdated) ? "CASE `id` $caseUpdated END" : "NULL";
    $caseIsOrder = !empty($caseIsOrder) ? "CASE `id` $caseIsOrder END" : "NULL";
    $caseIsExist = !empty($caseIsExist) ? "CASE `id` $caseIsExist END" : "NULL";
    $casePrice = !empty($casePrice) ? "CASE `id` $casePrice END" : "NULL";

    $updateProductRusklimat = "UPDATE `table` 
        SET `count` = $caseCount, 
            `is_updated` = $caseUpdated, 
            `is_order` = $caseIsOrder, 
            `is_exist` = $caseIsExist, 
            `price` = $casePrice 
        WHERE `id` IN ($sqlPartRusklimatProductName) 
        AND `deleted` = 'N'";
    
    db()->query($updateProductRusklimat);
} else {
    // Обработка случая, когда нет идентификаторов для обновления
}
```

Это должно помочь избежать ошибок синтаксиса в вашем SQL запросе.
Судя по обрывкам кода, первый фрагмент выполняется в цикле. 
Тогда по тексту ошибки видно, что этот цикл ни разу не выполнялся и в переменных пустые строки.
Главные причины проблем с кодом это наивность и самомнение. 

Что самое интересное - в других местах работает нормально...,

- это конечно запредельная наивность.
Начинающие программисты всегда пишут код так, как будто он будет работать в идеальных условиях. Данные всегда приходят корректные и из доверенного источника. "У меня код eval($_GET['command'])" работает отлично, проблем не доставляет!"

А вот когда этот замечательный код перестаёт работать, или начинает делать то, о чем никто не подумал, то глазки нашего разработчика наливаются удивлением и даже обидой - "ну как же так, раньше ведь всё работало!"

А то что это исходно был говнокод, они не думают. И что сейчас даже в первом классе рассказывают про подготовленные выражения они забыли. Или не забыли, а просто отмахнулись - "и так сойдёт!".

Не сошло.
Похожие вопросы