MySQL PDO SQLSTATE[22003] 异常案例

Part 0. 场景描述:

1. 基于 PHP 7.0.x 的项目部署于 CentOS 7.2(1511)系统下,程序通过 PDO 访问远程的 MySQL 5.7.x 数据库系统;

2. 程序在尝试向数据库中 Insert 一条数据时,提示某个 bigint 类型的字段异常,SQL STATE 22003 :


[2018-08-12 16:26:02] production.ERROR: SQLSTATE[22003]: Numeric value out of range: \

1264 Out of range value for column 'mem_id' at row ......

3. 尝试在 MySQL 数据库服务器本地通过 MySQL Client 执行同样的 SQL 语句,执行成功,说明问题发生在部署项目的应用服务器一端。

Part I. 对比分析

通过 phpinfo() 对比了一下新环境和开发环境的具体参数,发现由于升级到了 CentOS 7.2 系统,编译 PHP 7.0.x 时,参数 --with-pdo-mysql 使用默认值的情况下,生成的 pdo_mysql 的 API 版本变更为 5.5.56-MariaDB,而非 MySQL 原生的 API 版本。

猜测问题可能是由于这个 API 版本变更而导致的。

pdo_system.PNG

Part II. 使用原生 PDO 驱动重新编译 PHP

1. 重新编译 PHP 7.0.x ,MySQL 驱动相关参数强制指定使用原生驱动;


./configure \

......

--with-mysqli=mysqlnd \

--with-pdo-mysql=mysqlnd \

......

make 

make install

2. 重新编译 PHP 后,通过 phpinfo() 确认 pdo_mysql 的 API 版本;

pdo_mysqlnd.PNG

3. 重新通过程序执行了对数据库的 Insert 操作,显示执行成功。

Part III. 总结

1. PHP 编译参数中的 mysqlnd,nd 就是 Native Driver 的缩写,即所谓的官方原生驱动;

2. 为了降低操作系统差异造成的业务系统异常,建议编译 PHP 的过程中强制指定使用官方原生驱动,而非使用操作系统自带的驱动;

3. 本例中 PDO 产生的 SQLSTATE[22003] 异常,基本上还是属于特定版本 API 的 BUG 。

EOF

你可能感兴趣的:(MySQL PDO SQLSTATE[22003] 异常案例)