1

How do I pass an array of timestamps to the Postgres function using Java and JDBC?

Here's the signature of the function:

CREATE OR REPLACE FUNCTION getlistcount(_id integer, _subs text, _download_array timestamp without time zone[], _filter integer, _fault text) RETURNS refcursor AS...

Here is the Java code that creates the array:

GregorianCalendar[] dataDownloads = 
        downloadTimes.toArray(new GregorianCalendar[downloadTimes.size()]);

Array sqlArray = conn.createArrayOf("timestamp", dataDownloads);
cstmt.setArray(4, sqlArray);

The downloadTimes are List passed into the Java function.

One hint: we need to concatenate the time with the date, according to the Postgres documentation.

2
  • 1
    I see that you're using TIMESTAMP WITHOUT TIME ZONE. In almost every use case, TIMESTAMP WITH TIME ZONE is better; it represents an actual moment in time, while the other does not. Commented May 11, 2012 at 17:50
  • @KGrittn, that makes sense. We're getting the timezone from the download-time (see below), save the timezone with the timestamp. Thank you! Commented May 11, 2012 at 20:13

2 Answers 2

2

I found an answer on StackOverflow that is similar, but uses the PreparedStatement rather than the JDBC notation.

//Get timezone from first entry, assuming all same timezone
if(!downloadTimes.isEmpty()) {
    cal.setTimeZone(downloadTimes.get(0).getTimeZone());
}

//Create an array of timestamps
java.sql.Timestamp [] array = new java.sql.Timestamp [downloadTimes.size()];

for(int i=0; i < array.length; i++) {
    array[i] = new java.sql.Timestamp(downloadTimes.get(i).getTimeInMillis());
} 

//pass the array to JDBC call
//conn is the connection, and cstmt is the CallableStatement
Array sqlArray = conn.createArrayOf("timestamp", array);
cstmt.setArray(4, sqlArray);
1

The array doesn't have to be of the old java.sql.Timestamp class, you can use java.time classes instead.

Like this

LocalDateTime[] localTimes = new LocalDateTime[]{LocalDateTime.now()};
Array sqlArray = conn.createArrayOf("timestamp", localTimes);
cstmt.setArray(4, sqlArray);

For timestamp with zone use java.time.OffsetDateTime

2
  • 1
    Thanks for updating with fresher code, @david-lilljegren. Yes, that's the best-practice for the timestamp with timezone. Commented Dec 4, 2019 at 19:11
  • Postgres JDBC driver erases the timezone information, if one passes the type timestamp to the createArrayOf method. Using the type timestamptz will fix this problem. Commented Oct 10, 2021 at 5:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.