作者
digoal
日期
2019-04-17
标签
PostgreSQL , cached plan must not change result type , prepared statement , 绑定变量
背景
PostgreSQL的优化器是非常复杂的,和Oracle属于一个量级,所以如果是OLTP系统,建议使用绑定变量,减少sql parser, plan的开销。
在使用绑定变量时,可能会遇到这样的问题,当结构发生变化时,如果绑定变量的SQL结果依赖这个结构,那么会报类似错误:
ERROR: 0A000: cached plan must not change result type
LOCATION: RevalidateCachedQuery, plancache.c:745
原因是绑定变量对应SQL的结果与当前结构下对应的结果不一致。
例子:
```
postgres=# create table tc (id int ,c1 int);
CREATE TABLE
postgres=# insert into tc values (1,1);
postgres=# prepare x (int) as select * from tc where id=$1;
PREPARE
postgres=# \set VERBOSITY verbose
postgres=# execute x(1);
id | c1
----+----
1 | 1
(1 row)
postgres=# alter table tc add column c2 int;
ALTER TABLE
postgres=# execute x(1);
ERROR: 0A000: cached plan must not change result type
LOCATION: RevalidateCachedQuery, plancache.c:745
```
解法
discard all后,重新绑定即可。
```
postgres=# discard all;
DISCARD ALL
postgres=# execute x(1);
ERROR: 26000: prepared statement "x" does not exist
LOCATION: FetchPreparedStatement, prepare.c:535
postgres=# prepare x (int) as select * from tc where id=$1;
PREPARE
postgres=# execute x(1);
id | c1 | c2
----+----+----
1 | 1 |
(1 row)
```
参考
https://www.postgresql.org/docs/11/sql-prepare.html
https://www.postgresql.org/docs/11/libpq-async.html
PostgreSQL 许愿链接
您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.
9.9元购买3个月阿里云RDS PostgreSQL实例
PostgreSQL 解决方案集合
德哥 / digoal's github - 公益是一辈子的事.





