mysql autocasting string для integer

мой вопрос – общий вопрос:

доктрина лечит

$entitity->getTest()->clear();

в этот sql-запрос:

 DELETE FROM test WHERE test_id = '6' 

-> test_id является целым числом в базе данных, mysql преобразует автоматическое значение, чтобы оно работало. но правильный запрос:

  DELETE FROM test WHERE test_id = 6 

Здесь я нашел несколько дискуссий:

stackoverflow.com/questions/21762075/mysql-automatically-cast-convert-a-string-to-a-number

code.openark.org/blog/mysql/implicit-casting-you-dont-want-to-see-around

mysql doc говорит:

http://dev.mysql.com/doc/refman/5.5/en/type-conversion.html

«Следующие правила описывают, как происходит преобразование для операций сравнения» (..) Во всех остальных случаях аргументы сравниваются как числа с плавающей запятой (реальные).

Документация также сообщает о проблеме:

Сравнение, использующее числа с плавающей запятой (или значения, которые преобразуются в числа с плавающей запятой), является приблизительным, поскольку такие числа неточны. Это может привести к появлению непоследовательных результатов

Итак, почему доктрина orm, а также dbal действует так? Разве это не проблема с таблицами с целыми числами? только с bigint?

Также смотрите здесь:

http://www.cubrid.org/cubrid_implicit_type_conversion

-> Там он говорит, что это не проблема.

Поэтому мой вопрос: делать запрос с тем, где int_val = '1' (string) не имеет большого значения или это может быть опасно. если это опасно, поспешите учить проблему дизайна здесь?

Из документов:

  • Если один или оба аргумента равны NULL , результат сравнения равен NULL , за исключением NULL <=> оператора сравнения равенства. Для NULL <=> NULL результат верен. Преобразование не требуется.

  • Если оба аргумента в операции сравнения являются строками, они сравниваются как строки.

  • Если оба аргумента являются целыми числами, они сравниваются как целые числа.

  • Шестнадцатеричные значения рассматриваются как двоичные строки, если они не сравниваются с числом.

  • Если одним из аргументов является столбец TIMESTAMP или DATETIME а другой аргумент является константой, константа преобразуется в метку времени перед выполнением сравнения. Это сделано, чтобы быть более дружественным ODBC. Обратите внимание, что это не делается для аргументов IN() ! Чтобы быть в безопасности, всегда используйте полные даты, дату или временные строки при выполнении сравнений. Например, для достижения наилучших результатов при использовании BETWEEN с датами или значениями времени используйте CAST() чтобы явно преобразовать значения в нужный тип данных.

  • Если один из аргументов является десятичным значением, сравнение зависит от другого аргумента. Аргументы сравниваются как десятичные значения, если другой аргумент является десятичным или целочисленным значением или значениями с плавающей запятой, если другой аргумент является значением с плавающей запятой.

  • Во всех остальных случаях аргументы сравниваются как числа с плавающей запятой (реальные).

Ваше дело подпадает под «все другие случаи».

Строка будет int_val FLOAT а затем сравнена с вашим int_val .

Если строка отличает красиво (значения типа '1' , '0.1' или '1E5' ), результирующее значение будет сравниваться с целым числом.

Если нет (скажем, вы передаете значение типа '1235xxx' ), возможные ведущие цифры будут переданы в float ( 0 если нет), а остальные будут усечены. Кроме того, будет создано предупреждение.

Причина передачи идентификатора в строке может заключаться в том, что ваш идентификатор необязательно должен быть целым числом. Это может быть строка или дата.

Вероятно, ORM имеет общий код для генерации запроса DELETE который будет работать с любым типом данных.

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

Это также применяется при выборе / вставке / обновлении, используя тип столбца в качестве ссылки.

Итак, если вы выполняете SELECT * FROM users WHERE balance = '1234' а тип balance столбца – DECIMAL (6,2) , подразумевается следующее.

 mysql> SELECT CONVERT ('1234', DECIMAL (6,2)); +---------------------------------+ | CONVERT ('1234', DECIMAL (6,2)) | +---------------------------------+ | 1234.00 | +---------------------------------+ 1 row in set (0.00 sec) 

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

 mysql> SELECT CONVERT ('test', DECIMAL (6,2)); +---------------------------------+ | CONVERT ('test', DECIMAL (6,2)) | +---------------------------------+ | 0.00 | +---------------------------------+ 1 row in set, 1 warning (0.00 sec) 

Нет, нет никакой уязвимости (по крайней мере, на стороне MySQL).