Using SQL Server 2012 FileTables

SQL Server 2012 allows you to store file/directories in a special table called FileTable that builds on top of SQL Server FILESTREAM technology. As per Microsoft BOL, “FileTable lets an application integrate its storage and data management components, and provides integrated SQL Server services – including full-text search and semantic search – over unstructured data and metadata.”

FileTable has a fixed schema and each row of this table represents a file or a directory. The main advantage of FileTable is that it supports Win32APIs for file or directory management which mean we can access file and directory hierarchy through a Windows Share and database storage is transparent to Win32 application. Files can be bulk loaded, updated as well as managed in T-SQL like any other column. SQL Server also supports backup and restore job for this feature.

In this tip we will take a look at how to use FileTable feature of SQL Server 2012.

To use FileTable feature, execute the following query to verify that FILESTREAM is enabled at the instance level:

Note: 0 in value_in_use column indicates that FILESTREAM support s disabled for that instance, 1 indicates that FILESTREAM is available for Transact-SQL access and 2 indicates that the FILESTREAM access is enabled both for Transact SQL access and Win32 streaming access.

You can enable FILESTREAM feature at the instance level if it is disabled on your instance by following the instructions listed in the step 1 below:

Step-1: Enable FILESTREAM at the instance level

Open SQL Server Configuration Manager, Right click SQL Server service and choose Properties, Click on FILESTREAM tab and then tick Enable FILESTREAM for Transact-SQL access, Enable FILESTREAM for file I/O access, specify Windows Share name, and tick Allow remote clients access to FILESTREAM data as shown below:

Now open SQL Server Management Studio, click New Query to display the Query Editor. In Query Editor, enter the following Transact-SQL code:

<br />USE [master]<br />GO<br />-- Enabling Filestream<br />EXEC sp_configure filestream_access_level, 2<br />RECONFIGURE<br />

Click Execute and then restart the SQL Server service.

Microsoft Reference: Enable the FILESTREAM at instance level

MSDN – http://msdn.microsoft.com/en-us/library/cc645923.aspx

Step 2: Create Database with FILESTREAM enabled
Now executed the following Transact-SQL code to create a database with FILESTREAM File group, specify folder location for FILESTREAM folder and enable non-transaction access at the database level as follow:

<br />USE [master]<br />GO<br /><br />CREATE DATABASE SQLDocumentStoreDB ON PRIMARY (<br />	NAME = SQLDocumentStoreDB<br />	,FILENAME = 'D:\Program Files\Microsoft SQL Server\DBData\SQLDocumentStoreDB.mdf'<br />	)<br />	,FILEGROUP FileStreamFG CONTAINS FILESTREAM (<br />	NAME = SQLDocumentStoreFileTable<br />	,FILENAME = 'D:\FileTable_DocumentStore'<br />	) --Folder location<br />	LOG ON (<br />	NAME = SQLDocumentStoreDB_Log<br />	,FILENAME = 'D:\Program Files\Microsoft SQL Server\DBLogs\SQLDocumentStoreDB_Log.ldf'<br />	)<br />	WITH FILESTREAM<br />		--Gives full non-transactional access to the share/ directory<br />		(NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME = N'DocumentStore');<br />GO<br />

Step 3: Create FileTable

Now create a FileTable by executing the following Transact-SQL statement against your FILESTREAM enabled database in SQL Server Management Studio:

<br />USE [SQLDocumentStoreDB]<br />GO<br /><br />CREATE TABLE MyDocuments AS FILETABLE<br />	WITH (<br />		 FileTable_Directory = 'MyDocumentStore'<br />		,FileTable_Collate_Filename = database_default<br />	     );<br />

This can also be accesed at:

<br />\\&lt;ServerName&gt;\&lt;FILESTREAM Share Name&gt;\&lt;DirectoryName&gt;\&lt;FileTable Directory&gt;\<br />

For this example share path is:

<br />\\Machine-LT01\DEV01\DocumentStore\MyDocumentStore<br />

Step 4: Examine your newly created FileTable

Examine the FileTable and its structure in Object Explorer:

Now query your FileTable as follow:

<br />USE [SQLDocumentStoreDB]<br />GO<br /><br />SELECT [stream_id]<br />	,[file_stream]<br />	,[name]<br />	,[path_locator]<br />	,[parent_path_locator]<br />	,[file_type]<br />	,[cached_file_size]<br />	,[creation_time]<br />	,[last_write_time]<br />	,[last_access_time]<br />	,[is_directory]<br />	,[is_offline]<br />	,[is_hidden]<br />	,[is_readonly]<br />	,[is_archive]<br />	,[is_system]<br />	,[is_temporary]<br />FROM [dbo].[MyDocuments];<br />GO<br />

It will return no data because the FileTable is empty (see below):

Step 5: Copy files to your FileTable

This can be done by copying files to your FileTable directory. For this example FileTable directory name is MyDocumentStore and the full share path is as follow:

<br />\\Machine-LT01\DEV01\DocumentStore\MyDocumentStore<br />

Step 6: Examine the data again in your FileTable

Its time to query your FileTable again in SQL Server Management Studio as you have just copied files to your FileTable directory:

<br />USE [SQLDocumentStoreDB]<br />GO<br /><br />SELECT [stream_id]<br />	,[file_stream]<br />	,[name]<br />	,[path_locator]<br />	,[parent_path_locator]<br />	,[file_type]<br />	,[cached_file_size]<br />	,[creation_time]<br />	,[last_write_time]<br />	,[last_access_time]<br />	,[is_directory]<br />	,[is_offline]<br />	,[is_hidden]<br />	,[is_readonly]<br />	,[is_archive]<br />	,[is_system]<br />	,[is_temporary]<br />FROM [dbo].[MyDocuments];<br />GO<br />

As you can see this query is now returning the rows related to the files which I’ve just copied to FileTable directory:

Step 7: Explore FileTable directory via SSMS

You can also explore the FileTable directory via SQL Server Management Studio as follow:

Expand Tables > FileTables > Right-click your FileTable > Choose option Explore FileTable directory option as follow:

Step 8: View FILESTREAM Database Options

You can execute the following query to view the FILESTREAM database option as follow:

<br />USE [master]<br />GO<br /><br />SELECT DB_NAME(Database_id) AS [Database]<br />	,[database_id] AS [DatabaseID]<br />	,[non_transacted_access] AS [NonTransactedAccess]<br />	,[non_transacted_access_desc] AS [NonTransactedAccessDesc]<br />	,[directory_name] AS [DirectoryName]<br />FROM [sys].[database_filestream_options]<br />WHERE DB_NAME(Database_id) = &lt; Databse_Name &gt;<br />

For example:

You can also Enable/Disable the FileTable namespace as follow:

<br />USE [&lt;Database_Name&gt;]<br />GO<br /><br />ALTER TABLE &lt; FileTable NAME &gt; DISABLE FILETABLE_NAMESPACE;<br />GO<br />

This will disable all system-defined constraints and Win32 access to FileTable. This is useful when doing bulk-loading or re-organization of your data.

Key information for FileTables

  • DML\DDL triggers are supported on FileTable but DML trigger on a FileTable cannot update any FileTables.
  • Normal Insert/Update/Delete are allowed for the FileTable manipulation.
  • Built-infunctions:
    • GetFileNamespacePath()–UNC path for a file/directory.
    • FileTableRootPath()–UNC path to the FileTable root
    • GetPathlocator()–path_locator value for a file/directory.
  • FileTable can be dropped similar to any other table.
  • Database Backup/Restore operations include FileTable data.
    • Point in time Restore may contain more recent FILESTREAM data due to non-transactional updates during backups.
  • FileTables are secured similar to any other user tables. Also same security is enforced for Win32 access.
  • Windows tools like xcopy/robocopy OR drag-drop operations through WindowsExplorer can be used BCP operations are supported for direct T-SQL data inserts.

Conclusion

FileTable is a cool feature of SQL Server 2012 that allows applications or users to store files/directories inside database. This feature is built on of SQL Server FILESTREAM technology and is very simple to use.

References

About these ads

4 thoughts on “Using SQL Server 2012 FileTables

  1. How can you tie these documents in FILETABLE to an existing record (in another table) as FILETABLE have an schema fixed, or identify the user who owns the document? When using varbinary(max) in a normal table you would know it belogs to that particular row. Maybe using the stream_id as foreign key?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s