I’ve been reviewing my notes on FileTables lately. If you’re unfamiliar with FileTables, introduced in SQL Server 2012, you can read up on them here . But briefly they are an update to FILESTREAMING that allows you to store large objects in a hierarchical structure in a database table, and allows you to view the files in a network shared folder. In this particular case I was wondering how easy it would be to move binary data stored in a VARBINARY (MAX) column from a non-filestreamed database into a new FileTable. For my tests I’m using a Developer Edition of SQL Server 2012 installed on a virtual server that’s running Windows 2008 R2. My test instance does not have FILESTREAMING enabled yet. If you’re following along at home you can use any database but I decided to create a new one. I also created a table to store a few pictures. Note that when I created the table I added a column of the type UNIQUEIDENTIFIER with the attribute ROWGUIDCOL and also a column to store the file name. That’s not necessary for just inserting the pictures but it is necessary when I move them to the FileStream table later. I just saved myself a step in adding the columns later. CREATE DATABASE ConversionDB ON PRIMARY ( NAME = 'ConversionDB_data', FILENAME = 'E:\SQL2012\DATA\ConversionDB_data.mdf', SIZE = 512000KB, MAXSIZE = UNLIMITED, FILEGROWTH = 102400KB ) LOG ON ( NAME = 'ConversionDB_log', FILENAME = 'E:\SQL2012\DATA\ConversionDB_log.ldf', SIZE = 102400KB, MAXSIZE = 2048GB FILEGROWTH = 25600KB ); USE ConversionDB; CREATE TABLE dbo.TestConversion ( FileID UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE, [FileName] VARCHAR(20), FileItem VARBINARY (MAX) ); I chose a few pictures I took from my vacation last summer. It’s pretty simple to insert them into the new database. DECLARE @image1 VARBINARY(MAX) DECLARE @image2 VARBINARY(MAX) SELECT @image1 = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET(BULK 'C:\File Table Demo\Photos\SF Sailboat.jpg', SINGLE_BLOB) AS x SELECT @image2 = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET(BULK 'C:\File Table Demo\Photos\Half Dome.jpg', SINGLE_BLOB) AS y INSERT INTO dbo.TestConversion (FileID, [FileName], FileItem) SELECT NEWID(), 'SF Sailboat.jpg', @image1 INSERT INTO dbo.TestConversion (FileID, [FileName], FileItem) SELECT NEWID(), 'Half Dome.jpg', @image2; If I query my new table I’ll see the 2 new records. If I want to actually view the photos in the database I’d need to write a custom app. But I’m lazy, so I’m going to move them into a FileTable. Then I can use Windows Explorer to browse through them. The first step is to enable FILESTREAMING on my instance. I use the SQL Server Configuration Manager for this since I’ll need to restart SQL afterwards and I can do both from here. Since FILESTREAMING is a requirement for FileTables I next need to create a new filegroup to store the FILESTREAM data. I also need to enable the database for access and give it a share name so I can find it on my virtual network. I enabled for full access but I could have also set READ_ONLY. ALTER DATABASE ConversionDB ADD FILEGROUP FSSecondary CONTAINS FILESTREAM; ALTER DATABASE ConversionDB SET FILESTREAM ( DIRECTORY_NAME = 'FSData', NON_TRANSACTED_ACCESS = FULL ); ALTER DATABASE ConversionDB ADD FILE ( Name = FilestreamData, FILENAME = 'E:\SQL2012\ConversionFS\Data' ) TO FILEGROUP FSSecondary; Finally I create a new FileTable using the defaults. After that it’s just a matter of inserting into the FileTable all the records from the old table. CREATE TABLE dbo.Documents AS FILETABLE; INSERT INTO dbo.Documents (name, file_stream) SELECT [FileName], FileItem FROM dbo.TestConversion; And it’s just that easy. Now on my desktop I can map a drive to the shared folder created in the FILESTREAM database on my virtual server. And I can open the photos in any application that can handle jpeg images. Here’s the usual warning. All the code I’m presenting here was only used in a test environment. I make no guarantees that it will work on your production servers. Feel free to use my code but please run your own tests.
↧