“ERROR: cached plan must not change result type” when mixing DDL with SELECT via JDBC
我在JDBC上遇到了一个与PostgreSQL有关的有趣问题(暂时无法在JDBC之外重现它),
"ERROR: cached plan must not change result type"
重现此问题的最简单方法是使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = 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语句):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = 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(); } |
似乎可以通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = 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(); } |
我遇到另一个错误消息
"ERROR: prepared statement"S_1" doesn't exist"
有谁知道解决方法? 还是记录此错误的指针? 有趣的是,它似乎与默认的准备阈值5有关
这似乎与PostgreSQL的
将其设置为零将解决/解决此特定问题:
1 | ((PGConnection) connection).setPrepareThreshold(0); |
此堆栈溢出问题中也提供了更多信息
禁用准备好的语句对于解决此问题来说太过严厉了。 现在,您可以通过在pgjdbc连接设置上设置