我有一个插入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)
);
答案 0 :(得分:4)
您不能将getGeneratedKeys()
与CallableStatement
一起使用。但是,因为insert
已隐藏"在函数中,您也不能使用常规PreparedStatement
和getGeneratedKeys()
,因为驱动程序会在SQL语句中附加RETURNING
子句 - 它不能与之一起使用一个函数调用。
我看到了两个问题的解决方案:
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));
}
调用函数后,可以运行另一个语句来获取最后生成的序列值:
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));
}