У меня есть таблица с различными полями VARCHAR в MySQL. Я хотел бы вставить некоторые пользовательские данные из формы через PHP. Очевидно, если я знаю длины полей в PHP, я могу ограничить длину данных там с помощью substr()
. Но этот тип нарушает DRY (длина поля хранится в MySQL и как константа в моем PHP-скрипте). Есть ли способ настроить INSERT таким образом, чтобы он автоматически прерывал чрезмерно длинные строки, а не терпел неудачу?
edit: он не работает (или, по крайней мере, вызывает исключение) в PHP / PDO, когда у меня слишком длинные строки. Не уверен, что мне нужно делать в PHP / PDO, чтобы он делал правильную вещь.
edit 2: Ugh. Это неправильный подход; даже если я получу его, чтобы нормально работать в INSERT, если я хочу проверить дублируемую строку, это будет неправильно соответствовать.
Фактически, MySQL обрезает строки по ширине столбца по умолчанию. Он генерирует предупреждение, но допускает вставку.
mysql> create table foo (str varchar(10)); mysql> insert into foo values ('abcdefghijklmnopqrstuvwxyz'); Query OK, 1 row affected, 1 warning (0.00 sec) mysql> show warnings; +---------+------+------------------------------------------+ | Level | Code | Message | +---------+------+------------------------------------------+ | Warning | 1265 | Data truncated for column 'str' at row 1 | +---------+------+------------------------------------------+ mysql> select * from foo; +------------+ | str | +------------+ | abcdefghij | +------------+
Если вы установите строгий режим SQL, он превратит это предупреждение в ошибку и отклонит вставку.
Повторите свой комментарий: Режим SQL – это конфигурация сервера MySQL. Вероятно, это не PDO, это вызывает его, но, с другой стороны, это возможно, потому что любой клиент может установить режим SQL для своего сеанса.
Вы можете получить текущее глобальное значение или значение sql_mode сеанса со следующими утверждениями:
SELECT @@GLOBAL.sql_mode; SELECT @@SESSION.sql_mode;
По умолчанию должна быть пустая строка (без установленных режимов). Вы можете установить режим SQL в файле my.cnf
с параметром --sql-mode
для mysqld или с помощью инструкции SET
.
См. http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html полную документацию по режимам SQL.
Вы можете использовать метаданные столбца для проверки длины строки. ( Руководство PHP по PDOStatement-> getColumnMeta )
Получить метаданные для всей таблицы таким образом
$query = $conn->query("SELECT * FROM places"); $numcols = $query->columnCount(); $tablemeta = array(); for ($i = 0; $i < $numcols; $i++) { $colmeta = $query->getColumnMeta($i); $tablemeta[$colmeta['name']] = $colmeta; }
вы можете запросить информацию_схемы, чтобы получить длину столбца и использовать эти данные для усечения перед вставкой, но это больше накладных расходов, чем необходимо. просто отключите строгий режим SQL для этого утверждения:
SET @prev_mode = @@sql_mode; SET sql_mode = ''; INSERT blah....; SET sql_mode = @prev_mode;