插入时自动截断数据

ale*_*aui 5 php mysql windows pdo

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

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

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

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

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

非常感谢

mvp*_*mvp 4

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

如果您不知道 VARCHAR 列的实际宽度或者不想在脚本中对其进行硬编码,则可以通过使用如下查询查询INFORMATION_SCHEMA表来从数据库中读取它:COLUMNS

SELECT
    column_name,
    data_type,
    character_maximum_length,
    ordinal_position
FROM information_schema.columns
WHERE table_name = 'mytable'
Run Code Online (Sandbox Code Playgroud)

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

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

但如果您坚持以不安全的方式这样做,您可以尝试通过执行以下命令暂时禁用严格模式:

SET sql_mode = '';
Run Code Online (Sandbox Code Playgroud)

之后 MySQL 应该默默地修剪字符串。在这里阅读更多内容。