PostgreSQL提示无$1参数:新增列代码MySQL正常PostgreSQL失败原因排查
问题根因
- 核心差异点在于MySQL和PostgreSQL的JDBC驱动对预编译语句的处理逻辑,以及DDL语句的参数支持能力不同:
- MySQL JDBC驱动默认开启客户端预编译(
useServerPrepStmts=false),会直接在本地把?占位符替换成实际参数值再把完整SQL发给服务端,所以哪怕是DDL语句里的占位符也能被正常替换执行,不会报错。 - PostgreSQL JDBC驱动默认使用服务端预编译,会把带
?的SQL原样发给服务端,由服务端解析为$1、$2格式的参数占位符。但PostgreSQL本身不支持在ALTER TABLE这类DDL语句中使用预编译参数,DEFAULT 后面的默认值不接受动态参数绑定,因此服务端解析SQL时识别到非法的$1参数,就抛出了"There is no parameter $1"的报错。
- MySQL JDBC驱动默认开启客户端预编译(
修复方案
不要用PreparedStatement来执行DDL语句,直接把默认值拼接到ALTER TABLE的SQL字符串中即可:
// 调整getQuery方法,直接把defaultValue拼入SQL,字符串类型默认值注意加单引号、转义内部的单引号 String alterSql = getQuery(tableName, this.defaultValue); Statement s = connection.createStatement(); s.executeUpdate(alterSql);
注意:如果默认值是用户可控输入,拼接SQL前要做好特殊字符转义(比如字符串里的单引号要替换成两个单引号),避免SQL注入风险。如果是内部业务逻辑生成的固定默认值,直接拼接即可。
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

