Как выполнить поиск по идентификатору, используя число без его преобразования?

Здравствуйте! 

У меня есть таблица <code>page</code> с колонкой <code>id</code> ( <code>int PRIMARY KEY NOT NULL AUTO_INCREMENT</code>). 

Я могу корректно выполнить запрос, чтобы получить данные по <code>id</code>: <br/> 
<code class="sql">SELECT * FROM page WHERE id = '1' LIMIT 1</code>. 

Однако также идет успешное получение данных, если я выполню запрос с номером и буквой, например: <br/> 
<code class="sql">SELECT * FROM page WHERE id = '1dsf' LIMIT 1</code>. 

Насколько я понимаю, MySQL преобразует строковое значение к числу и игнорирует символы. 

Если это действительно так, как я могу сделать запросы с более строгой проверкой? Если причина в чем-то другом, как избежать этого поведения? 

Заранее спасибо!
  • 31 октября 2024 г. 16:52
Ответы на вопрос 1
Здравствуйте!

Да, вы правы, MySQL по умолчанию может неявно преобразовывать строковые значения к числовым, что приводит к тому, что, например, строка `'1dsf'` будет интерпретирована как `1`, и соответственно, запрос будет возвращать запись с `id = 1`. Это поведение связано с тем, что MySQL использует неявное преобразование типов при сравнении значений.

Если вы хотите выполнить более строгую проверку, чтобы гарантировать, что `id` является именно числом, вы можете использовать следующие подходы:

1. **Проверка на целочисленное значение в приложении**: Перед выполнением запроса в приложении проверьте, что переданный параметр является целым числом. Например, на языке PHP это можно сделать так:

   ```php
   if (filter_var($id, FILTER_VALIDATE_INT)) {
       $query = "SELECT * FROM page WHERE id = ?";
       // Выполнение запроса с использованием подготовленного выражения
   } else {
       // Обработка ошибки
   }
   ```

2. **Использование строгого сравнения**: Вы можете добавить явное преобразование типа в запросе, чтобы обеспечить строгое сравнение. Например, вы можете использовать оператор `CAST` или `CONVERT`:

   ```sql
   SELECT * FROM page WHERE id = CAST('1dsf' AS UNSIGNED) LIMIT 1;
   ```

   Однако это не даст вам желаемого результата, если строка не может быть преобразована в число (в случае вы получите 0).

3. **Использование регулярного выражения**: Убедитесь, что значение `id` соответствует вашему ожиданию, используя регулярное выражение:

   ```sql
   SELECT * FROM page WHERE id REGEXP '^[0-9]+$' AND id = '1dsf' LIMIT 1;
   ```

   Этот запрос вернет результат только для числовых значений.

4. **Использование текущих решений СУБД**: Некоторые движки баз данных могут иметь свои собственные способы обработки типов и могут поддерживать более строгие проверки типов. Если вы используете MySQL, вы можете также рассмотреть возможность использования `STRICT` режима в MySQL, однако это в основном будет касаться вставки и обновления данных.

Каждый из этих подходов может помочь вам получить более строгое поведение, когда вы делаете запросы по идентификатору. Выберите тот, который наилучшим образом соответствует вашим требованиям и среде.
Похожие вопросы