我正在通过JDBC遇到一个有趣的PostgreSQL问题(无法在JDBC之外再现它)我得到了一个
"错误:缓存计划不得更改结果类型"
重现此问题的最简单方法是使用以下代码:
Connection c = getConnection(); c.setAutoCommit(true); Liststatements = Arrays.asList( "create table t(a int)", "select * from t", "alter table t add b int", "select * from t", "alter table t add c int", "select * from t", "alter table t add d int", "select * from t", "alter table t add e int", "select * from t", "alter table t add f int", "select * from t" ); for (String statement : statements) try (PreparedStatement s = c.prepareStatement(statement)) { System.out.println(s); s.execute(); }
以下代码工作正常的事实导致我假设这是JDBC驱动程序中的一个非常微妙的错误(注意,我只是删除了批处理中的第六个DDL语句):
Connection c = getConnection(); c.setAutoCommit(true); Liststatements = Arrays.asList( "create table t(a int)", "select * from t", "alter table t add b int", "select * from t", "alter table t add c int", "select * from t", "alter table t add d int", "select * from t", "alter table t add e int", "select * from t" ); for (String statement : statements) try (PreparedStatement s = c.prepareStatement(statement)) { System.out.println(s); s.execute(); }
似乎丢弃所有缓存的计划DISCARD ALL
应该可行,但它会使事情变得更糟:
Connection c = getConnection(); c.setAutoCommit(true); Liststatements = Arrays.asList( "create table t(a int)", "select * from t", "alter table t add b int", "select * from t", "alter table t add c int", "select * from t", "alter table t add d int", "select * from t", "alter table t add e int", "select * from t", "alter table t add f int", "discard all", "select * from t" ); for (String statement : statements) try (PreparedStatement s = c.prepareStatement(statement)) { System.out.println(s); s.execute(); }
我正在遇到另一条错误消息
"错误:准备好的声明"S_1"不存在"
有没有人知道解决方法?还是记录这个bug的指针?有趣的是,它似乎与默认的准备阈值5相关
这似乎与PostgreSQL相关PREPARE_THRESHOLD
,对于JDBC驱动程序,默认为5.
将其设置为零将解决/解决此特定问题:
((PGConnection) connection).setPrepareThreshold(0);
此堆栈溢出问题中也提供了更多信息