java - JDBC语句执行时如何收集警告/通知?

标签 java postgresql jdbc postgresql-9.4

我在使用最新版本的 PostgreSQL JDBC 驱动程序时遇到问题:当准备好的语句仍在执行时,我无法收集警告/通知。警告列表仅在语句返回后可用。

我在一些以前的驱动程序版本(我猜是 9.1)中使用了这个特性,但是 PgPreparedStatement 的实现可能从那时起已经改变了。

我有哪些选项可以在返回结果之前收集警告?

我创建了这个简单的测试:

public class WarningTest {

    @Test
    public void readWarnings() throws Exception {
        Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test_db", "test_user", "test_password");
        createTestFunction(con);

        PreparedStatement statement = con.prepareStatement("SELECT test_function();");
        SQLWarning[] warnings = new SQLWarning[1];
        new Timer().schedule(new TimerTask() {
            @Override public void run() {
                try {
                    warnings[0] = statement.getWarnings();
                } catch (SQLException e) {
                    Assert.fail("Exception thrown: " + e.getMessage());
                }
            }
        }, 3500);
        statement.executeQuery();
        Thread.sleep(1000);
        statement.close();

        Assert.assertNotNull(warnings[0]);
        Assert.assertFalse(warnings[0].getMessage().isEmpty());
    }

    private void createTestFunction(Connection con) throws SQLException {
        final PreparedStatement statement = con.prepareStatement(
            "CREATE OR REPLACE FUNCTION test_function() RETURNS VOID AS\n"
            + "$BODY$\n"
            + "BEGIN\n"
            + "\tFOR i IN 1..3 LOOP \n"
            + "\t\tRAISE NOTICE 'Tick %', i;\n"
            + "\t\tEXECUTE pg_sleep(1);\n"
            + "\tEND LOOP;\n"
            + "END\n"
            + "$BODY$\n"
            + "\tLANGUAGE plpgsql STABLE;");
        statement.execute();
        statement.close();
    }
}

它创建了一个运行 3 秒的函数,并在每一秒开始时写入一个滴答声。

测试通过,因为计时器在返回结果后启动。但是,如果您将计时器延迟从 3500 减少到 1500,即使到那时数据库已经发出 2 个通知,测试也会失败。

最佳答案

此问题是在 REL9.4.1210 中引入的。 REL9.4.1209 及以下版本按预期工作。

Line 244 of this commit这就是为什么这不再有效的原因,警告之前一收到就直接添加到语句中,但它被重构了,现在它们只有在完成后才可用。

I have raised an issue for this , 以及 PR to address it.

关于java - JDBC语句执行时如何收集警告/通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44721709/

相关文章:

postgresql - 属性无法在 Sequelize Model Create 中正确插入

java - 如何修复错误包 com.mysql 不存在

java - Spring Boot + Flyway + AWS : Caused by: java. sql.SQLException:找不到合适的驱动程序

java - 编译错误,看不懂

python - 我如何在 SQLAlchemy 中查询由 JSON 列过滤的数据?

java - JavaFX 应用程序线程中需要运行的方法列表?

postgresql - 如何在 Postgresql 中创建列常量

java - 从 java 调用存储过程时出错

java - Guice 构造函数注入(inject) String 依赖项(或其他未绑定(bind)的原语)?

java - 如何在Android中保存图像而不压缩?