当前位置: 首页 > 知识库问答 >
问题:

通过JDBC将DDL与SELECT混合时出现“错误:缓存的计划不得更改结果类型”

殷学
2023-03-14

我在通过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();
    }

以下代码工作正常这一事实使我认为这是JDBC驱动程序中的一个非常微妙的错误(注意,我只是删除了批处理中的第六条DDL语句):

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

通过DISCARD all放弃所有缓存的计划似乎可以工作,但这会让事情变得更糟:

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

我遇到另一条错误消息

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

有人知道变通方法吗?还是记录这个错误的指针?有趣的一点,这似乎与5的默认准备阈值有关

共有2个答案

陶沛
2023-03-14

禁用准备好的语句对于解决此问题来说是一个过于激烈的操作。您现在可以通过在pgjdbc连接设置上设置autosave=conservative来解决特定问题,请参阅:https://stackoverflow.com/a/48536394/924597

文华美
2023-03-14

这似乎与PostgreSQL的PREPARE_THRESHOLD有关,JDBC驱动程序的默认值为5。

将其设置为零将解决/解决这个特殊问题:

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

更多信息也可在此堆栈溢出问题

 类似资料:
  • 问题内容: 我在JDBC上遇到了一个与PostgreSQL有关的有趣问题(暂时无法在JDBC之外重现它), “错误:缓存的计划不得更改结果类型” 重现此问题的最简单方法是使用以下代码: 以下代码可以正常工作的事实使我假设这是JDBC驱动程序中的一个非常微妙的错误(请注意,我只是在批处理中删除了第六条DDL语句): 似乎可以通过丢弃所有缓存的计划,但这会使情况变得更糟: 我遇到另一个错误消息 “错误

  • 问题内容: 我在PostgreSQL上通过JDBC遇到了一个有趣的问题(目前还无法在JDBC之外重现), ``RROR:缓存的计划不得更改结果类型’‘。 重现此问题的最简单方法是使用以下代码: 以下代码可以正常工作的事实使我假设这是JDBC驱动程序中的一个非常微妙的错误(请注意,我只是在批处理中删除了第六条DDL语句): 似乎可以通过丢弃所有缓存的计划,但这会使情况变得更糟: 我遇到另一个错误消息

  • 我真的需要帮助,我在stackoverflow上找到的所有问题中都搜索到了,但没有任何效果。我以前从未使用过hibernate,我不知道自己做错了什么 这是我的存储库:https://github.com/ionutincau/test_db 我收到了这个错误:

  • 我在使用以下方言创建表时遇到以下错误 “org.hibernate.dialoget.mysqlinoddDialogic”

  • 问题内容: 我真的需要帮助,我在关于stackoverflow的所有问题中进行了搜索,但没有任何效果。我以前从未使用过hibernate模式,也不知道自己在做什么错。 这是我的存储库:https : //github.com/ionutincau/test_db 我收到此错误: 问题答案: 在您的CFG文件中,请更改hibernate方言

  • 我的环境是: Spring Boot+Mybatis+Oracle 10g+JDK1.8 我在oracle中得到了一个名为book的表,如下所示: 我用我编写的映射器使它工作并成功地显示了它。但是当我用plsql在这个表中插入了2条记录后,当我用mybatis映射器查询它时,我仍然得到了相同的3条记录,而不是所有的5条记录(如下所示)。 映射器 实体