PDO:Prepare 执行15万长度的sql失败

新手上路,请多包涵

问题描述

sql长度为15万长度的时候失败,此时bindParam数组大小为 68000
sql 类型是insert,使用了参数绑定的方式,打印出来的sql都是占位符。

问题出现的环境背景及自己尝试过哪些方法

错误分析,一开始是bindValue($i,$v,PDO:STR); 这块报错。
后面追踪到 $sth = $this->conn->prepare($sql) 返回的对象为空,导致bindValue方法无法执行。
但在sql为14万长度 左右时执行成功,此时bindParam 数组大小为 63000
此时的sql与15万长度的sql 长度不一样,但语法都正确,没有被截取。

你期待的结果是什么?实际看到的错误信息又是什么?

百度过了,没看到prepare函数的中string参数的限制,
14万长度的sql也才 0.2mb=16 万字节
应该不是超长度了。 关于pdo的参数设置感觉也不太相关。
希望有经验的大神能分析一下这个问题,顺便问下 pdo底层的源码实现在哪可以看? 谢谢

阅读 2.9k
1 个回答
✓ 已被采纳新手上路,请多包涵

排查过程

  1. Sql有问题:打印输出。对比发现 sql是以占位符形式的 没有问题。
  2. bindParam 数组大小限制:php对数组无大小限制,string字符最大可以达到16MB,而16万长度的sql也才16万字节,0.12MB
  3. 后发现在执行 PDO::prepare($sql) 时不返回数据库对象
  4. 查阅资料,PDO::prepare($sql) 中预处理方式有两种: 将带占位符的 sql语句与bindParam 分开发给 Mysql
    或者是 直接以一条 拼接好的 sql 直接发给 Mysql 处理。
  5. prepare()函数的处理方式与 参数 PDO::ATTR_EMULATE_PREPARES 的值 (TRUE OR FALSE) 有关

    • ATTR_EMULATE_PREPARES,当这个开关为true时,就由本地PHP来处理SQL语句,然后再把语句发往数据库。而如果这个开关的值为false,则PHP不会处理SQL语句,而是把含有占位符的SQL语句及相关变量一起放送往数据库,并由数据库自己来处理。
  6. 以本地处理的形式时,会受本地的php缓存大小影响,因此会出现溢出等问题。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题