Cause: org.postgresql.util.PSQLException: ERROR: cached plan must not change result type

引起该报错的原因,都是应用端在修改了数据库字段,或者增减字段后,没有重启应用导致。

场景重现:

session 1:
hank=> create table test_tbl(id int,name varchar(50));
CREATE TABLE
hank=> insert into test_tbl values (1,'hank'),(2,'jecc'),(3,'jully');
INSERT 0 3
hank=> prepare select_test_tbl (character varying) as select * from test_tbl where name=$1;           
PREPARE
hank=> execute select_test_tbl ('hank');
 id | name 
----+------
  1 | hank
(1 row)

session 2:

hank=> alter table test_tbl add column age int;
ALTER TABLE

回到session 1: 报错
hank=> execute select_test_tbl ('hank');
ERROR:  cached plan must not change result type

这里解释一下,应用使用prepare语句是为了绑定变量,执行计划重用,减少硬解析,提高效率
1、prepared语句只在session的整个生命周期中存在,一旦session结束,Prepared语句也不存在了。如果下次再使用需重新创建。
2、prepared语句不能在多个并发的client中共用,所以要每个client都需要创建自己的prepare语句
3、prepared语句可以通过DEALLOCATE命令清除。
4、当前session的prepared语句:pg_prepared_statements,如下

hank=> select * from pg_prepared_statements ;
-[ RECORD 1 ]---+-------------------------------------------------------------------------------------
name            | select_test_tbl
statement       | prepare select_test_tbl (character varying) as select * from test_tbl where name=$1;
prepare_time    | 2019-09-25 15:34:53.238815+08
parameter_types | {"character varying"}
from_sql        | t

通过以上prepare使用的限制,可以得出解决办法有两种,一种不断开session,另一种断开session重连,或者重启应用

第一种,重新创建prepare语句
hank=> deallocate select_test_tbl ;
DEALLOCATE
hank=> execute select_test_tbl ('hank');
ERROR:  prepared statement "select_test_tbl" does not exist
hank=> prepare select_test_tbl (character varying) as select * from test_tbl where name=$1;
PREPARE
hank=>  execute select_test_tbl ('hank');
 id | name | age 
----+------+-----
  1 | hank |    
(1 row)

你可能感兴趣的:(#,postgreSQL)