sql >> Database teknologi >  >> RDS >> PostgreSQL

java -postgresql sidst indsatte id ved indsættelse får ikke

Du kan ikke bruge getGeneratedKeys() med en CallableStatement . Men som din insert er "skjult" i funktionen, kan du heller ikke bruge en almindelig PreparedStatement med getGeneratedKeys() fordi driveren tilføjer en RETURNING klausul til SQL-sætningen - som ikke virker med et funktionskald.

Jeg ser to løsninger på dit problem:

1. Skift funktionen for at returnere værdien:

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;

Bemærk, at jeg fjernede det ubrugte order_id parameter og omdøbt de to andre parametre - fordi det normalt ikke er en god idé at have parametre med samme navn som kolonner.

Så i din kode kan du bruge funktionen sådan her:

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. Forespørg sekvensen manuelt:

Efter at have kaldt din funktion, kan du køre en anden sætning for at få den sidst genererede sekvensværdi:

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

Ovenstående fungerer kun, hvis funktionen ikke indsættes i flere tabeller. Hvis det gør det, skal du bruge currval() med sekvensnavnet:

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



  1. Udførelse af flere indbyggede forespørgsler på én gang

  2. 'NOT LIKE' i en SQL-forespørgsel

  3. Idempotente PostgreSQL DDL-scripts

  4. Mysql betinget optælling