当前位置:  开发笔记 > 编程语言 > 正文

将DDL与SELECT混合使用时,"错误:缓存计划不得更改结果类型"

如何解决《将DDL与SELECT混合使用时,"错误:缓存计划不得更改结果类型"》经验,为你挑选了1个好方法。

我正在通过JDBC遇到一个有趣的PostgreSQL问题(无法在JDBC之外再现它)我得到了一个

"错误:缓存计划不得更改结果类型"

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

Connection c = getConnection();
c.setAutoCommit(true);
List 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 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 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"不存在"

有没有人知道解决方法?还是记录这个bug的指针?有趣的是,它似乎与默认的准备阈值5相关



1> Lukas Eder..:

这似乎与PostgreSQL相关PREPARE_THRESHOLD,对于JDBC驱动程序,默认为5.

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

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

此堆栈溢出问题中也提供了更多信息

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有