【问题标题】:java -postgresql last inserted id on insertion not gettingjava -postgresql 插入时最后插入的 id 没有得到
【发布时间】:2015-10-19 10:45:17
【问题描述】:

我有一个插入postgresql的函数如下:

CREATE OR REPLACE FUNCTION insert_orderhead(order_id integer, order_dt text, customer_id integer, route_id integer, routenum integer, ordertype text, create_station_id integer, create_stationtype text, create_time text, create_user_id integer, tran_time text, tran_user_id integer) RETURNS integer AS $BODY$
INSERT INTO ordermaster
VALUES(DEFAULT,
       order_dt,
       customer_id,
       route_id,
       routenum,
       ordertype,
       create_station_id,
       create_stationtype,
       create_time,
       create_user_id,
       tran_time,
       tran_user_id) returning order_id $BODY$ LANGUAGE SQL VOLATILE COST 100;


ALTER FUNCTION insert_orderhead(integer, text, integer, integer, integer, text, integer, text, text, integer, text, integer) OWNER TO postgres;

我使用java插入,调用如下:

cstorderhead = conn.prepareCall("{call insert_orderhead(?,?)}");
                    cstorderhead.setString(1, order_date);
                    cstorderhead.setInt(2, custidup);
                       .........
                    cstorderhead.executeUpdate();

值被正确插入。

我需要返回最后插入的 id,这里是串行自动增量。

我尝试如下:

ResultSet rstd = cstorderhead.getGeneratedKeys();
                    if (rstd.next()) {
                        int newId = rstd.getInt(1);
                            out.print("Value returned=="+newId);
                    }

但它没有返回最后插入的 id。我需要什么更改才能让我的代码得到它?

这是表定义:

create table ordermaster 
(
  order_id serial NOT NULL, order_dt text, customer_id integer, route_id integer, routenum integer, ordertype text, create_station_id integer, create_stationtype text, create_time text, create_user_id integer, tran_time text, tran_user_id integer, CONSTRAINT order_id PRIMARY KEY (order_id)
);

【问题讨论】:

  • 如果您想从存储过程(或函数)中获取生成的密钥,那么您需要自己从函数中返回它。 JDBC 生成的密钥工具(顺便说一句,需要为语句显式启用)仅适用于普通 DML,并且对于可调用语句未指定
  • 不相关但是:你为什么将date 作为String 传递。日期不应作为字符串值传递也不应存储
  • @a_horse_with_no_name 我的日期是字符串格式 yyyymmdd 是字符串格式,所以这不是问题
  • 将日期作为字符串传递 一个问题。是什么阻止您存储20150231
  • 我说这无关紧要,但在varchar 列中存储日期仍然是一个非常糟糕的主意。

标签: java postgresql jdbc


【解决方案1】:

您不能将getGeneratedKeys()CallableStatement 一起使用。但是,由于您的 insert 在函数中“隐藏”,因此您也不能将常规 PreparedStatementgetGeneratedKeys() 一起使用,因为驱动程序会将 RETURNING 子句附加到 SQL 语句 - 这不适用于一个函数调用。

我看到您的问题有两种解决方案:

1。更改函数返回值:

CREATE OR REPLACE FUNCTION insert_orderhead(
    p_order_id integer, 
    p_order_dt text, 
    p_customer_id integer, 
    p_route_id integer, 
    p_routenum integer, 
    p_ordertype text, 
    p_create_station_id integer, 
    p_create_stationtype text, 
    p_create_time text, 
    p_create_user_id integer, 
    p_tran_time text, 
    p_tran_user_id integer)
  RETURNS integer AS
$BODY$
   INSERT INTO ordermaster 
     (order_dt, customer_id, route_id, routenum, ordertype, create_station_id, create_stationtype, create_time,create_user_id,tran_time, tran_user_id)
   values 
     (p_order_dt, p_customer_id, p_route_id, p_routenum, p_ordertype, p_create_station_id, p_create_stationtype, p_create_time, p_create_user_id, p_tran_time, p_tran_user_id) 
   returning  orderline_id;
$BODY$
  LANGUAGE sql VOLATILE
  COST 100;

请注意,我删除了未使用的 order_id 参数,并重命名了其他两个参数 - 因为参数与列同名通常不是一个好主意。

然后在你的代码中你可以像这样使用函数:

PreparedStatement pstmt = con.prepareStatement("select insert_order(?,?)");
pstmt.setString(1, "foo");
pstmt.setInt(2, 42);

rs = pstmt.executeQuery();

if (rs.next()) {
  System.out.println("Generated ID is: " + rs.getInt(1));
}

2。手动查询序列:

调用你的函数后,你可以运行另一个语句来获取最后生成的序列值:

ResultSet rs = stmt.executeQuery("select lastval()");
if (rs.next()) {
  System.out.println("Generated ID is: " + rs.getInt(1));
}

仅当函数不插入多个表时,上述内容才有效。如果是这样,您需要使用带有序列名称的currval()

ResultSet rs = stmt.executeQuery("select currval('ordermaster.order_id_seq')");
if (rs.next()) {
  System.out.println("Generated ID is: " + rs.getInt(1));
}

【讨论】:

  • 出现错误`您可能需要添加显式类型转换。位置:8添加订单详情时出错`
  • @a_horse_with_no_name 已更新。请检查它的哥们!
  • @a_horse_with_no_name 根据您的建议更新了存储过程,请检查一下哥们。帮帮我:(
  • @Santhucool:我在您的问题中没有看到create table 声明。但是错误消息听起来好像您没有为参数或 setXXX() 调用使用正确的数据类型。
  • @a_horse_with_no_name 请在上方查看!!
猜你喜欢
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多