мой вопрос – общий вопрос:
доктрина лечит
$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).