我的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服务器?