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

从JDBC调用的PostgresQL存储过程不起作用

赫连子石
2023-03-14

我有一个带有一些表的postgresql数据库和一个在这个表上写的存储过程。当我从psql调用这个存储过程时,一切都很顺利:我看到我的记录插入了我的表中。虽然,当我通过JDBC调用这个存储过程时,我得到了存储过程执行的日志,序列是递增的,但是我的表没有更新。

以下是我在新安装的postgresql(9.5.1)中执行的SQL:

表格创建:

CREATE SEQUENCE atable_id_seq;
   CREATE TABLE IF NOT EXISTS "atable" (
   "id" int NOT NULL DEFAULT NEXTVAL('atable_id_seq'),
   "name" varchar(250) DEFAULT NULL,
   PRIMARY KEY ("id")
);

存储过程的创建:

CREATE OR REPLACE FUNCTION awrite(IN name character varying, OUT result character varying) AS
$$
BEGIN
            INSERT INTO atable(name) VALUES (name)
                    RETURNING atable.id INTO awrite.result;
                    RAISE INFO 'Create awrite: %', name;
END
$$
LANGUAGE plpgsql;

psql调用awrites存储过程实际上会触发postgres中的日志并更新表。

然后我写了一个java程序来调用相同的存储过程:

HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("org.postgresql.Driver");
hikariConfig.setJdbcUrl("jdbc:postgresql://127.0.0.1:5432/toto?charSet=UNICODE");
hikariConfig.setUsername("toto");

hikariConfig.setAutoCommit(false);
hikariConfig.setMinimumIdle(0);
hikariConfig.setMaximumPoolSize(2);

JdbcTemplate jdbcTemplate =
        new JdbcTemplate(new HikariDataSource(hikariConfig));

SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate).withProcedureName("awrite");

HashMap<String, Object> params = new HashMap<String, Object>();
params.put("name", "Foo");

call.addDeclaredParameter(new SqlOutParameter("result", Types.VARCHAR));

Map<String, Object> result = call.execute(params);
jdbcTemplate.execute("COMMIT;");

System.out.println("Result: ");
for (String s : result.keySet()) {
    System.out.println(s + ": " + result.get(s));
}

我得到了一个ID,执行顺利。但是我的表不包含记录。

我不明白,也许有人能帮我?

共有1个答案

劳韬
2023-03-14

我认为您的问题是,您正在将JDBC自动提交标志设置为false,但您没有使用JDBC事务。您需要在JDBC事务中运行自己的调用(最简单的方法是将代码放入方法中,并用@Transactional注释该方法,或者使用TransactionTemplate以编程方式启动并提交JDBC事务)。像你这样叫“promise”是行不通的。

 类似资料:
  • 主要内容:创建CallableStatement对象,关闭CallableStatement对象,JDBC SQL转义语法在讨论JDBC Statement教程文章时,我们已经学习了如何在JDBC中使用存储过程。 本教程文章与该部分类似,但它将讲解演示有关JDBC SQL转义语法的其他信息。 就像对象创建和对象一样,它可使用同样的方式创建对象,该对象将用于执行对数据库存储过程的调用。 创建CallableStatement对象 假设需要执行以下Oracle存储过程 - 注意:上面的存储过程是为O

  • 我创建了一个存储过程,如下所示: //mysql中的存储过程 并且我正在调用Java中的存储过程,如下所示: //使用JDBC调用存储过程 但它显示了一个编译时异常,如下所示: CAN在参数中为存储的函数调用的返回值设置。

  • 我有一个简单的存储过程,在我创建的表上执行。当我使用硬编码参数单独执行update语句时,它可以工作,但过程在执行时不会更新。它返回一个“命令已成功完成”,但不影响任何行。我检查了数据,数据也没有变化。

  • 我有一个非常复杂的oracle存储过程,它搜索和检索一些数据。该过程返回一个输出参数-oracle游标。我通过JDBC执行过程: 问题是,查询有时会花费相当长的时间(几分钟),我希望用户能够通过单击按钮随时取消查询。我引用了stmt对象,但不幸的是(从其他线程)调用stmt.cancel()没有效果。 另一方面,当我将CallableStatement sql更改为以下查询时: 在调用stmt.c

  • 我得到了这样的错误{“code”:“er_parse_error”,“errno”:1064,“sqlmessage”:“您的SQL语法中有错误;请查看与您的MySQL服务器版本相对应的手册,以便在第1行'sp_li_uploaddata_get'附近使用正确的语法”,“sqlstate”:“42000”,“index”:0,“SQL”:“sp_li_uploaddata_get”}

  • 问题内容: Spring JDBC模板调用存储过程的正确方法是什么? 说,我有一个同时声明和参数的存储过程,如下所示: 我遇到了一些基于方法,我们必须显式地注册和参数化。在课堂上考虑以下方法: 当然,我知道我可以这样使用它: 我已经在实现中注册它们的目的是什么?换句话说,为什么我需要传递一个csc春天可以简单地在内部完成的事情?基本上,我不能传递其中一个而不是两个吗? 或者,是否有比我到目前为止遇