插入时自动截断数据

时间:2012-12-28 21:48:33

标签: php mysql windows pdo

我的MySQL服务器(在Windows 2008 Server上通过PDO运行PHP)在插入超过列中允许的字符串时返回错误代码1406(字段数据太长)。事情是我在某处读到MySQL通常在严格模式下截断数据。我更改了my.ini中的sql_mode,这样即使在启动时它也不会进入严格模式(它当前是“”),但它仍然给我错误并回滚,因此数据丢失(截断是期望的网站行为)。

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

另外,我使网站输出当前的sql模式,包括全局和会话(@@ GLOBAL.sql_mode和@@ SESSION.sql_mode),它们都输出“”但只是不能按预期工作。

有谁知道是什么导致这种情况和/或如何改变它?

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

非常感谢

2 个答案:

答案 0 :(得分:3)

您不应该这样做 - 请不要将错误的数据存入您的数据库,并在插入之前在脚本中对其进行清理。

如果您不知道VARCHAR列的实际宽度或者不想在脚本中对其进行硬编码,则可以通过使用以下查询查询INFORMATION_SCHEMA table 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应该默默地修剪字符串。阅读更多here

答案 1 :(得分:0)

可能是mysql服务器处于“不宽容”模式,也就是说。传统的(大多数时候)。如果mysql服务器以宽容模式运行,那么你读到的是真的。如果你试图插入太长的字符串,它可能是非常重要的信息,因此mysql会发出错误。你有几个选择:

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

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

使用其中任何一个问题都应该消失。

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

PS2:更改my.cnf后,你重新启动了mysql服务器吗?