Working with SQL Server 2008 Filestream using v1.2 JDBC driver

In the previous post "Working with SQL Server 2008 Date/Time Data Types using v1.2 JDBC driver",I talked about how the current JDBC driver can interop with the new Date/Time/DateTime2/DatetimeOffset data types.  This time around, I will describe how to interop with SQL Server 2008 Filestream.

Please refer to "SQL Server 2008 Books Online" for detailed information about Filestream.

To demostrate how the v1.2 driver can retrieve a resultset containing a filestream column, I used the following T-SQL query to create the test database and table:

CREATE DATABASE Archive
ON
PRIMARY ( NAME = Arch1,
    FILENAME = 'c:\data\archdat1.mdf'),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME = Arch3,
    FILENAME = 'c:\data\filestream1')
LOG ON  ( NAME = Archlog1,
    FILENAME = 'c:\data\archlog1.ldf')
GO

CREATE TABLE foo
(
   id int NOT NULL PRIMARY KEY,
   Photo varbinary(max) FILESTREAM NULL,
   MyRowGuidColumn uniqueidentifier NOT NULL ROWGUIDCOL
   UNIQUE DEFAULT NEWID()
)
GO

Let's assume that the table has already been populated with some data.  Here is the code snippet that I used to retrieve the column values:

strCmd = "select * from foo";
rs = stmt.executeQuery(strCmd);
if (rs.next())
{
    ResultSetMetaData rsmd = rs.getMetaData();
    if (null != rsmd)
    {
        String x = rsmd.getColumnTypeName(2);
        String name = rsmd.getColumnName(2);
        System.out.println("Column " + name + " is data type: " + x);
        int i = rsmd.getColumnType(2);
        switch (i)
        {
        case (java.sql.Types.LONGVARBINARY):
            System.out.println("Column is of JDBC type LONGVARBINARY.");
            InputStream bStream = rs.getBinaryStream(2);
            byte[] y = new byte[1024];
            if (null != bStream)
            {
                // write the retrieved filestream data as a file.
                System.out.println("Write the filestream data out as a file.");
                FileOutputStream fs = new FileOutputStream("c:\\myFile");
                int read = bStream.read(y);
                while (read != -1)
                {
                     fs.write(y);
                     fs.flush();
                     read = bStream.read(y);
                }
                fs.close();
            }
            break;
        default:
            throw new Exception("Unexpected data type found: " + String.valueOf(i) + ". Expected LONGVARBINARY.");
        }
    }

    // now, update the data with a new file content.
    System.out.print("Now, let's update the filestream data.");
    FileInputStream iStream = new FileInputStream("c:\\testFile.xml");
    rs.updateBinaryStream(2, iStream, -1);
    rs.updateRow();
    iStream.close();
}
rs.close();

When executed as a console application, you'll get the following output:

Column Photo is data type: varbinary
Column is of JDBC type LONGVARBINARY.
Write the filestream data out as a file.
Now, let's update the filestream data.

As you've probably already noticed, SQL Server 2008 Filestream is simply a LONGVARBINARY to the v1.2 JDBC driver.  This means you can operate on a Filestream like any other LONGVARBINARY, though I recommend that you stick with binaryStream to minize the amount of buffering the driver has to do.

Jimmy Wu
SQL Server JDBC Team