How does one insert timestampz's into postgres using spring jdbc - spring

I have a table in postgres called retailPrices that has a column of type timestampz. I can insert a timestamp into it using the shell and programmatically using jdbc by concatenating it into a query and passing it into jdbc.update(). However I've been enlightened to the better way of running statements through jdbc which is through the use of the varargs overload as shown below.
ZonedDateTime ts = ZonedDateTime.now();
String tsFormatted = ts.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
String insertRetailPrice = "insert into retailprices values (?, ?, TIMESTAMP WITH TIME ZONE ?);";
int retailPriceAffectedRows = jdbcTemplate.update(insertRetailPrice, SKU, price, tsFormatted);
However I keep getting runtime exceptions when specifically trying to insert timestampz's. I've tried it with and without the prefix "TIMESTAMP WITH TIME ZONE" with both the ZonedDateTime, ts, and the string, tsFormatted, with no avail.

Related

Cassandra + SpringBoot: Configure Table to automatically add INSERT timestamp

Small question regarding Cassandra, with the context of a SpringBoot application please.
I am interested in adding onto the table the timestamp of when a row gets inserted onto the table.
Therefore, when creating the table, I do this:
create table mytable (someprimarykey text PRIMARY KEY, timestamp long, someotherfield text);
I can see a column timestamp, happy.
Then, the web application:
#Table
public class MyTable {
#PrimaryKey
private final String somePrimaryKey;
private final long timestamp;
private final String someOtherField;
//constructor + getters + setters
And when I insert, I will do the usual:
MyTable myTable = new MyTable(somePK, System.currentTimeMillis(), "foo");
myTableRepository.save(myTable);
This works fine, I can see in the table my record, with the time of the insert, happy.
Problem:
Now, for the hundreds of POJOs I am interested to insert into Cassandra, all of them are carrying this timestamp long field. Somehow, on the web application layer, I am dealing with a database concept, the timestamp of the write.
Question:
May I ask if it is possible to delegate this back to the database? Some kind of:
create table mytable (someprimarykey text PRIMARY KEY, hey-cassandra-please-automatically-add-the-time-when-this-row-is-written long, someotherfield text);
or
create table mytable (someprimarykey text PRIMARY KEY, someotherfield text WITH default timestamp-insert-time-column);
And the web app can have the abstraction creating and inserting POJOs without carrying this timestamp field?
Thank you
It isn't necessary to store the insert time of each row separately since Cassandra already stores this for all writes in the metadata.
There is a built-in CQL function WRITETIME() which returns the date/time (encoded in microseconds) when a column was written to the database.
In your case, you can query your table with:
SELECT WRITETIME(someotherfield) FROM mytable WHERE someprimarykey = ?
For details, see the CQL doc on retrieving the write time. Cheers!

jdbcTemplate - queryForList - Invalid Column Type Error

The table name will be dynamic and need to return the list of objects dynamically. The parameters also dynamic however 4 parameters will be same for any table.
Method name accepts the table name and 4 parameters required to query any table
List<?> conversations = jdbcTemplate.queryForList(
"select * from "+ tableName + " where id=? and userName=? and
password=? and tenantId=?" , paramsObjectArray);
tableName is a string which comes dynamically
paramsObjectArray is a Object[] which comes dynamically
Currently the query throws invalid column type.
Thanks.
Your paramsObjectArray contains wrong values. It should correspond with the ? in order declared in your SQL.
It will bind for each ? the correct value.
Now if one of the values in your paramsObjectArray is not what's expected, it will fail.
It could be that id in your db is integer, but you are giving it a String or tenantId - should be an integer I guess, but you are giving String.
Read the docs first.

ExecuteSQL doesn't select table if it having dateTime Offset value?

I have created table with single column having data type -dateTimeOffset value and inserted some values.
create table dto (dto datetimeoffset(7))
insert into dto values (GETDATE()) -- inserts date and time with 0 offset
insert into dto values (SYSDATETIMEOFFSET()) -- current date time and offset
insert into dto values ('20131114 08:54:00 +10:00') -- manual way
In Nifi,i have specified "Select * from dto" query in Execute SQL .
It shows below error..,
java.lang.IllegalArgumentException: createSchema: Unknown SQL type -155 cannot be converted to Avro type
If i change that column into dateTime then ExecuteSQL runs correctly but it doesn't worked in DateTimeOffset column.
Any help appreciated.
Many thanks
datetimeoffset is a MSSQL-specific JDBC type and is not supported by ExecuteSQL (which supports the standard JDBC types). You could try to cast the datetimeoffset field into some other standard type such as datetime, as described here.
I've created a Custom Processor and adapted the JdbcCommon.java class to include SQL Server's DATETIMEOFFSET. It's just one line of code. I'll try to see if I can ask them to merge this on the official repo.
This is a piece of my JdbcCommon.java:
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
case -101: // Oracle's TIMESTAMP WITH TIME ZONE
case -102: // Oracle's TIMESTAMP WITH LOCAL TIME ZONE
case -155: // SQL Server's DATETIMEOFFSET <---- added this line
addNullableField(builder, columnName,
u -> options.useLogicalTypes
? u.type(LogicalTypes.timestampMillis().addToSchema(SchemaBuilder.builder().longType()))
: u.stringType());
break;

How to use CURRENT_TIMESTAMP in JDBC (Oracle DB)

In MY_TABLE, when ORD_AMT field is updated then LST_UPDT_TS is updated with current_timestamp too. Presented by following query:
UPDATE MY_TABLE
SET ORD_AMT = 50, LST_UPDT_TS = CURRENT_TIMESTAMP
WHERE ORD_ID = 'ORD_123'
I need implement this business by JDBC code, and my Web server and DB server are difference timezone. If I pass Date().getTime() to JDBC, it's the current of Web server but I need the current time of DB server.
Is there a way for passing CURRENT_TIMESTAMP like this:
preparedStatement = dbConnection.prepareStatement(updateOrderSql);
preparedStatement.setFloat(1, 50);
preparedStatement.setTimestamp(2, Timestamp.CURRENT_TIMESTAMP);
preparedStatement.setString(3, 'ORD_123');
preparedStatement.executeUpdate();
Thanks for your help.
Instead of passing the current timestamp parameter to oracle, you can make use of SYSTIMESTAMP like below
UPDATE MY_TABLE
SET ORD_AMT = 50, LST_UPDT_TS = SYSTIMESTAMP
WHERE ORD_ID = 'ORD_123'
ultimately both might be same if FRONT END server and DB server are in same machine, i mean single tier architecture. If not you can type cast it to string and store the same in table with varchar2 datatype.
To update LST_UPDT_TS field with JDBC use the following code:
preparedStatement.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
And you'll see in DB updated LST_UPDT_TS field.

How to insert Current time in TIMESTAMP column(Oracle) from java class using jdbc

i have tryed many things but not able to insert data in my timestamp column.
from toad its possible using this
UPDATE SUPPORTSTAFF
SET SUPPSTAFFJOINDATE=to_timestamp('27/02/2002 15:51.12.539880', 'dd/mm/yyyy hh24:mi.ss.ff')
where JDBCUSERID='5700';
its working
but how can i insert data from java class using create statment and execute query its giving me invalid month error
Use a PreparedStatement with a parameter for the timestamp, e.g.
UPDATE SUPPORTSTAFF SET SUPPSTAFFJOINDATE = ? where JDBCUSERID = ?
and then set the parameters:
statement.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
statement.setString(2, "your ID");
(Then execute the statement, obviously.)

Resources