插入时自动截断数据


Automatically truncate data when inserting

我的MySQL服务器(运行PHP通过PDO在Windows 2008服务器)返回错误代码1406(数据太长字段)插入字符串超过允许在列中。问题是,我在某个地方读到MySQL通常在非严格模式下截断数据。我改变了my.ini中的sql_mode,以便即使在启动时它也不会进入严格模式(它目前是"),但它仍然给我错误并回滚,因此数据丢失(截断是该站点的期望行为)。

我进入命令行,并在较短的varchar字段中插入一个长字符串,它确实截断数据并保存,但它是网站没有。当我将模式更改回strict时,它不会在命令行中截断(只有错误)。

此外,我使站点输出当前sql模式,包括全局和会话(@@GLOBAL)。@@SESSION.sql_mode和@@SESSION.sql_mode),它们都输出",但不按预期工作。

有谁知道是什么原因造成的和/或如何改变它?

我的怀疑是,它可能与PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION启用PDO有关,但我已经阅读并找不到任何有用的东西(我真的不认为这绝对是解释,但我只是把它放在那里,以便您尽可能多地了解这个问题)。

非常感谢

您不应该这样做——请不要让不良数据进入数据库,并在插入之前在脚本中对其进行清理。

如果你不知道你的VARCHAR列的实际宽度,或者不想在你的脚本中硬编码它,你可以通过查询INFORMATION_SCHEMA表COLUMNS从数据库中读取它,如下所示:

SELECT
    column_name,
    data_type,
    character_maximum_length,
    ordinal_position
FROM information_schema.columns
WHERE table_name = 'mytable'

(您可能希望将其限制为仅data_type = 'varchar')。有了这些信息,特别是character_maximum_length,您可以使用PHP substr将输入字符串修剪到所需的长度。

这种方法的优点是它不改变任何服务器配置,并且应该适用于任何其他数据库,而不仅仅是MySQL。

但是如果你坚持使用不安全的方式,你可以通过执行下面的命令来暂时禁用严格模式:

SET sql_mode = '';

之后,MySQL应该静默地修剪字符串。

可能mysql服务器处于"不原谅"模式,也就是。传统的(大多数时候)。你读的是真的,如果mysql服务器运行在宽恕模式。如果你试图插入太长的字符串,它可能是非常重要的信息,因此mysql将发出一个错误。您有几个选择:

1:使用insert ignore(将所有错误转换为警告并继续截断数据)

2:对于当前会话,将sql_mode设置为"

"

只要有这两种方法,你的问题就会消失。

PS:我已经阅读了你得到的错误,但我仍然认为服务器是在传统模式下运行(所以我建议将sql_mode设置为空是没有错误的)。

PS2:修改了my.cnf文件后,是否重新启动了mysql服务器?