Автоматически обрезать строки до нужной длины при вставке - PullRequest
2 голосов
/ 19 июня 2009

У меня есть таблица с различными полями VARCHAR в MySQL. Я хотел бы вставить некоторые пользовательские данные из формы через PHP. Очевидно, что если я знаю длину полей в PHP, я могу ограничить длину данных там substr(). Но этот тип нарушает DRY (длина поля хранится в MySQL и как константа в моем PHP-скрипте). Есть ли способ настроить INSERT так, чтобы он автоматически обрезал чрезмерно длинные строки, а не отказывал?

edit: сбой (или по крайней мере вызывающий исключение) в PHP / PDO, когда у меня слишком длинные строки. Не уверен, что я должен делать в PHP / PDO, чтобы он правильно делал.

редактировать 2: тьфу. Это неправильный подход; даже если я заставлю его работать нормально на INSERT, если я хочу проверить наличие дублирующейся строки, она не будет соответствовать должным образом.

Ответы [ 3 ]

9 голосов
/ 19 июня 2009

На самом деле 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.

Обновление: MySQL 5.7 и выше устанавливает строгий режим по умолчанию. См https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

0 голосов
/ 02 июля 2009

Вы можете использовать метаданные столбца для проверки длины строки. ( Руководство по 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;
}
0 голосов
/ 19 июня 2009

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

SET @prev_mode = @@sql_mode;
SET sql_mode = '';
INSERT blah....;
SET sql_mode = @prev_mode;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...