Filesteam是SQL Server2008的新特性,它结合了SQL Server和NTFS文件系统,为Blob类型的数据提供了比较高效的存储和访问方案。我们最近的一个项目就是采用SQL Server的此种特性。下面是使用这种技术的方法。

  1. 开启FileStream特性,步骤如下:
  • 在“开始”菜单中,依次指向“所有程序”、“Microsoft SQL Server 2008”和“配置工具”,然后单击“SQL Server 配置管理器”。
  • 在服务列表中,右键单击“SQL Server 服务”,然后单击“打开”。
  • 在“SQL Server 配置管理器”管理单元中,找到要在其中启用 FILESTREAM 的 SQL Server 实例。
  • 右键单击该实例,然后单击“属性”。
  • 在“SQL Server 属性”对话框中,单击“FILESTREAM”选项卡。
  • 选中“针对 Transact-SQL 访问启用 FILESTREAM”复选框。
  • 如果要在 Windows 中读取和写入 FILESTREAM 数据,请单击“针对文件 I/O 流访问启用 FILESTREAM”。在“Windows 共享名”框中输入 Windows 共享的名称。
  • 如果远程客户端必须访问存储在此共享中的 FILESTREAM 数据,请选择“允许远程客户端针对 FILESTREAM 数据启用流访问”。
  • 单击“应用”。
  • 在 SQL Server Management Studio 中,单击“新建查询”以显示查询编辑器。
  • 在查询编辑器中,输入以下 Transact-SQL 代码:
    EXEC sp_configure filestream_access_level, 2 
    RECONFIGURE
  • 单击“执行”。
  1. 创建FileStream数据库
  • 在 SQL Server Management Studio 中,单击“新建查询”以显示查询编辑器。
  • 将下面示例的 Transact-SQL 代码复制到查询编辑器中。此 Transact-SQL 代码可创建一个启用了FILESTREAM 的数据库,称为 FileStreamTestDb。
USE master;
GO
CREATE DATABASE FileStreamTestDb
ON 
PRIMARY 
    (NAME = FileStreamTestDb, FILENAME = 'c:\tmp\FileStreamTestDb.mdf'),
FILEGROUP 
    FileStreamGroup1 CONTAINS FILESTREAM (NAME = FileStreamGroup1, FILENAME = 'c:\tmp\filestream1.ndf')
LOG ON 
    (NAME = FileStreamTestDblog, FILENAME = 'c:\tmp\FileStreamTestDb_log.ldf')

GO

-- 注意: 对于此脚本,C:\tmp目录必须存在。
  • 单击“执行”。
  1. 创建FileStream数据表
  • 在 SQL Server Management Studio 中,单击“新建查询”以显示查询编辑器。
  • 将下面示例的 Transact-SQL 代码复制到查询编辑器中。此 Transact-SQL 代码可创建一个启用了FILESTREAM 的表,称为 FileStreamTestTable。
use FileStreamTestDb
go

CREATE TABLE FileStreamTestTable
(
    [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE,
    [FileName] NVARCHAR(64) ,
    [BlobData] VARBINARY(MAX) FILESTREAM NULL
)

GO
  • 单击“执行”。
  1. 保存文件到数据表中
try
{
	OpenFileDialog dialog = new OpenFileDialog();
	dialog.Filter = "文件|*.*";

	if (dialog.ShowDialog() == DialogResult.OK)
	{
		using (SqlConnection conn = new SqlConnection(CONNECTIONSTRING)) 
		{
			conn.Open();
			using (SqlCommand cmd = conn.CreateCommand()) 
			{
				cmd.CommandText = "INSERT INTO FileStreamTestTable(FileName, BlobData) VALUES(@fileName, @file)";
				SqlParameter param = new SqlParameter("@fileName", SqlDbType.NVarChar, 64);
				param.Value = dialog.FileName;
				cmd.Parameters.Add(param);
				FileStream fs = new FileStream(dialog.FileName, FileMode.Open);
				byte[] bytes = new byte[fs.Length];
				fs.Read(bytes, 0, bytes.Length);
				SqlParameter param = new SqlParameter("@file", SqlDbType.VarBinary, 1000000);
				param.Value = bytes;
				cmd.Parameters.Add(param);
				MessageBox.Show(cmd.ExecuteNonQuery() == 1 ? "成功保存文件" : "保存文件失败");
				fs.Close();
			}
			conn.Close();
		}
	}
	else
	{
		MessageBox.Show("用户取消了操作");
	}
	catch (Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}
  1. 从数据表中读取文件
try
{
	using (SqlConnection conn = new SqlConnection(CONNECTIONSTRING))
	{
		conn.Open();

		using (SqlCommand cmd = conn.CreateCommand())
		{
			cmd.CommandText = "select top 1 BinaryContents from BinaryTable order by ID desc";
			SqlDataReader reader = cmd.ExecuteReader();
			SaveFileDialog dialog = new SaveFileDialog();
			dialog.Filter = "文件(*.*)|*.*";

			if (dialog.ShowDialog() == DialogResult.OK)
			{
				reader.Read();
				System.Data.SqlTypes.SqlBinary result = reader.GetSqlBinary(0);//值得注意的是这里并没有什么GetSqlImage的方法
				FileStream fs = new FileStream(dialog.FileName, FileMode.Create);
				fs.Write(result.Value, 0, result.Length);
				fs.Close();
				reader.Close();
			}
			else
			{
				MessageBox.Show("用户取消操作");
			}
		}
		conn.Close();
	}
}
catch (Exception ex) 
{ 
	MessageBox.Show(ex.Message); 
}

上面内容并非原创,而是从一些网站截取,下面是一些参考文章,里面介绍了一些更详细的内容:

 Sql Server 2008 FileSteam全攻略(一)---FileStream介绍

Sql Server 2008 FileSteam全攻略(二)---FileStream安装

在SQL Server 2008中配置FILESTREAM(百度文库)

Programming with FileStreams in SQL Server 2008(MSDN)