Java &引用;错误:缓存的计划不能更改结果类型;通过JDBC将DDL与SELECT混合使用时

Java &引用;错误:缓存的计划不能更改结果类型;通过JDBC将DDL与SELECT混合使用时,java,sql,postgresql,jdbc,Java,Sql,Postgresql,Jdbc,我在通过JDBC使用PostgreSQL时遇到了一个有趣的问题(目前还不能在JDBC之外复制它),我得到了一个 “错误:缓存的计划不能更改结果类型” 重现此问题的最简单方法是使用以下代码: Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = Arrays.asList( "create table t(a int)", "select * from t",

我在通过JDBC使用PostgreSQL时遇到了一个有趣的问题(目前还不能在JDBC之外复制它),我得到了一个

“错误:缓存的计划不能更改结果类型”

重现此问题的最简单方法是使用以下代码:

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();
    }

错误:准备的语句“S_1”不存在


有人知道解决方法吗?还是一个记录这个bug的指针?有趣的一点,它似乎与

有关

将其设置为零将解决/解决此特定问题:

 ((PGConnection) connection).setPrepareThreshold(0);

禁用已准备好的语句对于解决此问题来说过于激烈。现在,您可以通过在pgjdbc连接设置上设置
autosave=conservative
来解决特定问题,请参阅:

是否尝试使用其他变量名?也许
f
是某种保留关键字?此外,完整的堆栈跟踪也会很有帮助。@a_horse_和_no_name:是的,但这是真正问题的简化版本,从游戏中删除准备好的语句要少一些easy@aguibert ;) 说得好。我试过了,但是没有。真正的版本在名字周围使用引号…你检查过这个问题吗?看起来像是一个可能的重复:@aguibert:我确实有,而且它不是重复的,至少不是来自公认的答案(OP),该答案声称这些事情同时发生。在我的例子中,所有语句都在一个会话中执行。您也可以通过URL参数来更改:
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();
    }
 ((PGConnection) connection).setPrepareThreshold(0);