PHP中含INSERT ON CONFLICT与几何类型的Postgres参数化查询报错:参数$2类型不一致
PHP中含INSERT ON CONFLICT与几何类型的Postgres参数化查询报错:参数$2类型不一致
这个问题我之前排查过类似的,核心原因是PostgreSQL对同一个参数的类型推断出现了冲突,咱们一步步拆解来看:
错误根源
你在查询里多次使用了$2和$3这两个参数:
- 一次是插入到
numeric类型的latitude/longitude列 - 另一次是作为
ST_MakePoint的参数,而PostGIS的ST_MakePoint默认期望接收double precision(也就是float8)类型的数值
PostgreSQL在解析参数化查询时,会尝试为每个参数推导一个统一的类型,但这里$2同时被要求是numeric和double precision,两种类型无法统一,就抛出了inconsistent types deduced for parameter $2的错误。
解决办法
最简单的方式是在查询中对参数做显式类型转换,让同一个参数在所有场景下的类型一致。这里有两种可行的方向:
方案1:把几何函数的参数转成numeric(和列类型匹配)
修改你的INSERT语句,在ST_MakePoint中显式将参数转为numeric:
pg_query_params($connection, " INSERT INTO test_table5 ( unique_id , latitude , longitude , coordinates ) VALUES ( $1 , $2 , $3 , ST_SetSRID(ST_MakePoint( CAST($3 AS numeric), CAST($2 AS numeric) ), 4326) ) ON CONFLICT (unique_id) DO UPDATE SET latitude = $2 , longitude = $3 , coordinates = ST_SetSRID(ST_MakePoint( CAST($3 AS numeric), CAST($2 AS numeric) ), 4326)", [ 50113947, 35.76673, -78.36914 ]);
方案2:把列赋值的参数转成double precision(和几何函数期望的类型匹配)
如果更倾向于用double precision适配几何函数,也可以在插入和更新列时显式转换参数:
pg_query_params($connection, " INSERT INTO test_table5 ( unique_id , latitude , longitude , coordinates ) VALUES ( $1 , CAST($2 AS numeric) , CAST($3 AS numeric) , ST_SetSRID(ST_MakePoint( $3, $2), 4326) ) ON CONFLICT (unique_id) DO UPDATE SET latitude = CAST($2 AS numeric) , longitude = CAST($3 AS numeric) , coordinates = ST_SetSRID(ST_MakePoint( $3, $2), 4326)", [ 50113947, 35.76673, -78.36914 ]);
额外说明
其实PostgreSQL本身支持numeric和double precision之间的隐式转换,但在参数化查询的全局类型推导场景下,它不会自动做这个转换——因为它需要确定每个参数的唯一类型,避免歧义。显式转换相当于给数据库明确的指令,消除这种类型冲突。
备注:内容来源于stack exchange,提问作者developer981
相关产品推荐
相关产品推荐

