Oracle - update record and return updated date in

2020-04-20 21:39发布

问题:

I'm using Java 8 with Spring's JdbcTemplate and Oracle 12.1,

I want to update record and get the exact time record was updated

jdbcTemplate.update(UPDATE_SQL, null);

Currently it returns (int) the number of rows affected, but I want the exact updated date

Must I send a new request to get current time which may be inaccurate?

More exact will be to save in column updated date, but then to execute another SQL

Is there another option to get updated date in one query?

Obviously, I don't want to use get date from code also (as new Date()) also because server time is/can be different than DB Time

回答1:

You decided to use JDBCTemplate most probably to simplify the code in comparison to plain JDBC.

This particular problem IMHO makes the plain JDBC solution as proposed in other answer much simpler, so I'd definitively recommend to get the database connection from JDBCTemplate and make the insert in a JDBC way.

The simplest solution using JDBCTemplate that comes to my mind is to wrap the insert in a PROCEDURE and return the timestamp as an OUT parameter.

Simple example (Adjust the time logik as required)

create procedure insert_with_return_time (p_str VARCHAR2, p_time OUT DATE) as
BEGIN 
   insert into identity_pk(pad) values(p_str);
   p_time := sysdate;
END;
/

The call is done using SimpleJdbcCall

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("insert_with_return_time");
SqlParameterSource params = new MapSqlParameterSource().addValue("p_str", str);
Map<String, Object> out = jdbcCall.execute(params);

The Map contains the returned value e.g. [P_TIME:2019-10-19 11:58:10.0]

But I can only repeat, in this particular use case is IMHO JDBC a rescue from JDBCTemplate;)



回答2:

You're right that passing new Date() would store the server time rather than the DB time.

To store the DB time you can set your timestamp to the DB system timestamp systimestamp then you could run a query to retrieve that row and its updated timestamp.

If you want to update the row and get the updated timestamp in a single execution then you could do the following using RETURNING INTO where TimestampUpdated is your column name:

Connection con = ...;
String sql = "UPDATE TableName SET <updates> , TimestampUpdated = systimestamp RETURNING TimestampUpdated INTO ?";
CallableStatement statement = con.prepareCall(sql);
statement.registerOutParameter(1, Types.TIMESTAMP);

int updateCount = statement.executeUpdate();
Timestamp timestampUpdated  = statement.getInt(1);
System.out.println("Timestamp Updated = " + timestampUpdated);

Here is a related link doing this with JdbcTemplate