Working with SQL Server 2008 Date/Time Data Types using v1.2 JDBC driver

Since SQL Server 2008 release over the summer, people have been asking, "So, does the existing JDBC driver work with SQL Server 2008?" or "When will there be a SQL Server 2008 JDBC driver?".

There are many things to consider with a general questions like these.  What features of SQL Server 2008 are you truly looking forward to leveraging and can the features be used through existing drivers?

Today, I like to let people know that the existing v1.2 JDBC driver works with SQL Server 2008 as a downlevel client.  This means that you will be able to connect to a SQL Server 2008 instance and execute queries/updates on majority of the SQL Server 2008 data types.

This is post, I will focus on how you can retrieve the new Date/Time/Datetime2/DatetimeOffset data types introduced in SQL Server 2008 with existing v1.2 driver.

The first question you may ask, "So what is the metadata type of these new data types?"
To ensure full data fidelity, SQL Server 2008 has chosen to return the values for these data type columns as "nvarchar".  This means that all older SQL Server clients can operate on these new data types as String and it is up to the application layer to parser and understand these String values.  The v1.2 driver is no different.

To demostrate how the v1.2 driver can retrieve a resultset containing these data types, I have created a table containing 4 columns (one for each type) and populated the table with some sample data.

Here is the T-SQL script that I used to create my table:

CREATE TABLE bar
(
    [Date] date,
    [Time] time,
    [StartDate] datetime2,
    [HireDate] datetimeoffset
)
go

insert bar values
(
  '2008-01-01',
  '13:59:00.1234567',
  '2008-02-02T20:01:59.123456789',
  '2008-04-01T10:05:02+08:00'
)
go

Here is the code snippet that I used to retrieve the column values:

 String strCmd = "select * from bar";
 ResultSet rs = stmt.executeQuery(strCmd);
 if (rs.next())
 {
  ResultSetMetaData rsmd = rs.getMetaData();
  if (null != rsmd)
  {
   int count = rsmd.getColumnCount();
   for (int i = 1; i <= count; i++)
   {
    System.out.println("");
    String nameType = rsmd.getColumnTypeName(i);
    String name = rsmd.getColumnName(i);
    System.out.println("Column " + name + " is data type: " + nameType);
    String str = rs.getString(i);
    System.out.println("Column " + name + ": " + str);
   }

   Date dt = rs.getDate(1);
   System.out.println("Column 1 has value: " + dt.toString());

   Time t = rs.getTime(2);
   System.out.println("Column 2 has value: " + t.toString());

   Timestamp ts = rs.getTimestamp(3);
   System.out.println("Column 3 has value: " + ts.toString());
  }
 }
 rs.close();
 stmt.close();   

The output looks like:

Column Date is data type: nvarchar
Column Date: 2008-01-01

Column Time is data type: nvarchar
Column Time: 13:59:00.1234567

Column StartDate is data type: nvarchar
Column StartDate: 2008-02-02 20:01:59.1234568

Column HireDate is data type: nvarchar
Column HireDate: 2008-04-01 10:05:02.0000000 +08:00
Column 1 has value: 2008-01-01
Column 2 has value: 13:59:00
Column 3 has value: 2008-02-02 20:01:59.1234568

Note: For the DatetimeOffset column, the v1.2 JDBC driver is unable to automatically create a Timestamp object from the String, through rs.getTimestamp() due to the Timestamp class not supporting time zone information.  To leverage the Calendar or GregorianCalendar classes which do support time zone, the application will need to parse the string in order to create the Calendar object.

Jimmy Wu
SQL Server JDBC Team